mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 11:18:16 +08:00
Feature/downstream aggregation (#248)
* started messing around with this on the train last night * mega hacking away to change middleware into Ocelot iddleware * scoped data repo back in * broken commit getting tests working * another broken commit farting around with tests * all unit tests passing again * mw pipeline for ocelot...still loads of hacks but getting there now to get acceptance tests working, then fix config so you can have aggregate and then imlement multiplexer, then mapping to response...loads to do * all tests passing before aggregation feature implemented * removed all the request middleware stuff we dont need it * updated how errors work...tho i think there could be edge case here when aggregating because one downstream could error and this would effect another * removed multiplexer so you dont have to send route down, this isnt very thread safe...sigh * hacking around getting the config for aggregates in, this might change * refactored builder and unit tests passing now * Updated a bunch of ports for tests * plugged in code to create reroutes that are aggregates * made multiplexer a class * hacked test to death * simple aggregator done, initial validation done * removed request id from context, it is still specific for http request * now aggregates to json always * docs for aggregate reroutes * Updated docs
This commit is contained in:
@ -20,7 +20,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
private readonly IConfigurationValidator _configurationValidator;
|
||||
private FileConfiguration _fileConfiguration;
|
||||
private Response<ConfigurationValidationResult> _result;
|
||||
private Mock<IAuthenticationSchemeProvider> _provider;
|
||||
private readonly Mock<IAuthenticationSchemeProvider> _provider;
|
||||
|
||||
public ConfigurationFluentValidationTests()
|
||||
{
|
||||
@ -28,6 +28,373 @@ namespace Ocelot.UnitTests.Configuration
|
||||
_configurationValidator = new FileConfigurationFluentValidator(_provider.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void configuration_is_valid_if_aggregates_are_valid()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51878,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/laura",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Laura"
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51880,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Tom"
|
||||
}
|
||||
},
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHost = "localhost",
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"Tom",
|
||||
"Laura"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAConfiguration(configuration))
|
||||
.When(x => x.WhenIValidateTheConfiguration())
|
||||
.Then(x => x.ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void configuration_is_invalid_if_aggregates_are_duplicate_of_re_routes()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51878,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/laura",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Laura"
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51880,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Tom",
|
||||
UpstreamHost = "localhost"
|
||||
}
|
||||
},
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHost = "localhost",
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"Tom",
|
||||
"Laura"
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAConfiguration(configuration))
|
||||
.When(x => x.WhenIValidateTheConfiguration())
|
||||
.Then(x => x.ThenTheResultIsNotValid())
|
||||
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "reRoute /tom has duplicate aggregate"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void configuration_is_valid_if_aggregates_are_not_duplicate_of_re_routes()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51878,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/laura",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Laura"
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51880,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHttpMethod = new List<string> { "Post" },
|
||||
Key = "Tom",
|
||||
UpstreamHost = "localhost"
|
||||
}
|
||||
},
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHost = "localhost",
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"Tom",
|
||||
"Laura"
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAConfiguration(configuration))
|
||||
.When(x => x.WhenIValidateTheConfiguration())
|
||||
.Then(x => x.ThenTheResultIsValid())
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void configuration_is_invalid_if_aggregates_are_duplicate_of_aggregates()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51878,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/laura",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Laura"
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51880,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/lol",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Tom"
|
||||
}
|
||||
},
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHost = "localhost",
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"Tom",
|
||||
"Laura"
|
||||
}
|
||||
},
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHost = "localhost",
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"Tom",
|
||||
"Laura"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAConfiguration(configuration))
|
||||
.When(x => x.WhenIValidateTheConfiguration())
|
||||
.Then(x => x.ThenTheResultIsNotValid())
|
||||
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "aggregate /tom has duplicate aggregate"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void configuration_is_invalid_if_re_routes_dont_exist_for_aggregate()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51878,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/laura",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Laura"
|
||||
}
|
||||
},
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHost = "localhost",
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"Tom",
|
||||
"Laura"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAConfiguration(configuration))
|
||||
.When(x => x.WhenIValidateTheConfiguration())
|
||||
.Then(x => x.ThenTheResultIsNotValid())
|
||||
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "ReRoutes for aggregateReRoute / either do not exist or do not have correct Key property"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void configuration_is_invalid_if_aggregate_has_re_routes_with_specific_request_id_keys()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51878,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/laura",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Laura"
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51880,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
RequestIdKey = "should_fail",
|
||||
Key = "Tom"
|
||||
}
|
||||
},
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHost = "localhost",
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"Tom",
|
||||
"Laura"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => x.GivenAConfiguration(configuration))
|
||||
.When(x => x.WhenIValidateTheConfiguration())
|
||||
.Then(x => x.ThenTheResultIsNotValid())
|
||||
.And(x => x.ThenTheErrorMessageAtPositionIs(0, "aggregateReRoute / contains ReRoute with specific RequestIdKey, this is not possible with Aggregates"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void configuration_is_invalid_if_scheme_in_downstream_or_upstream_template()
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Castle.Components.DictionaryAdapter;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Ocelot.Cache;
|
||||
@ -81,6 +82,125 @@ namespace Ocelot.UnitTests.Configuration
|
||||
_downstreamAddressesCreator.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_aggregate_re_route()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51878,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/laura",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Laura",
|
||||
UpstreamHost = "localhost"
|
||||
},
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
||||
{
|
||||
new FileHostAndPort
|
||||
{
|
||||
Host = "localhost",
|
||||
Port = 51880,
|
||||
}
|
||||
},
|
||||
UpstreamPathTemplate = "/tom",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
Key = "Tom",
|
||||
UpstreamHost = "localhost",
|
||||
}
|
||||
},
|
||||
Aggregates = new List<FileAggregateReRoute>
|
||||
{
|
||||
new FileAggregateReRoute
|
||||
{
|
||||
UpstreamPathTemplate = "/",
|
||||
UpstreamHost = "localhost",
|
||||
ReRouteKeys = new List<string>
|
||||
{
|
||||
"Tom",
|
||||
"Laura"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
|
||||
|
||||
var expected = new List<ReRoute>();
|
||||
|
||||
var lauraDownstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithUpstreamHost("localhost")
|
||||
.WithKey("Laura")
|
||||
.WithDownstreamPathTemplate("/")
|
||||
.WithDownstreamScheme("http")
|
||||
.WithUpstreamHttpMethod(new List<string>() {"Get"})
|
||||
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("localhost", 51878)})
|
||||
.Build();
|
||||
|
||||
var lauraReRoute = new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string>() { "Get" })
|
||||
.WithUpstreamHost("localhost")
|
||||
.WithUpstreamPathTemplate("/laura")
|
||||
.WithDownstreamReRoute(lauraDownstreamReRoute)
|
||||
.Build();
|
||||
|
||||
expected.Add(lauraReRoute);
|
||||
|
||||
var tomDownstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithUpstreamHost("localhost")
|
||||
.WithKey("Tom")
|
||||
.WithDownstreamPathTemplate("/")
|
||||
.WithDownstreamScheme("http")
|
||||
.WithUpstreamHttpMethod(new List<string>() { "Get" })
|
||||
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() { new DownstreamHostAndPort("localhost", 51878) })
|
||||
.Build();
|
||||
|
||||
var tomReRoute = new ReRouteBuilder()
|
||||
.WithUpstreamHttpMethod(new List<string>() { "Get" })
|
||||
.WithUpstreamHost("localhost")
|
||||
.WithUpstreamPathTemplate("/tom")
|
||||
.WithDownstreamReRoute(tomDownstreamReRoute)
|
||||
.Build();
|
||||
|
||||
expected.Add(tomReRoute);
|
||||
|
||||
var aggregateReReRoute = new ReRouteBuilder()
|
||||
.WithUpstreamPathTemplate("/")
|
||||
.WithUpstreamHost("localhost")
|
||||
.WithDownstreamReRoute(lauraDownstreamReRoute)
|
||||
.WithDownstreamReRoute(tomDownstreamReRoute)
|
||||
.WithUpstreamHttpMethod(new List<string>() { "Get" })
|
||||
.Build();
|
||||
|
||||
expected.Add(aggregateReReRoute);
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(configuration))
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(new ReRouteOptionsBuilder().Build()))
|
||||
.And(x => x.GivenTheFollowingIsReturned(serviceProviderConfig))
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
.Then(x => x.ThenTheServiceProviderCreatorIsCalledCorrectly())
|
||||
.Then(x => x.ThenTheReRoutesAre(expected))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_call_service_provider_config_creator()
|
||||
{
|
||||
@ -234,6 +354,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("127.0.0.1", 80)})
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
@ -261,8 +388,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamAddresses(new List<DownstreamHostAndPort>(){new DownstreamHostAndPort("127.0.0.1", 80) })
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build()
|
||||
@ -276,6 +402,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamScheme("https")
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
@ -297,8 +430,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamScheme("https")
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build()
|
||||
@ -312,6 +444,14 @@ namespace Ocelot.UnitTests.Configuration
|
||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.WithUseServiceDiscovery(true)
|
||||
.WithServiceName("ProductService")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
@ -341,11 +481,9 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUseServiceDiscovery(true)
|
||||
.WithServiceName("ProductService")
|
||||
.Build()
|
||||
}))
|
||||
.BDDfy();
|
||||
@ -356,7 +494,15 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.WithUseServiceDiscovery(false)
|
||||
.Build();
|
||||
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
@ -378,10 +524,9 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUseServiceDiscovery(false)
|
||||
.Build()
|
||||
}))
|
||||
.BDDfy();
|
||||
@ -392,7 +537,15 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
|
||||
.Build();
|
||||
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
@ -415,7 +568,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
|
||||
@ -430,6 +583,13 @@ namespace Ocelot.UnitTests.Configuration
|
||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.WithRequestIdKey("blahhhh")
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
@ -456,10 +616,9 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithRequestIdKey("blahhhh")
|
||||
.Build()
|
||||
}))
|
||||
.And(x => x.ThenTheRequestIdKeyCreatorIsCalledCorrectly())
|
||||
@ -514,17 +673,23 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.WithAllowedScopes(new List<string>())
|
||||
.Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.WithAuthenticationOptions(authenticationOptions)
|
||||
.WithClaimsToHeaders(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("CustomerId", "CustomerId", "", 0),
|
||||
})
|
||||
.Build();
|
||||
|
||||
var expected = new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithAuthenticationOptions(authenticationOptions)
|
||||
.WithClaimsToHeaders(new List<ClaimToThing>
|
||||
{
|
||||
new ClaimToThing("CustomerId", "CustomerId", "", 0),
|
||||
})
|
||||
.Build()
|
||||
};
|
||||
|
||||
@ -554,13 +719,19 @@ namespace Ocelot.UnitTests.Configuration
|
||||
.WithAllowedScopes(new List<string>())
|
||||
.Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.WithAuthenticationOptions(authenticationOptions)
|
||||
.Build();
|
||||
|
||||
var expected = new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("/products/{productId}")
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamPathTemplate("/api/products/{productId}")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithAuthenticationOptions(authenticationOptions)
|
||||
.Build()
|
||||
};
|
||||
|
||||
@ -643,14 +814,16 @@ namespace Ocelot.UnitTests.Configuration
|
||||
var result = _config.Data.ReRoutes[i];
|
||||
var expected = expectedReRoutes[i];
|
||||
|
||||
result.DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate.Value);
|
||||
result.DownstreamReRoute.Count.ShouldBe(expected.DownstreamReRoute.Count);
|
||||
|
||||
result.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamReRoute[0].DownstreamPathTemplate.Value);
|
||||
result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
|
||||
result.UpstreamPathTemplate.Value.ShouldBe(expected.UpstreamPathTemplate.Value);
|
||||
result.UpstreamTemplatePattern?.Template.ShouldBe(expected.UpstreamTemplatePattern?.Template);
|
||||
result.ClaimsToClaims.Count.ShouldBe(expected.ClaimsToClaims.Count);
|
||||
result.ClaimsToHeaders.Count.ShouldBe(expected.ClaimsToHeaders.Count);
|
||||
result.ClaimsToQueries.Count.ShouldBe(expected.ClaimsToQueries.Count);
|
||||
result.RequestIdKey.ShouldBe(expected.RequestIdKey);
|
||||
result.DownstreamReRoute[0].ClaimsToClaims.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToClaims.Count);
|
||||
result.DownstreamReRoute[0].ClaimsToHeaders.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToHeaders.Count);
|
||||
result.DownstreamReRoute[0].ClaimsToQueries.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToQueries.Count);
|
||||
result.DownstreamReRoute[0].RequestIdKey.ShouldBe(expected.DownstreamReRoute[0].RequestIdKey);
|
||||
|
||||
}
|
||||
}
|
||||
@ -659,8 +832,8 @@ namespace Ocelot.UnitTests.Configuration
|
||||
{
|
||||
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
||||
{
|
||||
var result = _config.Data.ReRoutes[i].AuthenticationOptions;
|
||||
var expected = expectedReRoutes[i].AuthenticationOptions;
|
||||
var result = _config.Data.ReRoutes[i].DownstreamReRoute[0].AuthenticationOptions;
|
||||
var expected = expectedReRoutes[i].DownstreamReRoute[0].AuthenticationOptions;
|
||||
result.AllowedScopes.ShouldBe(expected.AllowedScopes);
|
||||
}
|
||||
}
|
||||
@ -714,10 +887,10 @@ namespace Ocelot.UnitTests.Configuration
|
||||
|
||||
private void ThenTheQosOptionsAre(QoSOptions qosOptions)
|
||||
{
|
||||
_config.Data.ReRoutes[0].QosOptionsOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
|
||||
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
|
||||
|
||||
_config.Data.ReRoutes[0].QosOptionsOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
|
||||
_config.Data.ReRoutes[0].QosOptionsOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
|
||||
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
|
||||
_config.Data.ReRoutes[0].DownstreamReRoute[0].QosOptionsOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
|
||||
}
|
||||
|
||||
private void ThenTheServiceProviderCreatorIsCalledCorrectly()
|
||||
|
@ -44,7 +44,7 @@ namespace Ocelot.UnitTests.Configuration
|
||||
|
||||
private void ThenTheConfigurationIsReturned()
|
||||
{
|
||||
_getResult.Data.ReRoutes[0].DownstreamPathTemplate.Value.ShouldBe("initial");
|
||||
_getResult.Data.ReRoutes[0].DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("initial");
|
||||
}
|
||||
|
||||
private void WhenIGetTheConfiguration()
|
||||
@ -83,13 +83,24 @@ namespace Ocelot.UnitTests.Configuration
|
||||
AdministrationPath = administrationPath;
|
||||
}
|
||||
|
||||
public List<ReRoute> ReRoutes => new List<ReRoute>
|
||||
public List<ReRoute> ReRoutes
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate(_downstreamTemplatePath)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build()
|
||||
};
|
||||
get
|
||||
{
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithDownstreamPathTemplate(_downstreamTemplatePath)
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build();
|
||||
|
||||
return new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamReRoute(downstreamReRoute)
|
||||
.WithUpstreamHttpMethod(new List<string> {"Get"})
|
||||
.Build()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public string AdministrationPath {get;}
|
||||
|
||||
|
Reference in New Issue
Block a user