mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:42:50 +08:00
commit
ac1e3ae22a
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,7 +6,7 @@
|
|||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
|
.DS_Store
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
*.userprefs
|
*.userprefs
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ We love to receive contributions from the community so please keep them coming :
|
|||||||
|
|
||||||
Pull requests, issues and commentary welcome!
|
Pull requests, issues and commentary welcome!
|
||||||
|
|
||||||
Please complete the relavent template for issues and PRs. Sometimes it's worth getting in touch with us to discuss changes
|
Please complete the relevant template for issues and PRs. Sometimes it's worth getting in touch with us to discuss changes
|
||||||
before doing any work incase this is something we are already doing or it might not make sense. We can also give
|
before doing any work incase this is something we are already doing or it might not make sense. We can also give
|
||||||
advice on the easiest way to do things :)
|
advice on the easiest way to do things :)
|
||||||
|
|
||||||
Finally we mark all existing issues as help wanted, small, medium and large effort. If you want to contriute for the first time I suggest looking at a help wanted & small effort issue :)
|
Finally we mark all existing issues as help wanted, small, medium and large effort. If you want to contribute for the first time I suggest looking at a help wanted & small effort issue :)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
## Expected Behavior / New Feature
|
## Expected Behavior / New Feature
|
||||||
|
|
||||||
|
|
||||||
## Actual Behavior / Motivation for New Feautre
|
## Actual Behavior / Motivation for New Feature
|
||||||
|
|
||||||
|
|
||||||
## Steps to Reproduce the Problem
|
## Steps to Reproduce the Problem
|
||||||
|
@ -81,11 +81,11 @@ We love to receive contributions from the community so please keep them coming :
|
|||||||
|
|
||||||
Pull requests, issues and commentary welcome!
|
Pull requests, issues and commentary welcome!
|
||||||
|
|
||||||
Please complete the relavent template for issues and PRs. Sometimes it's worth getting in touch with us to discuss changes
|
Please complete the relevant template for issues and PRs. Sometimes it's worth getting in touch with us to discuss changes
|
||||||
before doing any work incase this is something we are already doing or it might not make sense. We can also give
|
before doing any work incase this is something we are already doing or it might not make sense. We can also give
|
||||||
advice on the easiest way to do things :)
|
advice on the easiest way to do things :)
|
||||||
|
|
||||||
Finally we mark all existing issues as help wanted, small, medium and large effort. If you want to contriute for the first time I suggest looking at a help wanted & small effort issue :)
|
Finally we mark all existing issues as help wanted, small, medium and large effort. If you want to contribute for the first time I suggest looking at a help wanted & small effort issue :)
|
||||||
|
|
||||||
## Donate
|
## Donate
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ will need to be changed if you are running Ocelot on a different url to http://l
|
|||||||
The scripts show you how to request a bearer token from ocelot and then use it to GET the existing configuration and POST
|
The scripts show you how to request a bearer token from ocelot and then use it to GET the existing configuration and POST
|
||||||
a configuration.
|
a configuration.
|
||||||
|
|
||||||
If you are running multiple Ocelot's in a cluster then you need to use a certificate to sign the bearer tokens used to access the administration API.
|
If you are running multiple Ocelot instances in a cluster then you need to use a certificate to sign the bearer tokens used to access the administration API.
|
||||||
|
|
||||||
In order to do this you need to add two more environmental variables for each Ocelot in the cluster.
|
In order to do this you need to add two more environmental variables for each Ocelot in the cluster.
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ In order to do this you need to add two more environmental variables for each Oc
|
|||||||
``OCELOT_CERTIFICATE_PASSWORD``
|
``OCELOT_CERTIFICATE_PASSWORD``
|
||||||
The password for the certificate.
|
The password for the certificate.
|
||||||
|
|
||||||
Normally Ocelot just uses temporary signing credentials but if you set these environmental variables then it will use the certificate. If all the other Ocelots in the cluster have the same certificate then you are good!
|
Normally Ocelot just uses temporary signing credentials but if you set these environmental variables then it will use the certificate. If all the other Ocelot instances in the cluster have the same certificate then you are good!
|
||||||
|
|
||||||
|
|
||||||
Administration API
|
Administration API
|
||||||
@ -98,12 +98,14 @@ This gets the current Ocelot configuration. It is exactly the same JSON we use t
|
|||||||
|
|
||||||
**POST {adminPath}/configuration**
|
**POST {adminPath}/configuration**
|
||||||
|
|
||||||
|
|
||||||
This overrwrites the existing configuration (should probably be a put!). I reccomend getting your config from the GET endpoint, making any changes and posting it back...simples.
|
This overrwrites the existing configuration (should probably be a put!). I reccomend getting your config from the GET endpoint, making any changes and posting it back...simples.
|
||||||
|
|
||||||
The body of the request is JSON and it is the same format as the FileConfiguration.cs that we use to set up
|
The body of the request is JSON and it is the same format as the FileConfiguration.cs that we use to set up
|
||||||
Ocelot on a file system.
|
Ocelot on a file system.
|
||||||
|
|
||||||
|
Please note that if you want to use this API then the process running Ocelot must have permission to write to the disk
|
||||||
|
where your ocelot.json or ocelot.{environment}.json is located. This is because Ocelot will overwrite them on save.
|
||||||
|
|
||||||
**DELETE {adminPath}/outputcache/{region}**
|
**DELETE {adminPath}/outputcache/{region}**
|
||||||
|
|
||||||
This clears a region of the cache. If you are using a backplane it will clear all instances of the cache! Giving your the ability to run a cluster of Ocelots and cache over all of them in memory and clear them all at the same time / just use a distributed cache.
|
This clears a region of the cache. If you are using a backplane it will clear all instances of the cache! Giving your the ability to run a cluster of Ocelots and cache over all of them in memory and clear them all at the same time / just use a distributed cache.
|
||||||
|
@ -7,13 +7,13 @@ parameters and other claims. This is only available once a user has been authent
|
|||||||
After the user is authenticated we run the claims to claims transformation middleware.
|
After the user is authenticated we run the claims to claims transformation middleware.
|
||||||
This allows the user to transform claims before the authorisation middleware is called.
|
This allows the user to transform claims before the authorisation middleware is called.
|
||||||
After the user is authorised first we call the claims to headers middleware and Finally
|
After the user is authorised first we call the claims to headers middleware and Finally
|
||||||
the claims to query strig parameters middleware.
|
the claims to query string parameters middleware.
|
||||||
|
|
||||||
The syntax for performing the transforms is the same for each proces. In the ReRoute
|
The syntax for performing the transforms is the same for each process. In the ReRoute
|
||||||
configuration a json dictionary is added with a specific name either AddClaimsToRequest,
|
configuration a json dictionary is added with a specific name either AddClaimsToRequest,
|
||||||
AddHeadersToRequest, AddQueriesToRequest.
|
AddHeadersToRequest, AddQueriesToRequest.
|
||||||
|
|
||||||
Note I'm not a hotshot programmer so have no idea if this syntax is good..
|
Note: I'm not a hotshot programmer so have no idea if this syntax is good...
|
||||||
|
|
||||||
Within this dictionary the entries specify how Ocelot should transform things!
|
Within this dictionary the entries specify how Ocelot should transform things!
|
||||||
The key to the dictionary is going to become the key of either a claim, header
|
The key to the dictionary is going to become the key of either a claim, header
|
||||||
@ -23,12 +23,12 @@ The value of the entry is parsed to logic that will perform the transform. First
|
|||||||
all a dictionary accessor is specified e.g. Claims[CustomerId]. This means we want
|
all a dictionary accessor is specified e.g. Claims[CustomerId]. This means we want
|
||||||
to access the claims and get the CustomerId claim type. Next is a greater than (>)
|
to access the claims and get the CustomerId claim type. Next is a greater than (>)
|
||||||
symbol which is just used to split the string. The next entry is either value or value with
|
symbol which is just used to split the string. The next entry is either value or value with
|
||||||
and indexer. If value is specifed Ocelot will just take the value and add it to the
|
and indexer. If value is specified Ocelot will just take the value and add it to the
|
||||||
transform. If the value has an indexer Ocelot will look for a delimiter which is provided
|
transform. If the value has an indexer Ocelot will look for a delimiter which is provided
|
||||||
after another greater than symbol. Ocelot will then split the value on the delimiter
|
after another greater than symbol. Ocelot will then split the value on the delimiter
|
||||||
and add whatever was at the index requested to the transform.
|
and add whatever was at the index requested to the transform.
|
||||||
|
|
||||||
Claims to Claims Tranformation
|
Claims to Claims Transformation
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Below is an example configuration that will transforms claims to claims
|
Below is an example configuration that will transforms claims to claims
|
||||||
@ -54,10 +54,10 @@ Below is an example configuration that will transforms claims to headers
|
|||||||
"CustomerId": "Claims[sub] > value[1] > |"
|
"CustomerId": "Claims[sub] > value[1] > |"
|
||||||
}
|
}
|
||||||
|
|
||||||
This shows a transform where Ocelot looks at the users sub claim and trasnforms it into a
|
This shows a transform where Ocelot looks at the users sub claim and transforms it into a
|
||||||
CustomerId header. Assuming the sub looks like this "usertypevalue|useridvalue".
|
CustomerId header. Assuming the sub looks like this "usertypevalue|useridvalue".
|
||||||
|
|
||||||
Claims to Query String Parameters Tranformation
|
Claims to Query String Parameters Transformation
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Below is an example configuration that will transforms claims to query string parameters
|
Below is an example configuration that will transforms claims to query string parameters
|
||||||
@ -68,5 +68,5 @@ Below is an example configuration that will transforms claims to query string pa
|
|||||||
"LocationId": "Claims[LocationId] > value",
|
"LocationId": "Claims[LocationId] > value",
|
||||||
}
|
}
|
||||||
|
|
||||||
This shows a transform where Ocelot looks at the users LocationId claim and add its as
|
This shows a transform where Ocelot looks at the users LocationId claim and add it as
|
||||||
a query string parameter to be forwarded onto the downstream service.
|
a query string parameter to be forwarded onto the downstream service.
|
@ -4,8 +4,8 @@ Middleware Injection and Overrides
|
|||||||
Warning use with caution. If you are seeing any exceptions or strange behavior in your middleware
|
Warning use with caution. If you are seeing any exceptions or strange behavior in your middleware
|
||||||
pipeline and you are using any of the following. Remove them and try again!
|
pipeline and you are using any of the following. Remove them and try again!
|
||||||
|
|
||||||
When setting up Ocelot in your Startup.cs you can provide some additonal middleware
|
When setting up Ocelot in your Startup.cs you can provide some additional middleware
|
||||||
and override middleware. This is done as follos.
|
and override middleware. This is done as follows.
|
||||||
|
|
||||||
.. code-block:: csharp
|
.. code-block:: csharp
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ and override middleware. This is done as follos.
|
|||||||
app.UseOcelot(configuration);
|
app.UseOcelot(configuration);
|
||||||
|
|
||||||
In the example above the provided function will run before the first piece of Ocelot middleware.
|
In the example above the provided function will run before the first piece of Ocelot middleware.
|
||||||
This allows a user to supply any behaviours they want before and after the Ocelot pipeline has run.
|
This allows a user to supply any behaviors they want before and after the Ocelot pipeline has run.
|
||||||
This means you can break everything so use at your own pleasure!
|
This means you can break everything so use at your own pleasure!
|
||||||
|
|
||||||
The user can set functions against the following.
|
The user can set functions against the following.
|
||||||
@ -35,7 +35,7 @@ The user can set functions against the following.
|
|||||||
|
|
||||||
* AuthorisationMiddleware - This overrides Ocelots authorisation middleware.
|
* AuthorisationMiddleware - This overrides Ocelots authorisation middleware.
|
||||||
|
|
||||||
* PreQueryStringBuilderMiddleware - This alows the user to manipulate the query string on the http request before it is passed to Ocelots request creator.
|
* PreQueryStringBuilderMiddleware - This allows the user to manipulate the query string on the http request before it is passed to Ocelots request creator.
|
||||||
|
|
||||||
Obviously you can just add middleware as normal before the call to app.UseOcelot() It cannot be added
|
Obviously you can just add middleware as normal before the call to app.UseOcelot() It cannot be added
|
||||||
after as Ocelot does not call the next middleware.
|
after as Ocelot does not call the next middleware.
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
Routing
|
Routing
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Ocelot's primary functionality is to take incomeing http requests and forward them on
|
Ocelot's primary functionality is to take incoming http requests and forward them on
|
||||||
to a downstream service. At the moment in the form of another http request (in the future
|
to a downstream service. Ocelot currently only supports this in the form of another http request (in the future
|
||||||
this could be any transport mechanism).
|
this could be any transport mechanism).
|
||||||
|
|
||||||
Ocelot's describes the routing of one request to another as a ReRoute. In order to get
|
Ocelot's describes the routing of one request to another as a ReRoute. In order to get
|
||||||
@ -15,8 +15,7 @@ anything working in Ocelot you need to set up a ReRoute in the configuration.
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
In order to set up a ReRoute you need to add one to the json array called ReRoutes like
|
To configure a ReRoute you need to add one to the ReRoutes json array.
|
||||||
the following.
|
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -33,16 +32,16 @@ the following.
|
|||||||
"UpstreamHttpMethod": [ "Put", "Delete" ]
|
"UpstreamHttpMethod": [ "Put", "Delete" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
The DownstreamPathTemplate, Scheme and DownstreamHostAndPorts make the URL that this request will be forwarded to.
|
The DownstreamPathTemplate, DownstreamScheme and DownstreamHostAndPorts define the URL that a request will be forwarded to.
|
||||||
|
|
||||||
DownstreamHostAndPorts is an array that contains the host and port of any downstream services that you wish to forward requests to. Usually this will just contain one entry but sometimes you might want to load balance
|
DownstreamHostAndPorts is a collection that defines the host and port of any downstream services that you wish to forward requests to.
|
||||||
requests to your downstream services and Ocelot let's you add more than one entry and then select a load balancer.
|
Usually this will just contain a single entry but sometimes you might want to load balance requests to your downstream services and Ocelot allows you add more than one entry and then select a load balancer.
|
||||||
|
|
||||||
The UpstreamPathTemplate is the URL that Ocelot will use to identity which DownstreamPathTemplate to use for a given request. Finally the UpstreamHttpMethod is used so
|
The UpstreamPathTemplate is the URL that Ocelot will use to identity which DownstreamPathTemplate to use for a given request.
|
||||||
Ocelot can distinguish between requests to the same URL and is obviously needed to work :)
|
The UpstreamHttpMethod is used so Ocelot can distinguish between requests with different HTTP verbs to the same URL. You can set a specific list of HTTP Methods or set an empty list to allow any of them.
|
||||||
|
|
||||||
You can set a specific list of HTTP Methods or set an empty list to allow any of them. In Ocelot you can add placeholders for variables to your Templates in the form of {something}.
|
In Ocelot you can add placeholders for variables to your Templates in the form of {something}.
|
||||||
The placeholder needs to be in both the DownstreamPathTemplate and UpstreamPathTemplate. If it is Ocelot will attempt to replace the placeholder with the correct variable value from the Upstream URL when the request comes in.
|
The placeholder variable needs to be present in both the DownstreamPathTemplate and UpstreamPathTemplate properties. When it is Ocelot will attempt to substitute the value in the UpstreamPathTemplate placeholder into the DownstreamPathTemplate for each request Ocelot processes.
|
||||||
|
|
||||||
You can also do a catch all type of ReRoute e.g.
|
You can also do a catch all type of ReRoute e.g.
|
||||||
|
|
||||||
@ -63,7 +62,9 @@ You can also do a catch all type of ReRoute e.g.
|
|||||||
|
|
||||||
This will forward any path + query string combinations to the downstream service after the path /api.
|
This will forward any path + query string combinations to the downstream service after the path /api.
|
||||||
|
|
||||||
At the moment without any configuration Ocelot will default to all ReRoutes being case insensitive.
|
|
||||||
|
The default ReRouting configuration is case insensitive!
|
||||||
|
|
||||||
In order to change this you can specify on a per ReRoute basis the following setting.
|
In order to change this you can specify on a per ReRoute basis the following setting.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
@ -71,13 +72,14 @@ In order to change this you can specify on a per ReRoute basis the following set
|
|||||||
"ReRouteIsCaseSensitive": true
|
"ReRouteIsCaseSensitive": true
|
||||||
|
|
||||||
This means that when Ocelot tries to match the incoming upstream url with an upstream template the
|
This means that when Ocelot tries to match the incoming upstream url with an upstream template the
|
||||||
evaluation will be case sensitive. This setting defaults to false so only set it if you want
|
evaluation will be case sensitive.
|
||||||
the ReRoute to be case sensitive is my advice!
|
|
||||||
|
|
||||||
Catch All
|
Catch All
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
Ocelot's routing also supports a catch all style routing where the user can specify that they want to match all traffic if you set up your config like below the request will be proxied straight through (it doesnt have to be url any placeholder name will work).
|
Ocelot's routing also supports a catch all style routing where the user can specify that they want to match all traffic.
|
||||||
|
|
||||||
|
If you set up your config like below, all requests will be proxied straight through. The placeholder {url} name is not significant, any name will work.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -136,18 +138,15 @@ In order to use this feature please add the following to your config.
|
|||||||
|
|
||||||
The ReRoute above will only be matched when the host header value is somedomain.com.
|
The ReRoute above will only be matched when the host header value is somedomain.com.
|
||||||
|
|
||||||
If you do not set UpstreamHost on a ReRoue then any host header can match it. This is basically a catch all and
|
If you do not set UpstreamHost on a ReRoute then any host header will match it. This means that if you have two ReRoutes that are the same, apart from the UpstreamHost, where one is null and the other set Ocelot will favour the one that has been set.
|
||||||
preservers existing functionality at the time of building the feature. This means that if you have two ReRoutes that are the same apart from the UpstreamHost where one is null and the other set. Ocelot will favour the one that has been set.
|
|
||||||
|
|
||||||
This feature was requested as part of `Issue 216 <https://github.com/TomPallister/Ocelot/pull/216>`_ .
|
This feature was requested as part of `Issue 216 <https://github.com/TomPallister/Ocelot/pull/216>`_ .
|
||||||
|
|
||||||
Priority
|
Priority
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
In `Issue 270 <https://github.com/TomPallister/Ocelot/pull/270>`_ I finally decided to expose the ReRoute priority in
|
You can define the order you want your ReRoutes to match the Upstream HttpRequest by including a "Priority" property in ocelot.json
|
||||||
ocelot.json. This means you can decide in what order you want your ReRoutes to match the Upstream HttpRequest.
|
See `Issue 270 <https://github.com/TomPallister/Ocelot/pull/270>`_ for reference
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
@ -182,14 +181,15 @@ matched /goods/{catchAll} (because this is the first ReRoute in the list!).
|
|||||||
Dynamic Routing
|
Dynamic Routing
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
This feature was requested in `issue 340 <https://github.com/TomPallister/Ocelot/issue/340>`_. The idea is to enable dynamic routing
|
This feature was requested in `issue 340 <https://github.com/TomPallister/Ocelot/issue/340>`_.
|
||||||
when using a service discovery provider so you don't have to provide the ReRoute config. See the docs :ref:`service-discovery` if
|
|
||||||
|
The idea is to enable dynamic routing when using a service discovery provider so you don't have to provide the ReRoute config. See the docs :ref:`service-discovery` if
|
||||||
this sounds interesting to you.
|
this sounds interesting to you.
|
||||||
|
|
||||||
Query Strings
|
Query Strings
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
Ocelot allow's you to specify a querystring as part of the DownstreamPathTemplate like the example below.
|
Ocelot allows you to specify a querystring as part of the DownstreamPathTemplate like the example below.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ Ocelot allow's you to specify a querystring as part of the DownstreamPathTemplat
|
|||||||
|
|
||||||
In this example Ocelot will use the value from the {unitId} in the upstream path template and add it to the downstream request as a query string parameter called unitId!
|
In this example Ocelot will use the value from the {unitId} in the upstream path template and add it to the downstream request as a query string parameter called unitId!
|
||||||
|
|
||||||
Ocelot will also allow you to put query string parametrs in the UpstreamPathTemplate so you can match certain queries to certain services.
|
Ocelot will also allow you to put query string parameters in the UpstreamPathTemplate so you can match certain queries to certain services.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
@ -244,4 +244,4 @@ Ocelot will also allow you to put query string parametrs in the UpstreamPathTemp
|
|||||||
}
|
}
|
||||||
|
|
||||||
In this example Ocelot will only match requests that have a matching url path and the querystring starts with unitId=something. You can have other queries after this
|
In this example Ocelot will only match requests that have a matching url path and the querystring starts with unitId=something. You can have other queries after this
|
||||||
but you must start with the matching parameter. Also in this example Ocelot will swap the unitId param from the query string and use it in the downstream request path.
|
but you must start with the matching parameter. Also Ocelot will swap the {unitId} parameter from the query string and use it in the downstream request path.
|
@ -59,6 +59,20 @@ The polling interval is in milliseconds and tells Ocelot how often to call Consu
|
|||||||
|
|
||||||
Please note there are tradeoffs here. If you poll Consul it is possible Ocelot will not know if a service is down depending on your polling interval and you might get more errors than if you get the latest services per request. This really depends on how volitile your services are. I doubt it will matter for most people and polling may give a tiny performance improvement over calling consul per request (as sidecar agent). If you are calling a remote consul agent then polling will be a good performance improvement.
|
Please note there are tradeoffs here. If you poll Consul it is possible Ocelot will not know if a service is down depending on your polling interval and you might get more errors than if you get the latest services per request. This really depends on how volitile your services are. I doubt it will matter for most people and polling may give a tiny performance improvement over calling consul per request (as sidecar agent). If you are calling a remote consul agent then polling will be a good performance improvement.
|
||||||
|
|
||||||
|
You services need to be added to Consul something like below (c# style but hopefully this make sense)...The only important thing to note
|
||||||
|
is not to add http or https to the Address field. I have been contacted before about not accepting scheme in Address and accepting scheme
|
||||||
|
in address. After reading `this <https://www.consul.io/docs/agent/services.html>`_ I don't think the scheme should be in there.
|
||||||
|
|
||||||
|
.. code-block: json
|
||||||
|
|
||||||
|
new AgentService()
|
||||||
|
{
|
||||||
|
Service = "some-service-name",
|
||||||
|
Address = "localhost",
|
||||||
|
Port = 8080,
|
||||||
|
ID = "some-id",
|
||||||
|
}
|
||||||
|
|
||||||
ACL Token
|
ACL Token
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ Ocelot does not support...
|
|||||||
|
|
||||||
* Chunked Encoding - Ocelot will always get the body size and return Content-Length header. Sorry if this doesn't work for your use case!
|
* Chunked Encoding - Ocelot will always get the body size and return Content-Length header. Sorry if this doesn't work for your use case!
|
||||||
|
|
||||||
* 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 :(
|
* Forwarding 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 ocelot.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
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
.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("ocelot.json")
|
.AddJsonFile("ocelot.json", false, false)
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
|
@ -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("ocelot.json")
|
.AddJsonFile("ocelot.json", false, false)
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s => {
|
.ConfigureServices(s => {
|
||||||
|
@ -59,7 +59,6 @@ namespace OcelotApplicationApiGateway
|
|||||||
{
|
{
|
||||||
this.webHost = new WebHostBuilder()
|
this.webHost = new WebHostBuilder()
|
||||||
.UseKestrel()
|
.UseKestrel()
|
||||||
//.UseStartup<Startup>()
|
|
||||||
.UseUrls(this.listeningAddress)
|
.UseUrls(this.listeningAddress)
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
{
|
{
|
||||||
@ -67,7 +66,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("ocelot.json")
|
.AddJsonFile("ocelot.json", false, false)
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureLogging((hostingContext, logging) =>
|
.ConfigureLogging((hostingContext, logging) =>
|
||||||
|
@ -9,15 +9,16 @@ namespace Ocelot.Configuration.Repository
|
|||||||
{
|
{
|
||||||
public class DiskFileConfigurationRepository : IFileConfigurationRepository
|
public class DiskFileConfigurationRepository : IFileConfigurationRepository
|
||||||
{
|
{
|
||||||
private readonly string _configFilePath;
|
private readonly string _environmentFilePath;
|
||||||
|
private readonly string _ocelotFilePath;
|
||||||
private static readonly object _lock = new object();
|
private static readonly object _lock = new object();
|
||||||
|
|
||||||
private const string ConfigurationFileName = "ocelot";
|
private const string ConfigurationFileName = "ocelot";
|
||||||
|
|
||||||
public DiskFileConfigurationRepository(IHostingEnvironment hostingEnvironment)
|
public DiskFileConfigurationRepository(IHostingEnvironment hostingEnvironment)
|
||||||
{
|
{
|
||||||
_configFilePath = $"{AppContext.BaseDirectory}/{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
|
_environmentFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
|
||||||
|
|
||||||
|
_ocelotFilePath = $"{AppContext.BaseDirectory}{ConfigurationFileName}.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Response<FileConfiguration>> Get()
|
public Task<Response<FileConfiguration>> Get()
|
||||||
@ -26,7 +27,7 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
lock(_lock)
|
lock(_lock)
|
||||||
{
|
{
|
||||||
jsonConfiguration = System.IO.File.ReadAllText(_configFilePath);
|
jsonConfiguration = System.IO.File.ReadAllText(_environmentFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration);
|
var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration);
|
||||||
@ -40,12 +41,19 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
lock(_lock)
|
lock(_lock)
|
||||||
{
|
{
|
||||||
if (System.IO.File.Exists(_configFilePath))
|
if (System.IO.File.Exists(_environmentFilePath))
|
||||||
{
|
{
|
||||||
System.IO.File.Delete(_configFilePath);
|
System.IO.File.Delete(_environmentFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.IO.File.WriteAllText(_configFilePath, jsonConfiguration);
|
System.IO.File.WriteAllText(_environmentFilePath, jsonConfiguration);
|
||||||
|
|
||||||
|
if (System.IO.File.Exists(_ocelotFilePath))
|
||||||
|
{
|
||||||
|
System.IO.File.Delete(_ocelotFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.IO.File.WriteAllText(_ocelotFilePath, jsonConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult<Response>(new OkResponse());
|
return Task.FromResult<Response>(new OkResponse());
|
||||||
|
@ -71,7 +71,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
File.WriteAllText("ocelot.json", json);
|
File.WriteAllText("ocelot.json", json);
|
||||||
|
|
||||||
builder.AddJsonFile("ocelot.json");
|
builder.AddJsonFile("ocelot.json", false, false);
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
@ -52,9 +52,17 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
|
|||||||
if(ContainsQueryString(dsPath))
|
if(ContainsQueryString(dsPath))
|
||||||
{
|
{
|
||||||
context.DownstreamRequest.AbsolutePath = GetPath(dsPath);
|
context.DownstreamRequest.AbsolutePath = GetPath(dsPath);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(context.DownstreamRequest.Query))
|
||||||
|
{
|
||||||
context.DownstreamRequest.Query = GetQueryString(dsPath);
|
context.DownstreamRequest.Query = GetQueryString(dsPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
context.DownstreamRequest.Query += GetQueryString(dsPath).Replace('?', '&');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
RemoveQueryStringParametersThatHaveBeenUsedInTemplate(context);
|
RemoveQueryStringParametersThatHaveBeenUsedInTemplate(context);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ocelot.Configuration.Repository;
|
using Ocelot.Configuration.Repository;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using DependencyInjection;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
using Ocelot.Configuration.Creator;
|
using Ocelot.Configuration.Creator;
|
||||||
@ -115,22 +116,32 @@
|
|||||||
var internalConfigRepo = (IInternalConfigurationRepository)builder.ApplicationServices.GetService(typeof(IInternalConfigurationRepository));
|
var internalConfigRepo = (IInternalConfigurationRepository)builder.ApplicationServices.GetService(typeof(IInternalConfigurationRepository));
|
||||||
internalConfigRepo.AddOrReplace(internalConfig.Data);
|
internalConfigRepo.AddOrReplace(internalConfig.Data);
|
||||||
|
|
||||||
var fileConfigSetter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
|
|
||||||
|
|
||||||
var fileConfigRepo = (IFileConfigurationRepository)builder.ApplicationServices.GetService(typeof(IFileConfigurationRepository));
|
var fileConfigRepo = (IFileConfigurationRepository)builder.ApplicationServices.GetService(typeof(IFileConfigurationRepository));
|
||||||
|
|
||||||
|
var adminPath = (IAdministrationPath)builder.ApplicationServices.GetService(typeof(IAdministrationPath));
|
||||||
|
|
||||||
if (UsingConsul(fileConfigRepo))
|
if (UsingConsul(fileConfigRepo))
|
||||||
{
|
{
|
||||||
|
//Lots of jazz happens in here..check it out if you are using consul to store your config.
|
||||||
await SetFileConfigInConsul(builder, fileConfigRepo, fileConfig, internalConfigCreator, internalConfigRepo);
|
await SetFileConfigInConsul(builder, fileConfigRepo, fileConfig, internalConfigCreator, internalConfigRepo);
|
||||||
}
|
}
|
||||||
else
|
else if(AdministrationApiInUse(adminPath))
|
||||||
{
|
{
|
||||||
|
//We have to make sure the file config is set for the ocelot.env.json and ocelot.json so that if we pull it from the
|
||||||
|
//admin api it works...boy this is getting a spit spags boll.
|
||||||
|
var fileConfigSetter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
|
||||||
|
|
||||||
await SetFileConfig(fileConfigSetter, fileConfig);
|
await SetFileConfig(fileConfigSetter, fileConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetOcelotConfigAndReturn(internalConfigRepo);
|
return GetOcelotConfigAndReturn(internalConfigRepo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool AdministrationApiInUse(IAdministrationPath adminPath)
|
||||||
|
{
|
||||||
|
return adminPath.GetType() != typeof(NullAdministrationPath);
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task SetFileConfigInConsul(IApplicationBuilder builder,
|
private static async Task SetFileConfigInConsul(IApplicationBuilder builder,
|
||||||
IFileConfigurationRepository fileConfigRepo, IOptions<FileConfiguration> fileConfig,
|
IFileConfigurationRepository fileConfigRepo, IOptions<FileConfiguration> fileConfig,
|
||||||
IInternalConfigurationCreator internalConfigCreator, IInternalConfigurationRepository internalConfigRepo)
|
IInternalConfigurationCreator internalConfigCreator, IInternalConfigurationRepository internalConfigRepo)
|
||||||
@ -179,8 +190,7 @@
|
|||||||
|
|
||||||
private static async Task SetFileConfig(IFileConfigurationSetter fileConfigSetter, IOptions<FileConfiguration> fileConfig)
|
private static async Task SetFileConfig(IFileConfigurationSetter fileConfigSetter, IOptions<FileConfiguration> fileConfig)
|
||||||
{
|
{
|
||||||
Response response;
|
var response = await fileConfigSetter.Set(fileConfig.Value);
|
||||||
response = await fileConfigSetter.Set(fileConfig.Value);
|
|
||||||
|
|
||||||
if (IsError(response))
|
if (IsError(response))
|
||||||
{
|
{
|
||||||
|
@ -38,15 +38,19 @@
|
|||||||
|
|
||||||
private async Task<HttpContent> MapContent(HttpRequest request)
|
private async Task<HttpContent> MapContent(HttpRequest request)
|
||||||
{
|
{
|
||||||
if (request.Body == null)
|
if (request.Body == null || (request.Body.CanSeek && request.Body.Length <= 0))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Never change this to StreamContent again, I forgot it doesnt work in #464.
|
||||||
var content = new ByteArrayContent(await ToByteArray(request.Body));
|
var content = new ByteArrayContent(await ToByteArray(request.Body));
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(request.ContentType))
|
||||||
|
{
|
||||||
content.Headers
|
content.Headers
|
||||||
.TryAddWithoutValidation("Content-Type", new[] {request.ContentType});
|
.TryAddWithoutValidation("Content-Type", new[] {request.ContentType});
|
||||||
|
}
|
||||||
|
|
||||||
AddHeaderIfExistsOnRequest("Content-Language", content, request);
|
AddHeaderIfExistsOnRequest("Content-Language", content, request);
|
||||||
AddHeaderIfExistsOnRequest("Content-Location", content, request);
|
AddHeaderIfExistsOnRequest("Content-Location", content, request);
|
||||||
@ -88,6 +92,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsSupportedHeader(KeyValuePair<string, StringValues> header)
|
||||||
|
{
|
||||||
|
return !_unsupportedHeaders.Contains(header.Key.ToLower());
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<byte[]> ToByteArray(Stream stream)
|
private async Task<byte[]> ToByteArray(Stream stream)
|
||||||
{
|
{
|
||||||
using(stream)
|
using(stream)
|
||||||
@ -99,10 +108,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsSupportedHeader(KeyValuePair<string, StringValues> header)
|
|
||||||
{
|
|
||||||
return !_unsupportedHeaders.Contains(header.Key.ToLower());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,14 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
public class AggregateTests : IDisposable
|
public class AggregateTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _serviceOneBuilder;
|
|
||||||
private IWebHost _serviceTwoBuilder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private string _downstreamPathOne;
|
private string _downstreamPathOne;
|
||||||
private string _downstreamPathTwo;
|
private string _downstreamPathTwo;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public AggregateTests()
|
public AggregateTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51885,
|
Port = 51875,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UpstreamPathTemplate = "/laura",
|
UpstreamPathTemplate = "/laura",
|
||||||
@ -157,7 +157,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
var expected = "{\"Laura\":{Hello from Laura},\"Tom\":{Hello from Tom}}";
|
var expected = "{\"Laura\":{Hello from Laura},\"Tom\":{Hello from Tom}}";
|
||||||
|
|
||||||
this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51885", "/", 200, "{Hello from Laura}"))
|
this.Given(x => x.GivenServiceOneIsRunning("http://localhost:51875", "/", 200, "{Hello from Laura}"))
|
||||||
.Given(x => x.GivenServiceTwoIsRunning("http://localhost:51886", "/", 200, "{Hello from Tom}"))
|
.Given(x => x.GivenServiceTwoIsRunning("http://localhost:51886", "/", 200, "{Hello from Tom}"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
@ -370,15 +370,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenServiceOneIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenServiceOneIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_serviceOneBuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPathOne = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPathOne = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -393,23 +385,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_serviceOneBuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenServiceTwoIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenServiceTwoIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_serviceTwoBuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPathTwo = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPathTwo = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -424,10 +404,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_serviceTwoBuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPathOne, string expectedDownstreamPath)
|
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPathOne, string expectedDownstreamPath)
|
||||||
@ -438,8 +414,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_serviceOneBuilder?.Dispose();
|
_serviceHandler.Dispose();
|
||||||
_serviceTwoBuilder?.Dispose();
|
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using IdentityServer4.Test;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -13,25 +16,21 @@ using Ocelot.Configuration.File;
|
|||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
using IdentityServer4.Test;
|
|
||||||
|
|
||||||
public class AuthenticationTests : IDisposable
|
public class AuthenticationTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _servicebuilder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private string _identityServerRootUrl = "http://localhost:51888";
|
private string _identityServerRootUrl = "http://localhost:51888";
|
||||||
private string _downstreamServicePath = "/";
|
private string _downstreamServicePath = "/";
|
||||||
private string _downstreamServiceHost = "localhost";
|
private string _downstreamServiceHost = "localhost";
|
||||||
private int _downstreamServicePort = 51876;
|
|
||||||
private string _downstreamServiceScheme = "http";
|
private string _downstreamServiceScheme = "http";
|
||||||
private string _downstreamServiceUrl = "http://localhost:51876";
|
private string _downstreamServiceUrl = "http://localhost:";
|
||||||
private readonly Action<IdentityServerAuthenticationOptions> _options;
|
private readonly Action<IdentityServerAuthenticationOptions> _options;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public AuthenticationTests()
|
public AuthenticationTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
_options = o =>
|
_options = o =>
|
||||||
{
|
{
|
||||||
@ -46,6 +45,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_401_using_identity_server_access_token()
|
public void should_return_401_using_identity_server_access_token()
|
||||||
{
|
{
|
||||||
|
int port = 54329;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -58,7 +59,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host =_downstreamServiceHost,
|
Host =_downstreamServiceHost,
|
||||||
Port = _downstreamServicePort,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
@ -73,7 +74,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn($"{_downstreamServiceUrl}{port}", 201, string.Empty))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
.And(x => _steps.GivenThePostHasContent("postContent"))
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
@ -85,6 +86,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_using_identity_server()
|
public void should_return_response_200_using_identity_server()
|
||||||
{
|
{
|
||||||
|
int port = 54099;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -97,7 +100,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host =_downstreamServiceHost,
|
Host =_downstreamServiceHost,
|
||||||
Port = _downstreamServicePort,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
@ -112,7 +115,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn($"{_downstreamServiceUrl}{port}", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -126,6 +129,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_401_using_identity_server_with_token_requested_for_other_api()
|
public void should_return_response_401_using_identity_server_with_token_requested_for_other_api()
|
||||||
{
|
{
|
||||||
|
int port = 54196;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -138,7 +143,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host =_downstreamServiceHost,
|
Host =_downstreamServiceHost,
|
||||||
Port = _downstreamServicePort,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
@ -153,7 +158,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn($"{_downstreamServiceUrl}{port}", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApi2(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveATokenForApi2(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -166,6 +171,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_201_using_identity_server_access_token()
|
public void should_return_201_using_identity_server_access_token()
|
||||||
{
|
{
|
||||||
|
int port = 52226;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -178,7 +185,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host =_downstreamServiceHost,
|
Host =_downstreamServiceHost,
|
||||||
Port = _downstreamServicePort,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
@ -193,7 +200,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn($"{_downstreamServiceUrl}{port}", 201, string.Empty))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -207,6 +214,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_201_using_identity_server_reference_token()
|
public void should_return_201_using_identity_server_reference_token()
|
||||||
{
|
{
|
||||||
|
int port = 52222;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -219,7 +228,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host =_downstreamServiceHost,
|
Host =_downstreamServiceHost,
|
||||||
Port = _downstreamServicePort,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = _downstreamServiceScheme,
|
DownstreamScheme = _downstreamServiceScheme,
|
||||||
@ -234,7 +243,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Reference))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", "api2", AccessTokenType.Reference))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
|
.And(x => x.GivenThereIsAServiceRunningOn($"{_downstreamServiceUrl}{port}", 201, string.Empty))
|
||||||
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -247,23 +256,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_servicebuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_servicebuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAnIdentityServerOn(string url, string apiName, string api2Name, AccessTokenType tokenType)
|
private void GivenThereIsAnIdentityServerOn(string url, string apiName, string api2Name, AccessTokenType tokenType)
|
||||||
@ -371,7 +368,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_servicebuilder?.Dispose();
|
_serviceHandler.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
_identityServerBuilder?.Dispose();
|
_identityServerBuilder?.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -12,22 +14,19 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
using IdentityServer4;
|
|
||||||
using IdentityServer4.Test;
|
using IdentityServer4.Test;
|
||||||
|
|
||||||
public class AuthorisationTests : IDisposable
|
public class AuthorisationTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _servicebuilder;
|
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private Action<IdentityServerAuthenticationOptions> _options;
|
private readonly Action<IdentityServerAuthenticationOptions> _options;
|
||||||
private string _identityServerRootUrl = "http://localhost:51888";
|
private string _identityServerRootUrl = "http://localhost:51888";
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public AuthorisationTests()
|
public AuthorisationTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
_options = o =>
|
_options = o =>
|
||||||
{
|
{
|
||||||
@ -42,6 +41,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_authorising_route()
|
public void should_return_response_200_authorising_route()
|
||||||
{
|
{
|
||||||
|
int port = 52875;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -54,7 +55,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51876,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
@ -86,7 +87,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -100,6 +101,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_403_authorising_route()
|
public void should_return_response_403_authorising_route()
|
||||||
{
|
{
|
||||||
|
int port = 59471;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -112,7 +115,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51876,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
@ -143,7 +146,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -156,6 +159,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_using_identity_server_with_allowed_scope()
|
public void should_return_response_200_using_identity_server_with_allowed_scope()
|
||||||
{
|
{
|
||||||
|
int port = 63471;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -168,7 +173,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51876,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
@ -184,7 +189,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -197,6 +202,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_403_using_identity_server_with_scope_not_allowed()
|
public void should_return_response_403_using_identity_server_with_scope_not_allowed()
|
||||||
{
|
{
|
||||||
|
int port = 60571;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -209,7 +216,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51876,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
@ -225,7 +232,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveATokenForApiReadOnlyScope("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -238,6 +245,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_fix_issue_240()
|
public void should_fix_issue_240()
|
||||||
{
|
{
|
||||||
|
int port = 61071;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -250,7 +259,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51876,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
@ -284,7 +293,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt, users))
|
this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt, users))
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
|
.And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
.And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
.And(x => _steps.GivenOcelotIsRunning(_options, "Test"))
|
||||||
@ -297,23 +306,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_servicebuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_servicebuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType)
|
private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType)
|
||||||
@ -465,7 +462,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_servicebuilder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
_identityServerBuilder?.Dispose();
|
_identityServerBuilder?.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,22 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class CachingTests : IDisposable
|
public class CachingTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public CachingTests()
|
public CachingTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,21 +199,13 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenTheServiceNowReturns(string url, int statusCode, string responseBody)
|
private void GivenTheServiceNowReturns(string url, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder.Dispose();
|
_serviceHandler.Dispose();
|
||||||
GivenThereIsAServiceRunningOn(url, statusCode, responseBody, null, null);
|
GivenThereIsAServiceRunningOn(url, statusCode, responseBody, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody, string key, string value)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody, string key, string value)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(key))
|
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(key))
|
||||||
{
|
{
|
||||||
@ -224,15 +214,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,21 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class CaseSensitiveRoutingTests : IDisposable
|
public class CaseSensitiveRoutingTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public CaseSensitiveRoutingTests()
|
public CaseSensitiveRoutingTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,29 +224,16 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
using System;
|
using Xunit;
|
||||||
|
|
||||||
|
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using IdentityServer4.Test;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -12,24 +18,18 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
using IdentityServer4;
|
|
||||||
using IdentityServer4.Test;
|
|
||||||
|
|
||||||
public class ClaimsToHeadersForwardingTests : IDisposable
|
public class ClaimsToHeadersForwardingTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _servicebuilder;
|
|
||||||
private IWebHost _identityServerBuilder;
|
private IWebHost _identityServerBuilder;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private Action<IdentityServerAuthenticationOptions> _options;
|
private Action<IdentityServerAuthenticationOptions> _options;
|
||||||
private string _identityServerRootUrl = "http://localhost:52888";
|
private string _identityServerRootUrl = "http://localhost:52888";
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public ClaimsToHeadersForwardingTests()
|
public ClaimsToHeadersForwardingTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
_options = o =>
|
_options = o =>
|
||||||
{
|
{
|
||||||
@ -107,15 +107,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode)
|
||||||
{
|
{
|
||||||
_servicebuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
var customerId = context.Request.Headers.First(x => x.Key == "CustomerId").Value.First();
|
var customerId = context.Request.Headers.First(x => x.Key == "CustomerId").Value.First();
|
||||||
var locationId = context.Request.Headers.First(x => x.Key == "LocationId").Value.First();
|
var locationId = context.Request.Headers.First(x => x.Key == "LocationId").Value.First();
|
||||||
@ -126,10 +118,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_servicebuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType, TestUser user)
|
private void GivenThereIsAnIdentityServerOn(string url, string apiName, AccessTokenType tokenType, TestUser user)
|
||||||
@ -203,7 +191,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_servicebuilder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
_identityServerBuilder?.Dispose();
|
_identityServerBuilder?.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,25 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
namespace Ocelot.AcceptanceTests
|
||||||
using Microsoft.AspNetCore.Hosting;
|
{
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class ClientRateLimitTests : IDisposable
|
public class ClientRateLimitTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private int _counterOne;
|
private int _counterOne;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public ClientRateLimitTests()
|
public ClientRateLimitTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_builder?.Dispose();
|
|
||||||
_steps.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_call_withratelimiting()
|
public void should_call_withratelimiting()
|
||||||
{
|
{
|
||||||
@ -158,6 +147,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_call_middleware_withWhitelistClient()
|
public void should_call_middleware_withWhitelistClient()
|
||||||
{
|
{
|
||||||
|
int port = 61876;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -170,7 +161,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51876,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DownstreamScheme = "http",
|
DownstreamScheme = "http",
|
||||||
@ -201,7 +192,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", "/api/ClientRateLimit"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/api/ClientRateLimit"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 4))
|
.When(x => _steps.WhenIGetUrlOnTheApiGatewayMultipleTimesForRateLimit("/api/ClientRateLimit", 4))
|
||||||
@ -211,26 +202,18 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(context =>
|
|
||||||
{
|
{
|
||||||
_counterOne++;
|
_counterOne++;
|
||||||
context.Response.StatusCode = 200;
|
context.Response.StatusCode = 200;
|
||||||
context.Response.WriteAsync(_counterOne.ToString());
|
context.Response.WriteAsync(_counterOne.ToString());
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
})
|
}
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
177
test/Ocelot.AcceptanceTests/ContentTests.cs
Normal file
177
test/Ocelot.AcceptanceTests/ContentTests.cs
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class ContentTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Steps _steps;
|
||||||
|
private string _contentType;
|
||||||
|
private long? _contentLength;
|
||||||
|
private bool _contentTypeHeaderExists;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
|
public ContentTests()
|
||||||
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
|
_steps = new Steps();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_not_add_content_type_or_content_length_headers()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 51339,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51339", "/", 200, "Hello from Laura"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||||
|
.And(x => ThenTheContentTypeShouldBeEmpty())
|
||||||
|
.And(x => ThenTheContentLengthShouldBeEmpty())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_add_content_type_and_content_length_headers()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 51349,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var contentType = "application/json";
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51349", "/", 201, string.Empty))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
|
.And(x => _steps.GivenThePostHasContentType(contentType))
|
||||||
|
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
|
||||||
|
.And(x => ThenTheContentLengthIs(11))
|
||||||
|
.And(x => ThenTheContentTypeIsIs(contentType))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_add_default_content_type_header()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 51359,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Post" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51359", "/", 201, string.Empty))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.And(x => _steps.GivenThePostHasContent("postContent"))
|
||||||
|
.When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
|
||||||
|
.And(x => ThenTheContentLengthIs(11))
|
||||||
|
.And(x => ThenTheContentTypeIsIs("text/plain; charset=utf-8"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheContentTypeIsIs(string expected)
|
||||||
|
{
|
||||||
|
_contentType.ShouldBe(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheContentLengthShouldBeEmpty()
|
||||||
|
{
|
||||||
|
_contentLength.ShouldBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheContentLengthIs(int expected)
|
||||||
|
{
|
||||||
|
_contentLength.ShouldBe(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheContentTypeShouldBeEmpty()
|
||||||
|
{
|
||||||
|
_contentType.ShouldBeNullOrEmpty();
|
||||||
|
_contentTypeHeaderExists.ShouldBe(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
|
{
|
||||||
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
|
{
|
||||||
|
_contentType = context.Request.ContentType;
|
||||||
|
_contentLength = context.Request.ContentLength;
|
||||||
|
_contentTypeHeaderExists = context.Request.Headers.TryGetValue("Content-Type", out var value);
|
||||||
|
context.Response.StatusCode = statusCode;
|
||||||
|
await context.Response.WriteAsync(responseBody);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_serviceHandler?.Dispose();
|
||||||
|
_steps.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
using System;
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
@ -13,17 +12,16 @@ using Shouldly;
|
|||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class CustomMiddlewareTests : IDisposable
|
public class CustomMiddlewareTests : IDisposable
|
||||||
{
|
{
|
||||||
private readonly string _configurationPath;
|
private readonly string _configurationPath;
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private int _counter;
|
private int _counter;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public CustomMiddlewareTests()
|
public CustomMiddlewareTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_counter = 0;
|
_counter = 0;
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
_configurationPath = "ocelot.json";
|
_configurationPath = "ocelot.json";
|
||||||
@ -340,16 +338,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string basePath)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string basePath)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(context =>
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(basePath))
|
if (string.IsNullOrEmpty(basePath))
|
||||||
{
|
{
|
||||||
@ -362,15 +351,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,29 +1,25 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class GzipTests : IDisposable
|
public class GzipTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public GzipTests()
|
public GzipTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,15 +62,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody, string expected)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody, string expected)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.Headers.TryGetValue("Content-Encoding", out var contentEncoding))
|
if (context.Request.Headers.TryGetValue("Content-Encoding", out var contentEncoding))
|
||||||
{
|
{
|
||||||
@ -83,7 +71,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
string text = null;
|
string text = null;
|
||||||
using (var decompress = new GZipStream(context.Request.Body, CompressionMode.Decompress))
|
using (var decompress = new GZipStream(context.Request.Body, CompressionMode.Decompress))
|
||||||
{
|
{
|
||||||
using (var sr = new StreamReader(decompress)) {
|
using (var sr = new StreamReader(decompress))
|
||||||
|
{
|
||||||
text = sr.ReadToEnd();
|
text = sr.ReadToEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,15 +91,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync("downstream path didnt match base path");
|
await context.Response.WriteAsync("downstream path didnt match base path");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,24 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class HeaderTests : IDisposable
|
public class HeaderTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private int _count;
|
private int _count;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public HeaderTests()
|
public HeaderTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,17 +311,81 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void issue_474_should_not_put_spaces_in_header()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 51879,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Accept"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.And(x => _steps.GivenIAddAHeader("Accept", "text/html,application/xhtml+xml,application/xml;"))
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.And(x => _steps.ThenTheResponseBodyShouldBe("text/html,application/xhtml+xml,application/xml;"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void issue_474_should_put_spaces_in_header()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 51879,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Accept"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
|
.And(x => _steps.GivenIAddAHeader("Accept", "text/html"))
|
||||||
|
.And(x => _steps.GivenIAddAHeader("Accept", "application/xhtml+xml"))
|
||||||
|
.And(x => _steps.GivenIAddAHeader("Accept", "application/xml"))
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.And(x => _steps.ThenTheResponseBodyShouldBe("text/html, application/xhtml+xml, application/xml"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(context =>
|
|
||||||
{
|
{
|
||||||
if (_count == 0)
|
if (_count == 0)
|
||||||
{
|
{
|
||||||
@ -345,23 +407,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
context.Response.StatusCode = 500;
|
context.Response.StatusCode = 500;
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string headerKey)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string headerKey)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.Headers.TryGetValue(headerKey, out var values))
|
if (context.Request.Headers.TryGetValue(headerKey, out var values))
|
||||||
{
|
{
|
||||||
@ -370,23 +420,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(result);
|
await context.Response.WriteAsync(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string headerKey, string headerValue)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string headerKey, string headerValue)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(context =>
|
|
||||||
{
|
{
|
||||||
context.Response.OnStarting(() =>
|
context.Response.OnStarting(() =>
|
||||||
{
|
{
|
||||||
@ -397,15 +435,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
using System;
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
public class HttpDelegatingHandlersTests : IDisposable
|
||||||
{
|
{
|
||||||
public class HttpDelegatingHandlersTests
|
|
||||||
{
|
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private string _downstreamPath;
|
private string _downstreamPath;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public HttpDelegatingHandlersTests()
|
public HttpDelegatingHandlersTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +247,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
return base.SendAsync(request, cancellationToken);
|
return base.SendAsync(request, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable once ClassNeverInstantiated.Local
|
// ReSharper disable once ClassNeverInstantiated.Local
|
||||||
private class FakeHandlerAgain : DelegatingHandler
|
private class FakeHandlerAgain : DelegatingHandler
|
||||||
{
|
{
|
||||||
@ -263,15 +262,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -286,10 +277,12 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
}
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_steps?.Dispose();
|
||||||
|
_serviceHandler?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.LoadBalancer.LoadBalancers;
|
using Ocelot.LoadBalancer.LoadBalancers;
|
||||||
@ -10,27 +9,28 @@ using Shouldly;
|
|||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class LoadBalancerTests : IDisposable
|
public class LoadBalancerTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builderOne;
|
|
||||||
private IWebHost _builderTwo;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private int _counterOne;
|
private int _counterOne;
|
||||||
private int _counterTwo;
|
private int _counterTwo;
|
||||||
private static readonly object _syncLock = new object();
|
private static readonly object _syncLock = new object();
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public LoadBalancerTests()
|
public LoadBalancerTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_load_balance_request_with_least_connection()
|
public void should_load_balance_request_with_least_connection()
|
||||||
{
|
{
|
||||||
var downstreamServiceOneUrl = "http://localhost:50881";
|
int portOne = 50591;
|
||||||
var downstreamServiceTwoUrl = "http://localhost:50892";
|
int portTwo = 51482;
|
||||||
|
|
||||||
|
var downstreamServiceOneUrl = $"http://localhost:{portOne}";
|
||||||
|
var downstreamServiceTwoUrl = $"http://localhost:{portTwo}";
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
@ -48,12 +48,12 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 50881
|
Port = portOne
|
||||||
},
|
},
|
||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 50892
|
Port = portTwo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,8 +76,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_load_balance_request_with_round_robin()
|
public void should_load_balance_request_with_round_robin()
|
||||||
{
|
{
|
||||||
var downstreamPortOne = 51881;
|
var downstreamPortOne = 51701;
|
||||||
var downstreamPortTwo = 51892;
|
var downstreamPortTwo = 53802;
|
||||||
var downstreamServiceOneUrl = $"http://localhost:{downstreamPortOne}";
|
var downstreamServiceOneUrl = $"http://localhost:{downstreamPortOne}";
|
||||||
var downstreamServiceTwoUrl = $"http://localhost:{downstreamPortTwo}";
|
var downstreamServiceTwoUrl = $"http://localhost:{downstreamPortTwo}";
|
||||||
|
|
||||||
@ -136,15 +136,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenProductServiceOneIsRunning(string url, int statusCode)
|
private void GivenProductServiceOneIsRunning(string url, int statusCode)
|
||||||
{
|
{
|
||||||
_builderOne = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -154,6 +146,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_counterOne++;
|
_counterOne++;
|
||||||
response = _counterOne.ToString();
|
response = _counterOne.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(response);
|
await context.Response.WriteAsync(response);
|
||||||
}
|
}
|
||||||
@ -162,23 +155,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderOne.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenProductServiceTwoIsRunning(string url, int statusCode)
|
private void GivenProductServiceTwoIsRunning(string url, int statusCode)
|
||||||
{
|
{
|
||||||
_builderTwo = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -192,21 +173,16 @@ namespace Ocelot.AcceptanceTests
|
|||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(response);
|
await context.Response.WriteAsync(response);
|
||||||
}
|
}
|
||||||
catch (System.Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderTwo.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builderOne?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_builderTwo?.Dispose();
|
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,24 @@
|
|||||||
using System;
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class QoSTests : IDisposable
|
public class QoSTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _brokenService;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private int _requestCount;
|
private int _requestCount;
|
||||||
private IWebHost _workingService;
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public QoSTests()
|
public QoSTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,15 +224,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAPossiblyBrokenServiceRunningOn(string url, string responseBody)
|
private void GivenThereIsAPossiblyBrokenServiceRunningOn(string url, string responseBody)
|
||||||
{
|
{
|
||||||
_brokenService = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
//circuit starts closed
|
//circuit starts closed
|
||||||
if (_requestCount == 0)
|
if (_requestCount == 0)
|
||||||
@ -260,41 +249,23 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
context.Response.StatusCode = 200;
|
context.Response.StatusCode = 200;
|
||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_brokenService.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody, int timeout)
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody, int timeout)
|
||||||
{
|
{
|
||||||
_workingService = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
Thread.Sleep(timeout);
|
Thread.Sleep(timeout);
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_workingService.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_workingService?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_brokenService?.Dispose();
|
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,21 @@
|
|||||||
using System;
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class RequestIdTests : IDisposable
|
public class RequestIdTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public RequestIdTests()
|
public RequestIdTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,30 +166,17 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url)
|
private void GivenThereIsAServiceRunningOn(string url)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
{
|
||||||
app.Run(context =>
|
context.Request.Headers.TryGetValue(_steps.RequestIdKey, out var requestId);
|
||||||
{
|
|
||||||
StringValues requestId;
|
|
||||||
context.Request.Headers.TryGetValue(_steps.RequestIdKey, out requestId);
|
|
||||||
context.Response.Headers.Add(_steps.RequestIdKey, requestId.First());
|
context.Response.Headers.Add(_steps.RequestIdKey, requestId.First());
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,20 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class ResponseCodeTests : IDisposable
|
public class ResponseCodeTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private string _downstreamPath;
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public ResponseCodeTests()
|
public ResponseCodeTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,26 +53,15 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
using System;
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class ReturnsErrorTests : IDisposable
|
public class ReturnsErrorTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _servicebuilder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public ReturnsErrorTests()
|
public ReturnsErrorTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,27 +53,12 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url)
|
private void GivenThereIsAServiceRunningOn(string url)
|
||||||
{
|
{
|
||||||
_servicebuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, context => throw new Exception("BLAMMMM"));
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(context =>
|
|
||||||
{
|
|
||||||
throw new Exception("BLAMMMM");
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_servicebuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_servicebuilder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,23 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class RoutingTests : IDisposable
|
public class RoutingTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private string _downstreamPath;
|
private string _downstreamPath;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public RoutingTests()
|
public RoutingTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,15 +971,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -996,10 +986,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPath)
|
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPath)
|
||||||
@ -1009,7 +995,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,25 +1,21 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class RoutingWithQueryStringTests : IDisposable
|
public class RoutingWithQueryStringTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private string _downstreamPath;
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public RoutingWithQueryStringTests()
|
public RoutingWithQueryStringTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,15 +204,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string queryString, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string queryString, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.PathBase.Value != basePath || context.Request.QueryString.Value != queryString)
|
if (context.Request.PathBase.Value != basePath || context.Request.QueryString.Value != queryString)
|
||||||
{
|
{
|
||||||
@ -229,20 +217,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPath)
|
|
||||||
{
|
|
||||||
_downstreamPath.ShouldBe(expectedDownstreamPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Consul;
|
using Consul;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
@ -18,21 +15,19 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public class ServiceDiscoveryTests : IDisposable
|
public class ServiceDiscoveryTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builderOne;
|
|
||||||
private IWebHost _builderTwo;
|
|
||||||
private IWebHost _fakeConsulBuilder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private readonly List<ServiceEntry> _consulServices;
|
private readonly List<ServiceEntry> _consulServices;
|
||||||
private readonly List<IServiceInstance> _eurekaInstances;
|
private readonly List<IServiceInstance> _eurekaInstances;
|
||||||
private int _counterOne;
|
private int _counterOne;
|
||||||
private int _counterTwo;
|
private int _counterTwo;
|
||||||
private static readonly object SyncLock = new object();
|
private static readonly object SyncLock = new object();
|
||||||
private IWebHost _builder;
|
|
||||||
private string _downstreamPath;
|
private string _downstreamPath;
|
||||||
private string _receivedToken;
|
private string _receivedToken;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public ServiceDiscoveryTests()
|
public ServiceDiscoveryTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
_consulServices = new List<ServiceEntry>();
|
_consulServices = new List<ServiceEntry>();
|
||||||
_eurekaInstances = new List<IServiceInstance>();
|
_eurekaInstances = new List<IServiceInstance>();
|
||||||
@ -74,7 +69,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenEurekaProductServiceOneIsRunning(downstreamServiceOneUrl, 200))
|
this.Given(x => x.GivenEurekaProductServiceOneIsRunning(downstreamServiceOneUrl))
|
||||||
.And(x => x.GivenThereIsAFakeEurekaServiceDiscoveryProvider(fakeEurekaServiceDiscoveryUrl, serviceName))
|
.And(x => x.GivenThereIsAFakeEurekaServiceDiscoveryProvider(fakeEurekaServiceDiscoveryUrl, serviceName))
|
||||||
.And(x => x.GivenTheServicesAreRegisteredWithEureka(instanceOne))
|
.And(x => x.GivenTheServicesAreRegisteredWithEureka(instanceOne))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
@ -568,15 +563,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAFakeEurekaServiceDiscoveryProvider(string url, string serviceName)
|
private void GivenThereIsAFakeEurekaServiceDiscoveryProvider(string url, string serviceName)
|
||||||
{
|
{
|
||||||
_fakeConsulBuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.Path.Value == "/eureka/apps/")
|
if (context.Request.Path.Value == "/eureka/apps/")
|
||||||
{
|
{
|
||||||
@ -642,23 +629,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteJsonAsync(applications);
|
await context.Response.WriteJsonAsync(applications);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_fakeConsulBuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
|
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
|
||||||
{
|
{
|
||||||
_fakeConsulBuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
||||||
{
|
{
|
||||||
@ -670,23 +645,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteJsonAsync(_consulServices);
|
await context.Response.WriteJsonAsync(_consulServices);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_fakeConsulBuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenProductServiceOneIsRunning(string url, int statusCode)
|
private void GivenProductServiceOneIsRunning(string url, int statusCode)
|
||||||
{
|
{
|
||||||
_builderOne = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -696,6 +659,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_counterOne++;
|
_counterOne++;
|
||||||
response = _counterOne.ToString();
|
response = _counterOne.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(response);
|
await context.Response.WriteAsync(response);
|
||||||
}
|
}
|
||||||
@ -704,23 +668,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderOne.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenProductServiceTwoIsRunning(string url, int statusCode)
|
private void GivenProductServiceTwoIsRunning(string url, int statusCode)
|
||||||
{
|
{
|
||||||
_builderTwo = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -739,23 +691,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderTwo.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenEurekaProductServiceOneIsRunning(string url, int statusCode)
|
private void GivenEurekaProductServiceOneIsRunning(string url)
|
||||||
{
|
{
|
||||||
_builderOne = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -767,23 +707,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderOne.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -798,16 +726,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builderOne?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_builderTwo?.Dispose();
|
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,22 @@
|
|||||||
using System.Linq;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
namespace Ocelot.AcceptanceTests
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
public class ServiceFabricTests : IDisposable
|
public class ServiceFabricTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private string _downstreamPath;
|
private string _downstreamPath;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public ServiceFabricTests()
|
public ServiceFabricTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,15 +96,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody, string expectedQueryString)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody, string expectedQueryString)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -133,15 +119,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
108
test/Ocelot.AcceptanceTests/ServiceHandler.cs
Normal file
108
test/Ocelot.AcceptanceTests/ServiceHandler.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.WebSockets;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
public class ServiceHandler : IDisposable
|
||||||
|
{
|
||||||
|
private IWebHost _builder;
|
||||||
|
|
||||||
|
public void GivenThereIsAServiceRunningOn(string baseUrl, RequestDelegate del)
|
||||||
|
{
|
||||||
|
_builder = new WebHostBuilder()
|
||||||
|
.UseUrls(baseUrl)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.Run(del);
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_builder.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, RequestDelegate del)
|
||||||
|
{
|
||||||
|
_builder = new WebHostBuilder()
|
||||||
|
.UseUrls(baseUrl)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UsePathBase(basePath);
|
||||||
|
app.Run(del);
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_builder.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, string fileName, string password, int port, RequestDelegate del)
|
||||||
|
{
|
||||||
|
_builder = new WebHostBuilder()
|
||||||
|
.UseUrls(baseUrl)
|
||||||
|
.UseKestrel(options =>
|
||||||
|
{
|
||||||
|
options.Listen(IPAddress.Loopback, port, listenOptions =>
|
||||||
|
{
|
||||||
|
listenOptions.UseHttps(fileName, password);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UsePathBase(basePath);
|
||||||
|
app.Run(del);
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_builder.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StartFakeDownstreamService(string url, string path, Func<HttpContext, Func<Task>, Task> middleware)
|
||||||
|
{
|
||||||
|
_builder = new WebHostBuilder()
|
||||||
|
.ConfigureServices(s => { }).UseKestrel()
|
||||||
|
.UseUrls(url)
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
|
{
|
||||||
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
|
var env = hostingContext.HostingEnvironment;
|
||||||
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
|
config.AddEnvironmentVariables();
|
||||||
|
})
|
||||||
|
.ConfigureLogging((hostingContext, logging) =>
|
||||||
|
{
|
||||||
|
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
||||||
|
logging.AddConsole();
|
||||||
|
})
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UseWebSockets();
|
||||||
|
app.Use(middleware);
|
||||||
|
})
|
||||||
|
.UseIISIntegration()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
await _builder.StartAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_builder?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +1,22 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class SslTests : IDisposable
|
public class SslTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private string _downstreamPath;
|
private string _downstreamPath;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public SslTests()
|
public SslTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,20 +95,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody, int port)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody, int port)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, "idsrv3test.pfx", "idsrv3test", port, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel(options =>
|
|
||||||
{
|
|
||||||
options.Listen(IPAddress.Loopback, port, listenOptions =>
|
|
||||||
{
|
|
||||||
listenOptions.UseHttps("idsrv3test.pfx", "idsrv3test");
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -126,20 +110,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPath)
|
|
||||||
{
|
|
||||||
_downstreamPath.ShouldBe(expectedDownstreamPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
100
test/Ocelot.AcceptanceTests/StartupTests.cs
Normal file
100
test/Ocelot.AcceptanceTests/StartupTests.cs
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Configuration.Repository;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Responses;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class StartupTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Steps _steps;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
private string _downstreamPath;
|
||||||
|
|
||||||
|
public StartupTests()
|
||||||
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
|
_steps = new Steps();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_not_try_and_write_to_disk_on_startup_when_not_using_admin_api()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||||
|
{
|
||||||
|
new FileHostAndPort
|
||||||
|
{
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 52179,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = new List<string> { "Get" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var fakeRepo = new FakeFileConfigurationRepository();
|
||||||
|
|
||||||
|
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:52179", "/", 200, "Hello from Laura"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunningWithBlowingUpDiskRepo(fakeRepo))
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
|
{
|
||||||
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
|
{
|
||||||
|
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
|
if (_downstreamPath != basePath)
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = statusCode;
|
||||||
|
await context.Response.WriteAsync("downstream path didnt match base path");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = statusCode;
|
||||||
|
await context.Response.WriteAsync(responseBody);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_serviceHandler?.Dispose();
|
||||||
|
_steps.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeFileConfigurationRepository : IFileConfigurationRepository
|
||||||
|
{
|
||||||
|
public Task<Response<FileConfiguration>> Get()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Response> Set(FileConfiguration fileConfiguration)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,7 @@ using static Ocelot.Infrastructure.Wait;
|
|||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
namespace Ocelot.AcceptanceTests
|
||||||
{
|
{
|
||||||
|
using Configuration.Repository;
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
|
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
|
||||||
|
|
||||||
@ -68,9 +69,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureLogging((hostingContext, logging) =>
|
.ConfigureLogging((hostingContext, logging) =>
|
||||||
@ -126,9 +127,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -154,9 +155,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -197,9 +198,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -228,9 +229,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -261,9 +262,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -294,9 +295,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -326,9 +327,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -357,9 +358,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -396,9 +397,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -444,9 +445,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -481,9 +482,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -509,9 +510,9 @@ namespace Ocelot.AcceptanceTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
@ -570,8 +571,8 @@ 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: false)
|
||||||
.AddJsonFile("ocelot.json")
|
.AddJsonFile("ocelot.json", false, false)
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
|
|
||||||
var configuration = builder.Build();
|
var configuration = builder.Build();
|
||||||
@ -746,7 +747,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public void GivenIAddAHeader(string key, string value)
|
public void GivenIAddAHeader(string key, string value)
|
||||||
{
|
{
|
||||||
_ocelotClient.DefaultRequestHeaders.Add(key, value);
|
_ocelotClient.DefaultRequestHeaders.TryAddWithoutValidation(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WhenIGetUrlOnTheApiGatewayMultipleTimes(string url, int times)
|
public void WhenIGetUrlOnTheApiGatewayMultipleTimes(string url, int times)
|
||||||
@ -823,6 +824,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_postContent = new StringContent(postcontent);
|
_postContent = new StringContent(postcontent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GivenThePostHasContentType(string postcontent)
|
||||||
|
{
|
||||||
|
_postContent.Headers.ContentType = new MediaTypeHeaderValue(postcontent);
|
||||||
|
}
|
||||||
|
|
||||||
public void GivenThePostHasGzipContent(object input)
|
public void GivenThePostHasGzipContent(object input)
|
||||||
{
|
{
|
||||||
var json = JsonConvert.SerializeObject(input);
|
var json = JsonConvert.SerializeObject(input);
|
||||||
@ -923,5 +929,35 @@ namespace Ocelot.AcceptanceTests
|
|||||||
var content = await response.Content.ReadAsStringAsync();
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
content.ShouldBe(expectedBody);
|
content.ShouldBe(expectedBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GivenOcelotIsRunningWithBlowingUpDiskRepo(IFileConfigurationRepository fake)
|
||||||
|
{
|
||||||
|
_webHostBuilder = new WebHostBuilder();
|
||||||
|
|
||||||
|
_webHostBuilder
|
||||||
|
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||||
|
{
|
||||||
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
|
var env = hostingContext.HostingEnvironment;
|
||||||
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
|
config.AddEnvironmentVariables();
|
||||||
|
})
|
||||||
|
.ConfigureServices(s =>
|
||||||
|
{
|
||||||
|
s.AddSingleton<IFileConfigurationRepository>(fake);
|
||||||
|
s.AddOcelot();
|
||||||
|
})
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.UseOcelot().Wait();
|
||||||
|
});
|
||||||
|
|
||||||
|
_ocelotServer = new TestServer(_webHostBuilder);
|
||||||
|
|
||||||
|
_ocelotClient = _ocelotServer.CreateClient();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,31 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class StickySessionsTests : IDisposable
|
public class StickySessionsTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builderOne;
|
|
||||||
private IWebHost _builderTwo;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private int _counterOne;
|
private int _counterOne;
|
||||||
private int _counterTwo;
|
private int _counterTwo;
|
||||||
private static readonly object _syncLock = new object();
|
private static readonly object SyncLock = new object();
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public StickySessionsTests()
|
public StickySessionsTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_use_same_downstream_host()
|
public void should_use_same_downstream_host()
|
||||||
{
|
{
|
||||||
var downstreamPortOne = 51881;
|
var downstreamPortOne = 51375;
|
||||||
var downstreamPortTwo = 51892;
|
var downstreamPortTwo = 51892;
|
||||||
var downstreamServiceOneUrl = $"http://localhost:{downstreamPortOne}";
|
var downstreamServiceOneUrl = $"http://localhost:{downstreamPortOne}";
|
||||||
var downstreamServiceTwoUrl = $"http://localhost:{downstreamPortTwo}";
|
var downstreamServiceTwoUrl = $"http://localhost:{downstreamPortTwo}";
|
||||||
@ -244,20 +241,12 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenProductServiceOneIsRunning(string url, int statusCode)
|
private void GivenProductServiceOneIsRunning(string url, int statusCode)
|
||||||
{
|
{
|
||||||
_builderOne = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = string.Empty;
|
var response = string.Empty;
|
||||||
lock (_syncLock)
|
lock (SyncLock)
|
||||||
{
|
{
|
||||||
_counterOne++;
|
_counterOne++;
|
||||||
response = _counterOne.ToString();
|
response = _counterOne.ToString();
|
||||||
@ -270,28 +259,16 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderOne.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenProductServiceTwoIsRunning(string url, int statusCode)
|
private void GivenProductServiceTwoIsRunning(string url, int statusCode)
|
||||||
{
|
{
|
||||||
_builderTwo = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var response = string.Empty;
|
var response = string.Empty;
|
||||||
lock (_syncLock)
|
lock (SyncLock)
|
||||||
{
|
{
|
||||||
_counterTwo++;
|
_counterTwo++;
|
||||||
response = _counterTwo.ToString();
|
response = _counterTwo.ToString();
|
||||||
@ -300,21 +277,16 @@ namespace Ocelot.AcceptanceTests
|
|||||||
context.Response.StatusCode = statusCode;
|
context.Response.StatusCode = statusCode;
|
||||||
await context.Response.WriteAsync(response);
|
await context.Response.WriteAsync(response);
|
||||||
}
|
}
|
||||||
catch (System.Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
await context.Response.WriteAsync(exception.StackTrace);
|
await context.Response.WriteAsync(exception.StackTrace);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderTwo.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builderOne?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_builderTwo?.Dispose();
|
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,25 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Consul;
|
using Consul;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class TwoDownstreamServicesTests : IDisposable
|
public class TwoDownstreamServicesTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builderOne;
|
|
||||||
private IWebHost _builderTwo;
|
|
||||||
private IWebHost _fakeConsulBuilder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private readonly List<ServiceEntry> _serviceEntries;
|
private readonly List<ServiceEntry> _serviceEntries;
|
||||||
private string _downstreamPathOne;
|
private string _downstreamPathOne;
|
||||||
private string _downstreamPathTwo;
|
private string _downstreamPathTwo;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public TwoDownstreamServicesTests()
|
public TwoDownstreamServicesTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
_serviceEntries = new List<ServiceEntry>();
|
_serviceEntries = new List<ServiceEntry>();
|
||||||
}
|
}
|
||||||
@ -98,40 +93,22 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url)
|
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url)
|
||||||
{
|
{
|
||||||
_fakeConsulBuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.Path.Value == "/v1/health/service/product")
|
if (context.Request.Path.Value == "/v1/health/service/product")
|
||||||
{
|
{
|
||||||
await context.Response.WriteJsonAsync(_serviceEntries);
|
await context.Response.WriteJsonAsync(_serviceEntries);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_fakeConsulBuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenProductServiceOneIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenProductServiceOneIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builderOne = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
{
|
||||||
app.UsePathBase(basePath);
|
_downstreamPathOne = !string.IsNullOrEmpty(context.Request.PathBase.Value)
|
||||||
app.Run(async context =>
|
? context.Request.PathBase.Value
|
||||||
{
|
: context.Request.Path.Value;
|
||||||
_downstreamPathOne = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
|
||||||
|
|
||||||
if (_downstreamPathOne != basePath)
|
if (_downstreamPathOne != basePath)
|
||||||
{
|
{
|
||||||
@ -144,23 +121,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderOne.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenProductServiceTwoIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenProductServiceTwoIsRunning(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builderTwo = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPathTwo = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPathTwo = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -175,16 +140,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builderTwo.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builderOne?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_builderTwo?.Dispose();
|
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,30 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class UpstreamHostTests : IDisposable
|
public class UpstreamHostTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private string _downstreamPath;
|
private string _downstreamPath;
|
||||||
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public UpstreamHostTests()
|
public UpstreamHostTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_with_simple_url_and_hosts_match()
|
public void should_return_response_200_with_simple_url_and_hosts_match()
|
||||||
{
|
{
|
||||||
|
int port = 64905;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -39,7 +38,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51875,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
@ -49,7 +48,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -61,6 +60,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_with_simple_url_and_hosts_match_multiple_re_routes()
|
public void should_return_response_200_with_simple_url_and_hosts_match_multiple_re_routes()
|
||||||
{
|
{
|
||||||
|
int port = 64904;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -74,7 +75,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51875,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
@ -100,7 +101,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -112,6 +113,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_with_simple_url_and_hosts_match_multiple_re_routes_reversed()
|
public void should_return_response_200_with_simple_url_and_hosts_match_multiple_re_routes_reversed()
|
||||||
{
|
{
|
||||||
|
int port = 64903;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -141,7 +144,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51875,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
@ -151,7 +154,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -163,6 +166,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_200_with_simple_url_and_hosts_match_multiple_re_routes_reversed_with_no_host_first()
|
public void should_return_response_200_with_simple_url_and_hosts_match_multiple_re_routes_reversed_with_no_host_first()
|
||||||
{
|
{
|
||||||
|
int port = 64902;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -191,7 +196,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51875,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
@ -201,7 +206,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -213,6 +218,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_return_response_404_with_simple_url_and_hosts_dont_match()
|
public void should_return_response_404_with_simple_url_and_hosts_dont_match()
|
||||||
{
|
{
|
||||||
|
int port = 64901;
|
||||||
|
|
||||||
var configuration = new FileConfiguration
|
var configuration = new FileConfiguration
|
||||||
{
|
{
|
||||||
ReRoutes = new List<FileReRoute>
|
ReRoutes = new List<FileReRoute>
|
||||||
@ -226,7 +233,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
new FileHostAndPort
|
new FileHostAndPort
|
||||||
{
|
{
|
||||||
Host = "localhost",
|
Host = "localhost",
|
||||||
Port = 51875,
|
Port = port,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UpstreamPathTemplate = "/",
|
UpstreamPathTemplate = "/",
|
||||||
@ -236,7 +243,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51875", "/", 200, "Hello from Laura"))
|
this.Given(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{port}", "/", 200, "Hello from Laura"))
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
.And(x => _steps.GivenOcelotIsRunning())
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
@ -246,15 +253,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
|
||||||
{
|
{
|
||||||
_builder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>
|
||||||
.UseUrls(baseUrl)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UsePathBase(basePath);
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
|
||||||
|
|
||||||
@ -269,20 +268,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await context.Response.WriteAsync(responseBody);
|
await context.Response.WriteAsync(responseBody);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_builder.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPath)
|
|
||||||
{
|
|
||||||
_downstreamPath.ShouldBe(expectedDownstreamPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_builder?.Dispose();
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,29 @@
|
|||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Consul;
|
using Consul;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
public class WebSocketTests : IDisposable
|
public class WebSocketTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _firstDownstreamHost;
|
|
||||||
private IWebHost _secondDownstreamHost;
|
|
||||||
private readonly List<string> _secondRecieved;
|
private readonly List<string> _secondRecieved;
|
||||||
private readonly List<string> _firstRecieved;
|
private readonly List<string> _firstRecieved;
|
||||||
private readonly List<ServiceEntry> _serviceEntries;
|
private readonly List<ServiceEntry> _serviceEntries;
|
||||||
private readonly Steps _steps;
|
private readonly Steps _steps;
|
||||||
private IWebHost _fakeConsulBuilder;
|
private readonly ServiceHandler _serviceHandler;
|
||||||
|
|
||||||
public WebSocketTests()
|
public WebSocketTests()
|
||||||
{
|
{
|
||||||
|
_serviceHandler = new ServiceHandler();
|
||||||
_steps = new Steps();
|
_steps = new Steps();
|
||||||
_firstRecieved = new List<string>();
|
_firstRecieved = new List<string>();
|
||||||
_secondRecieved = new List<string>();
|
_secondRecieved = new List<string>();
|
||||||
@ -211,25 +205,13 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
|
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
|
||||||
{
|
{
|
||||||
_fakeConsulBuilder = new WebHostBuilder()
|
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
||||||
.UseUrls(url)
|
|
||||||
.UseKestrel()
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.UseIISIntegration()
|
|
||||||
.UseUrls(url)
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.Run(async context =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
|
||||||
{
|
{
|
||||||
await context.Response.WriteJsonAsync(_serviceEntries);
|
await context.Response.WriteJsonAsync(_serviceEntries);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_fakeConsulBuilder.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task WhenIStartTheClients()
|
private async Task WhenIStartTheClients()
|
||||||
@ -333,33 +315,13 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
private async Task StartFakeDownstreamService(string url, string path)
|
private async Task StartFakeDownstreamService(string url, string path)
|
||||||
{
|
{
|
||||||
_firstDownstreamHost = new WebHostBuilder()
|
await _serviceHandler.StartFakeDownstreamService(url, path, async(context, next) =>
|
||||||
.ConfigureServices(s => { }).UseKestrel()
|
|
||||||
.UseUrls(url)
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureLogging((hostingContext, logging) =>
|
|
||||||
{
|
|
||||||
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
|
||||||
logging.AddConsole();
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseWebSockets();
|
|
||||||
app.Use(async (context, next) =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.Path == path)
|
if (context.Request.Path == path)
|
||||||
{
|
{
|
||||||
if (context.WebSockets.IsWebSocketRequest)
|
if (context.WebSockets.IsWebSocketRequest)
|
||||||
{
|
{
|
||||||
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
|
var webSocket = await context.WebSockets.AcceptWebSocketAsync();
|
||||||
await Echo(webSocket);
|
await Echo(webSocket);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -372,34 +334,11 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.UseIISIntegration().Build();
|
|
||||||
await _firstDownstreamHost.StartAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StartSecondFakeDownstreamService(string url, string path)
|
private async Task StartSecondFakeDownstreamService(string url, string path)
|
||||||
{
|
{
|
||||||
_secondDownstreamHost = new WebHostBuilder()
|
await _serviceHandler.StartFakeDownstreamService(url, path, async (context, next) =>
|
||||||
.ConfigureServices(s => { }).UseKestrel()
|
|
||||||
.UseUrls(url)
|
|
||||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureLogging((hostingContext, logging) =>
|
|
||||||
{
|
|
||||||
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
|
||||||
logging.AddConsole();
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseWebSockets();
|
|
||||||
app.Use(async (context, next) =>
|
|
||||||
{
|
{
|
||||||
if (context.Request.Path == path)
|
if (context.Request.Path == path)
|
||||||
{
|
{
|
||||||
@ -418,9 +357,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.UseIISIntegration().Build();
|
|
||||||
await _secondDownstreamHost.StartAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Echo(WebSocket webSocket)
|
private async Task Echo(WebSocket webSocket)
|
||||||
@ -473,10 +409,8 @@ namespace Ocelot.AcceptanceTests
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
_serviceHandler?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
_firstDownstreamHost?.Dispose();
|
|
||||||
_secondDownstreamHost?.Dispose();
|
|
||||||
_fakeConsulBuilder?.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ namespace Ocelot.Benchmarks
|
|||||||
.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("ocelot.json")
|
.AddJsonFile("ocelot.json", false, false)
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s => {
|
.ConfigureServices(s => {
|
||||||
|
@ -276,9 +276,23 @@ namespace Ocelot.IntegrationTests
|
|||||||
.And(x => ThenTheResponseShouldBe(updatedConfiguration))
|
.And(x => ThenTheResponseShouldBe(updatedConfiguration))
|
||||||
.When(x => WhenIGetUrlOnTheApiGateway("/administration/configuration"))
|
.When(x => WhenIGetUrlOnTheApiGateway("/administration/configuration"))
|
||||||
.And(x => ThenTheResponseShouldBe(updatedConfiguration))
|
.And(x => ThenTheResponseShouldBe(updatedConfiguration))
|
||||||
|
.And(_ => ThenTheConfigurationIsSavedCorrectly(updatedConfiguration))
|
||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ThenTheConfigurationIsSavedCorrectly(FileConfiguration expected)
|
||||||
|
{
|
||||||
|
var ocelotJsonPath = $"{AppContext.BaseDirectory}ocelot.json";
|
||||||
|
var resultText = File.ReadAllText(ocelotJsonPath);
|
||||||
|
var expectedText = JsonConvert.SerializeObject(expected, Formatting.Indented);
|
||||||
|
resultText.ShouldBe(expectedText);
|
||||||
|
|
||||||
|
var environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot.Production.json";
|
||||||
|
resultText = File.ReadAllText(environmentSpecificPath);
|
||||||
|
expectedText = JsonConvert.SerializeObject(expected, Formatting.Indented);
|
||||||
|
resultText.ShouldBe(expectedText);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_get_file_configuration_edit_and_post_updated_version_redirecting_reroute()
|
public void should_get_file_configuration_edit_and_post_updated_version_redirecting_reroute()
|
||||||
{
|
{
|
||||||
@ -536,9 +550,9 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
@ -660,9 +674,9 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x => {
|
.ConfigureServices(x => {
|
||||||
@ -693,9 +707,9 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
@ -733,9 +747,9 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x => {
|
.ConfigureServices(x => {
|
||||||
|
@ -446,10 +446,10 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddJsonFile("peers.json", optional: true, reloadOnChange: true);
|
config.AddJsonFile("peers.json", optional: true, reloadOnChange: false);
|
||||||
#pragma warning disable CS0618
|
#pragma warning disable CS0618
|
||||||
config.AddOcelotBaseUrl(url);
|
config.AddOcelotBaseUrl(url);
|
||||||
#pragma warning restore CS0618
|
#pragma warning restore CS0618
|
||||||
|
@ -106,9 +106,9 @@ namespace Ocelot.IntegrationTests
|
|||||||
{
|
{
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
||||||
var env = hostingContext.HostingEnvironment;
|
var env = hostingContext.HostingEnvironment;
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
|
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
||||||
config.AddJsonFile("ocelot.json");
|
config.AddJsonFile("ocelot.json", false, false);
|
||||||
config.AddEnvironmentVariables();
|
config.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
.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("ocelot.json")
|
.AddJsonFile("ocelot.json", false, false)
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
})
|
})
|
||||||
.ConfigureServices(s => {
|
.ConfigureServices(s => {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"DownstreamHostAndPorts": [
|
"DownstreamHostAndPorts": [
|
||||||
{
|
{
|
||||||
"Host": "localhost",
|
"Host": "localhost",
|
||||||
"Port": 3000
|
"Port": 5001
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"QoSOptions": {
|
"QoSOptions": {
|
||||||
|
@ -9,24 +9,30 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
using Xunit;
|
using Xunit;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Ocelot.Configuration.Repository;
|
using Ocelot.Configuration.Repository;
|
||||||
|
|
||||||
public class DiskFileConfigurationRepositoryTests
|
public class DiskFileConfigurationRepositoryTests : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Mock<IHostingEnvironment> _hostingEnvironment = new Mock<IHostingEnvironment>();
|
private readonly Mock<IHostingEnvironment> _hostingEnvironment;
|
||||||
private IFileConfigurationRepository _repo;
|
private IFileConfigurationRepository _repo;
|
||||||
private string _configurationPath;
|
private string _environmentSpecificPath;
|
||||||
|
private string _ocelotJsonPath;
|
||||||
private FileConfiguration _result;
|
private FileConfiguration _result;
|
||||||
private FileConfiguration _fileConfiguration;
|
private FileConfiguration _fileConfiguration;
|
||||||
|
|
||||||
// This is a bit dirty and it is dev.dev so that the ConfigurationBuilderExtensionsTests
|
// 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
|
// cant pick it up if they run in parralel..and the semaphore stops them running at the same time...sigh
|
||||||
// tests but whatever...
|
// these are not really unit tests but whatever...
|
||||||
private string _environmentName = "DEV.DEV";
|
private string _environmentName = "DEV.DEV";
|
||||||
|
private static SemaphoreSlim _semaphore;
|
||||||
|
|
||||||
public DiskFileConfigurationRepositoryTests()
|
public DiskFileConfigurationRepositoryTests()
|
||||||
{
|
{
|
||||||
|
_semaphore = new SemaphoreSlim(1, 1);
|
||||||
|
_semaphore.Wait();
|
||||||
|
_hostingEnvironment = new Mock<IHostingEnvironment>();
|
||||||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName);
|
||||||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
|
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object);
|
||||||
}
|
}
|
||||||
@ -79,6 +85,33 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_set_environment_file_configuration_and_ocelot_file_configuration()
|
||||||
|
{
|
||||||
|
var config = FakeFileConfigurationForSet();
|
||||||
|
|
||||||
|
this.Given(_ => GivenIHaveAConfiguration(config))
|
||||||
|
.And(_ => GivenTheConfigurationIs(config))
|
||||||
|
.And(_ => GivenTheUserAddedOcelotJson())
|
||||||
|
.When(_ => WhenISetTheConfiguration())
|
||||||
|
.Then(_ => ThenTheConfigurationIsStoredAs(config))
|
||||||
|
.And(_ => ThenTheConfigurationJsonIsIndented(config))
|
||||||
|
.Then(_ => ThenTheOcelotJsonIsStoredAs(config))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheUserAddedOcelotJson()
|
||||||
|
{
|
||||||
|
_ocelotJsonPath = $"{AppContext.BaseDirectory}/ocelot.json";
|
||||||
|
|
||||||
|
if (File.Exists(_ocelotJsonPath))
|
||||||
|
{
|
||||||
|
File.Delete(_ocelotJsonPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.WriteAllText(_ocelotJsonPath, "Doesnt matter");
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenTheEnvironmentNameIsUnavailable()
|
private void GivenTheEnvironmentNameIsUnavailable()
|
||||||
{
|
{
|
||||||
_environmentName = null;
|
_environmentName = null;
|
||||||
@ -119,25 +152,32 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ThenTheOcelotJsonIsStoredAs(FileConfiguration expecteds)
|
||||||
|
{
|
||||||
|
var resultText = File.ReadAllText(_ocelotJsonPath);
|
||||||
|
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
|
||||||
|
resultText.ShouldBe(expectedText);
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
private void GivenTheConfigurationIs(FileConfiguration fileConfiguration)
|
||||||
{
|
{
|
||||||
_configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
_environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||||
|
|
||||||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
|
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented);
|
||||||
|
|
||||||
if (File.Exists(_configurationPath))
|
if (File.Exists(_environmentSpecificPath))
|
||||||
{
|
{
|
||||||
File.Delete(_configurationPath);
|
File.Delete(_environmentSpecificPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
File.WriteAllText(_configurationPath, jsonConfiguration);
|
File.WriteAllText(_environmentSpecificPath, jsonConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
|
private void ThenTheConfigurationJsonIsIndented(FileConfiguration expecteds)
|
||||||
{
|
{
|
||||||
var path = !string.IsNullOrEmpty(_configurationPath) ? _configurationPath : _configurationPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
var path = !string.IsNullOrEmpty(_environmentSpecificPath) ? _environmentSpecificPath : _environmentSpecificPath = $"{AppContext.BaseDirectory}/ocelot{(string.IsNullOrEmpty(_environmentName) ? string.Empty : ".")}{_environmentName}.json";
|
||||||
|
|
||||||
var resultText = File.ReadAllText(_configurationPath);
|
var resultText = File.ReadAllText(path);
|
||||||
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
|
var expectedText = JsonConvert.SerializeObject(expecteds, Formatting.Indented);
|
||||||
resultText.ShouldBe(expectedText);
|
resultText.ShouldBe(expectedText);
|
||||||
}
|
}
|
||||||
@ -238,5 +278,10 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
ReRoutes = reRoutes
|
ReRoutes = reRoutes
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_semaphore.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,6 +289,39 @@
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void issue_473_should_not_remove_additional_query_string()
|
||||||
|
{
|
||||||
|
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||||
|
.WithDownstreamPathTemplate("/Authorized/{action}?server={server}")
|
||||||
|
.WithUpstreamHttpMethod(new List<string> { "Post", "Get" })
|
||||||
|
.WithDownstreamScheme("http")
|
||||||
|
.WithUpstreamPathTemplate("/uc/Authorized/{server}/{action}")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var config = new ServiceProviderConfigurationBuilder()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
this.Given(x => x.GivenTheDownStreamRouteIs(
|
||||||
|
new DownstreamRoute(
|
||||||
|
new List<PlaceholderNameAndValue>
|
||||||
|
{
|
||||||
|
new PlaceholderNameAndValue("{action}", "1"),
|
||||||
|
new PlaceholderNameAndValue("{server}", "2")
|
||||||
|
},
|
||||||
|
new ReRouteBuilder()
|
||||||
|
.WithDownstreamReRoute(downstreamReRoute)
|
||||||
|
.WithUpstreamHttpMethod(new List<string> { "Post", "Get" })
|
||||||
|
.Build())))
|
||||||
|
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:5000/uc/Authorized/2/1/refresh?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d"))
|
||||||
|
.And(x => GivenTheServiceProviderConfigIs(config))
|
||||||
|
.And(x => x.GivenTheUrlReplacerWillReturn("/Authorized/1?server=2"))
|
||||||
|
.When(x => x.WhenICallTheMiddleware())
|
||||||
|
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:5000/Authorized/1?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d&server=2"))
|
||||||
|
.And(x => ThenTheQueryStringIs("?refreshToken=2288356cfb1338fdc5ff4ca558ec785118dfe1ff2864340937da8226863ff66d&server=2"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenTheServiceProviderConfigIs(ServiceProviderConfiguration config)
|
private void GivenTheServiceProviderConfigIs(ServiceProviderConfiguration config)
|
||||||
{
|
{
|
||||||
var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null);
|
var configuration = new InternalConfiguration(null, null, config, null, null, null, null, null);
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public class RequestMapperTests
|
public class RequestMapperTests
|
||||||
{
|
{
|
||||||
@ -121,7 +122,7 @@
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void Should_handle_no_content()
|
public void Should_handle_no_content()
|
||||||
{
|
{
|
||||||
this.Given(_ => GivenTheInputRequestHasNoContent())
|
this.Given(_ => GivenTheInputRequestHasNullContent())
|
||||||
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||||
.And(_ => GivenTheInputRequestHasAValidUri())
|
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||||
.When(_ => WhenMapped())
|
.When(_ => WhenMapped())
|
||||||
@ -130,6 +131,40 @@
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_handle_no_content_type()
|
||||||
|
{
|
||||||
|
this.Given(_ => GivenTheInputRequestHasNoContentType())
|
||||||
|
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||||
|
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||||
|
.When(_ => WhenMapped())
|
||||||
|
.Then(_ => ThenNoErrorIsReturned())
|
||||||
|
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_handle_no_content_length()
|
||||||
|
{
|
||||||
|
this.Given(_ => GivenTheInputRequestHasNoContentLength())
|
||||||
|
.And(_ => GivenTheInputRequestHasMethod("GET"))
|
||||||
|
.And(_ => GivenTheInputRequestHasAValidUri())
|
||||||
|
.When(_ => WhenMapped())
|
||||||
|
.Then(_ => ThenNoErrorIsReturned())
|
||||||
|
.And(_ => ThenTheMappedRequestHasNoContent())
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheInputRequestHasNoContentLength()
|
||||||
|
{
|
||||||
|
_inputRequest.ContentLength = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheInputRequestHasNoContentType()
|
||||||
|
{
|
||||||
|
_inputRequest.ContentType = null;
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Should_map_content_headers()
|
public void Should_map_content_headers()
|
||||||
{
|
{
|
||||||
@ -339,14 +374,14 @@
|
|||||||
_inputRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes(content));
|
_inputRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenTheInputRequestHasNoContent()
|
private void GivenTheInputRequestHasNullContent()
|
||||||
{
|
{
|
||||||
_inputRequest.Body = null;
|
_inputRequest.Body = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WhenMapped()
|
private async Task WhenMapped()
|
||||||
{
|
{
|
||||||
_mappedRequest = _requestMapper.Map(_inputRequest).GetAwaiter().GetResult();
|
_mappedRequest = await _requestMapper.Map(_inputRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenNoErrorIsReturned()
|
private void ThenNoErrorIsReturned()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user