first passing proxy acceptnace test yeyyy!

This commit is contained in:
TomPallister
2016-09-07 21:47:39 +01:00
parent 71b7e7743e
commit 03ef47038a
12 changed files with 264 additions and 43 deletions

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
using Ocelot.Library.Infrastructure.UrlMatcher;
namespace Ocelot.Library.Infrastructure.DownstreamRouteFinder
{
public class DownstreamRoute
{
public DownstreamRoute(List<TemplateVariableNameAndValue> templateVariableNameAndValues, string downstreamUrlTemplate)
{
TemplateVariableNameAndValues = templateVariableNameAndValues;
DownstreamUrlTemplate = downstreamUrlTemplate;
}
public List<TemplateVariableNameAndValue> TemplateVariableNameAndValues { get; private set; }
public string DownstreamUrlTemplate { get; private set; }
}
}

View File

@ -0,0 +1,38 @@
using System.Collections.Generic;
using Microsoft.Extensions.Options;
using Ocelot.Library.Infrastructure.Responses;
using Ocelot.Library.Infrastructure.UrlMatcher;
namespace Ocelot.Library.Infrastructure.DownstreamRouteFinder
{
public class DownstreamRouteFinder : IDownstreamRouteFinder
{
private readonly IOptions<Configuration.Configuration> _configuration;
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
public DownstreamRouteFinder(IOptions<Configuration.Configuration> configuration, IUrlPathToUrlTemplateMatcher urlMatcher)
{
_configuration = configuration;
_urlMatcher = urlMatcher;
}
public Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath)
{
foreach (var template in _configuration.Value.ReRoutes)
{
var urlMatch = _urlMatcher.Match(upstreamUrlPath, template.UpstreamTemplate);
if (urlMatch.Match)
{
return new OkResponse<DownstreamRoute>(new DownstreamRoute(urlMatch.TemplateVariableNameAndValues, template.DownstreamTemplate));
}
}
return new ErrorResponse<DownstreamRoute>(new List<Error>
{
new UnableToFindDownstreamRouteError()
});
}
}
}

View File

@ -0,0 +1,9 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.DownstreamRouteFinder
{
public interface IDownstreamRouteFinder
{
Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath);
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.DownstreamRouteFinder
{
public class UnableToFindDownstreamRouteError : Error
{
public UnableToFindDownstreamRouteError() : base("UnableToFindDownstreamRouteError")
{
}
}
}

View File

@ -1,17 +1,17 @@
using System.Text;
using Ocelot.Library.Infrastructure.UrlMatcher;
using Ocelot.Library.Infrastructure.DownstreamRouteFinder;
namespace Ocelot.Library.Infrastructure.UrlTemplateReplacer
{
public class DownstreamUrlTemplateVariableReplacer : IDownstreamUrlTemplateVariableReplacer
{
public string ReplaceTemplateVariable(UrlMatch urlMatch)
public string ReplaceTemplateVariable(DownstreamRoute downstreamRoute)
{
var upstreamUrl = new StringBuilder();
upstreamUrl.Append(urlMatch.DownstreamUrlTemplate);
upstreamUrl.Append(downstreamRoute.DownstreamUrlTemplate);
foreach (var templateVarAndValue in urlMatch.TemplateVariableNameAndValues)
foreach (var templateVarAndValue in downstreamRoute.TemplateVariableNameAndValues)
{
upstreamUrl.Replace(templateVarAndValue.TemplateVariableName, templateVarAndValue.TemplateVariableValue);
}

View File

@ -1,9 +1,10 @@
using Ocelot.Library.Infrastructure.DownstreamRouteFinder;
using Ocelot.Library.Infrastructure.UrlMatcher;
namespace Ocelot.Library.Infrastructure.UrlTemplateReplacer
{
public interface IDownstreamUrlTemplateVariableReplacer
{
string ReplaceTemplateVariable(UrlMatch urlMatch);
string ReplaceTemplateVariable(DownstreamRoute downstreamRoute);
}
}

View File

@ -1,56 +1,62 @@
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.Library.Infrastructure.UrlMatcher;
using Microsoft.Extensions.Options;
using Ocelot.Library.Infrastructure.Configuration;
using Ocelot.Library.Infrastructure.DownstreamRouteFinder;
using Ocelot.Library.Infrastructure.UrlTemplateReplacer;
namespace Ocelot.Library.Middleware
{
using System.Net;
using Infrastructure.Configuration;
using Microsoft.Extensions.Options;
public class ProxyMiddleware
{
private readonly RequestDelegate _next;
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
private readonly IDownstreamUrlTemplateVariableReplacer _urlReplacer;
private readonly IOptions<Configuration> _configuration;
private readonly IDownstreamRouteFinder _downstreamRouteFinder;
public ProxyMiddleware(RequestDelegate next,
IUrlPathToUrlTemplateMatcher urlMatcher,
IDownstreamUrlTemplateVariableReplacer urlReplacer, IOptions<Configuration> configuration)
IDownstreamUrlTemplateVariableReplacer urlReplacer,
IOptions<Configuration> configuration,
IDownstreamRouteFinder downstreamRouteFinder)
{
_next = next;
_urlMatcher = urlMatcher;
_urlReplacer = urlReplacer;
_configuration = configuration;
_downstreamRouteFinder = downstreamRouteFinder;
}
public async Task Invoke(HttpContext context)
{
var upstreamUrlPath = context.Request.Path.ToString();
UrlMatch urlMatch = null;
var downstreamRoute = _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath);
foreach (var template in _configuration.Value.ReRoutes)
{
urlMatch = _urlMatcher.Match(upstreamUrlPath, template.UpstreamTemplate);
if (urlMatch.Match)
{
break;
}
}
if (urlMatch == null || !urlMatch.Match)
if (downstreamRoute.IsError)
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
var downstreamUrl = _urlReplacer.ReplaceTemplateVariable(urlMatch);
var downstreamUrl = _urlReplacer.ReplaceTemplateVariable(downstreamRoute.Data);
//make a http request to this endpoint...maybe bring in a library
using (var httpClient = new HttpClient())
{
var httpMethod = new HttpMethod(context.Request.Method);
var httpRequestMessage = new HttpRequestMessage(httpMethod, downstreamUrl);
var response = await httpClient.SendAsync(httpRequestMessage);
if (!response.IsSuccessStatusCode)
{
context.Response.StatusCode = (int)response.StatusCode;
return;
}
await context.Response.WriteAsync(await response.Content.ReadAsStringAsync());
}
await _next.Invoke(context);
}

View File

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Ocelot.Library.Infrastructure.DownstreamRouteFinder;
using Ocelot.Library.Middleware;
namespace Ocelot
@ -36,6 +37,7 @@ namespace Ocelot
// Add framework services.
services.AddSingleton<IUrlPathToUrlTemplateMatcher, UrlPathToUrlTemplateMatcher>();
services.AddSingleton<IDownstreamUrlTemplateVariableReplacer, DownstreamUrlTemplateVariableReplacer>();
services.AddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.