Support placeholder in service fabric services names (#722)

This commit is contained in:
Felix Boers 2019-01-11 14:54:54 +01:00 committed by Phil Proctor
parent 7ba6d303b4
commit 6495891a07
6 changed files with 90 additions and 12 deletions

View File

@ -27,7 +27,7 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
public async Task Invoke(DownstreamContext context) public async Task Invoke(DownstreamContext context)
{ {
var response = _replacer var response = _replacer
.Replace(context.DownstreamReRoute.DownstreamPathTemplate, context.TemplatePlaceholderNameAndValues); .Replace(context.DownstreamReRoute.DownstreamPathTemplate.Value, context.TemplatePlaceholderNameAndValues);
if (response.IsError) if (response.IsError)
{ {
@ -116,8 +116,9 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
private (string path, string query) CreateServiceFabricUri(DownstreamContext context, Response<DownstreamPath> dsPath) private (string path, string query) CreateServiceFabricUri(DownstreamContext context, Response<DownstreamPath> dsPath)
{ {
var query = context.DownstreamRequest.Query; var query = context.DownstreamRequest.Query;
var serviceFabricPath = $"/{context.DownstreamReRoute.ServiceName + dsPath.Data.Value}"; var serviceName = _replacer.Replace(context.DownstreamReRoute.ServiceName, context.TemplatePlaceholderNameAndValues);
return (serviceFabricPath, query); var pathTemplate = $"/{serviceName.Data.Value}{dsPath.Data.Value}";
return (pathTemplate, query);
} }
private static bool ServiceFabricRequest(DownstreamContext context) private static bool ServiceFabricRequest(DownstreamContext context)

View File

@ -8,11 +8,12 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
{ {
public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
{ {
public Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues) public Response<DownstreamPath> Replace(string downstreamPathTemplate,
List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
{ {
var downstreamPath = new StringBuilder(); var downstreamPath = new StringBuilder();
downstreamPath.Append(downstreamPathTemplate.Value); downstreamPath.Append(downstreamPathTemplate);
foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues) foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
{ {

View File

@ -7,6 +7,6 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
{ {
public interface IDownstreamPathPlaceholderReplacer public interface IDownstreamPathPlaceholderReplacer
{ {
Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues); Response<DownstreamPath> Replace(string downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues);
} }
} }

View File

@ -128,6 +128,42 @@ namespace Ocelot.AcceptanceTests
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_support_placeholder_in_service_fabric_service_name()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/values",
DownstreamScheme = "http",
UpstreamPathTemplate = "/api/{version}/values",
UpstreamHttpMethod = new List<string> { "Get" },
ServiceName = "Service_{version}/Api"
}
},
GlobalConfiguration = new FileGlobalConfiguration
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider()
{
Host = "localhost",
Port = 19081,
Type = "ServiceFabric"
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:19081", "/Service_1.0/Api/values", 200, "Hello from Laura", "test=best"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/api/1.0/values?test=best"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}
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)
{ {
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context => _serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, basePath, async context =>

View File

@ -223,7 +223,7 @@
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => GivenTheServiceProviderConfigIs(config)) .And(x => GivenTheServiceProviderConfigIs(config))
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081")) .And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081"))
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1")) .And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
.When(x => x.WhenICallTheMiddleware()) .When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1")) .Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1"))
.BDDfy(); .BDDfy();
@ -253,7 +253,7 @@
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => GivenTheServiceProviderConfigIs(config)) .And(x => GivenTheServiceProviderConfigIs(config))
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?Tom=test&laura=1")) .And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?Tom=test&laura=1"))
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1")) .And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
.When(x => x.WhenICallTheMiddleware()) .When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1?Tom=test&laura=1")) .Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1?Tom=test&laura=1"))
.BDDfy(); .BDDfy();
@ -283,12 +283,40 @@
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => GivenTheServiceProviderConfigIs(config)) .And(x => GivenTheServiceProviderConfigIs(config))
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?PartitionKind=test&PartitionKey=1")) .And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?PartitionKind=test&PartitionKey=1"))
.And(x => x.GivenTheUrlReplacerWillReturn("/api/products/1")) .And(x => x.GivenTheUrlReplacerWillReturnSequence("/api/products/1", "Ocelot/OcelotApp"))
.When(x => x.WhenICallTheMiddleware()) .When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1?PartitionKind=test&PartitionKey=1")) .Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Ocelot/OcelotApp/api/products/1?PartitionKind=test&PartitionKey=1"))
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_create_service_fabric_url_with_version_from_upstream_path_template()
{
var downstreamRoute = new DownstreamRoute(
new List<PlaceholderNameAndValue>(),
new ReRouteBuilder().WithDownstreamReRoute(
new DownstreamReRouteBuilder()
.WithDownstreamScheme("http")
.WithUpstreamPathTemplate(new UpstreamPathTemplateBuilder().WithOriginalValue("/products").Build())
.WithUseServiceDiscovery(true)
.Build()
).Build());
var config = new ServiceProviderConfigurationBuilder()
.WithType("ServiceFabric")
.WithHost("localhost")
.WithPort(19081)
.Build();
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.And(x => GivenTheServiceProviderConfigIs(config))
.And(x => x.GivenTheDownstreamRequestUriIs("http://localhost:19081?PartitionKind=test&PartitionKey=1"))
.And(x => x.GivenTheUrlReplacerWillReturnSequence("/products", "Service_1.0/Api"))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheDownstreamRequestUriIs("http://localhost:19081/Service_1.0/Api/products?PartitionKind=test&PartitionKey=1"))
.BDDfy();
}
[Fact] [Fact]
public void issue_473_should_not_remove_additional_query_string() public void issue_473_should_not_remove_additional_query_string()
{ {
@ -322,6 +350,8 @@
.BDDfy(); .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);
@ -346,11 +376,21 @@
_downstreamContext.DownstreamRequest = new DownstreamRequest(_request); _downstreamContext.DownstreamRequest = new DownstreamRequest(_request);
} }
private void GivenTheUrlReplacerWillReturnSequence(params string[] paths)
{
var setup = _downstreamUrlTemplateVariableReplacer
.SetupSequence(x => x.Replace(It.IsAny<string>(), It.IsAny<List<PlaceholderNameAndValue>>()));
foreach (var path in paths)
{
var response = new OkResponse<DownstreamPath>(new DownstreamPath(path));
setup.Returns(response);
}
}
private void GivenTheUrlReplacerWillReturn(string path) private void GivenTheUrlReplacerWillReturn(string path)
{ {
_downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(path)); _downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(path));
_downstreamUrlTemplateVariableReplacer _downstreamUrlTemplateVariableReplacer
.Setup(x => x.Replace(It.IsAny<DownstreamPathTemplate>(), It.IsAny<List<PlaceholderNameAndValue>>())) .Setup(x => x.Replace(It.IsAny<string>(), It.IsAny<List<PlaceholderNameAndValue>>()))
.Returns(_downstreamPath); .Returns(_downstreamPath);
} }

View File

@ -199,7 +199,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
private void WhenIReplaceTheTemplateVariables() private void WhenIReplaceTheTemplateVariables()
{ {
_result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues); _result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value, _downstreamRoute.TemplatePlaceholderNameAndValues);
} }
private void ThenTheDownstreamUrlPathIsReturned(string expected) private void ThenTheDownstreamUrlPathIsReturned(string expected)