Add support for httpmethods in swaggatherer

This commit is contained in:
Ryan Nowak 2018-07-11 21:23:38 -07:00
parent 2d53d398b2
commit 7aba48ca27
3 changed files with 32 additions and 11 deletions

View File

@ -2,10 +2,12 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing.EndpointConstraints;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Routing.Matchers namespace Microsoft.AspNetCore.Routing.Matchers
@ -23,15 +25,21 @@ namespace Microsoft.AspNetCore.Routing.Matchers
return services.BuildServiceProvider(); return services.BuildServiceProvider();
} }
internal static MatcherEndpoint CreateEndpoint(string template) internal static MatcherEndpoint CreateEndpoint(string template, string httpMethod = null)
{ {
var metadata = new List<object>();
if (httpMethod != null)
{
metadata.Add(new HttpMethodEndpointConstraint(new string[] { httpMethod, }));
}
return new MatcherEndpoint( return new MatcherEndpoint(
(next) => (context) => Task.CompletedTask, (next) => (context) => Task.CompletedTask,
template, template,
new RouteValueDictionary(), new RouteValueDictionary(),
new RouteValueDictionary(), new RouteValueDictionary(),
0, 0,
EndpointMetadataCollection.Empty, new EndpointMetadataCollection(metadata),
template); template);
} }

View File

@ -18,6 +18,7 @@ namespace Swaggatherer
{ {
Invoke = InvokeCore; Invoke = InvokeCore;
HttpMethods = Option("-m|--method", "allow multiple endpoints with different http method", CommandOptionType.NoValue);
Input = Option("-i", "input swagger 2.0 JSON file", CommandOptionType.MultipleValue); Input = Option("-i", "input swagger 2.0 JSON file", CommandOptionType.MultipleValue);
InputDirectory = Option("-d", "input directory", CommandOptionType.SingleValue); InputDirectory = Option("-d", "input directory", CommandOptionType.SingleValue);
Output = Option("-o", "output", CommandOptionType.SingleValue); Output = Option("-o", "output", CommandOptionType.SingleValue);
@ -29,6 +30,9 @@ namespace Swaggatherer
public CommandOption InputDirectory { get; } public CommandOption InputDirectory { get; }
// Support multiple endpoints that are distinguished only by http method.
public CommandOption HttpMethods { get; }
public CommandOption Output { get; } public CommandOption Output { get; }
private int InvokeCore() private int InvokeCore()
@ -55,6 +59,7 @@ namespace Swaggatherer
Input.Values.AddRange(Directory.EnumerateFiles(InputDirectory.Value(), "*.json", SearchOption.AllDirectories)); Input.Values.AddRange(Directory.EnumerateFiles(InputDirectory.Value(), "*.json", SearchOption.AllDirectories));
} }
Console.WriteLine($"Processing {Input.Values.Count} files...");
var entries = new List<RouteEntry>(); var entries = new List<RouteEntry>();
for (var i = 0; i < Input.Values.Count; i++) for (var i = 0; i < Input.Values.Count; i++)
{ {
@ -69,7 +74,6 @@ namespace Swaggatherer
{ {
Out.WriteLine("Skipping route with complex segment: " + entries[i].Template.TemplateText); Out.WriteLine("Skipping route with complex segment: " + entries[i].Template.TemplateText);
entries.RemoveAt(i); entries.RemoveAt(i);
break;
} }
} }
@ -96,7 +100,7 @@ namespace Swaggatherer
matches.Add(entry); matches.Add(entry);
} }
// We're not too sophisticated with how we generate parameter values, just hoping for // We're not too sophisticated with how we generate parameter values, just hoping for
// the best. For parameters we generate a segment that is the same length as the parameter name // the best. For parameters we generate a segment that is the same length as the parameter name
// but with a minimum of 5 characters to avoid collisions. // but with a minimum of 5 characters to avoid collisions.
@ -128,14 +132,14 @@ namespace Swaggatherer
} }
catch (JsonReaderException ex) catch (JsonReaderException ex)
{ {
Out.WriteLine("Error reading: {0}"); Out.WriteLine($"Error reading: {input}");
Out.WriteLine(ex); Out.WriteLine(ex);
return new JObject(); return new JObject();
} }
} }
} }
private static void ParseEntries(JObject input, List<RouteEntry> entries) private void ParseEntries(JObject input, List<RouteEntry> entries)
{ {
var basePath = ""; var basePath = "";
if (input["basePath"] is JProperty basePathProperty) if (input["basePath"] is JProperty basePathProperty)
@ -153,7 +157,7 @@ namespace Swaggatherer
var parsed = TemplateParser.Parse(template); var parsed = TemplateParser.Parse(template);
entries.Add(new RouteEntry() entries.Add(new RouteEntry()
{ {
Method = method.Name, Method = HttpMethods.HasValue() ? method.Name.ToString() : null,
Template = parsed, Template = parsed,
Precedence = RoutePrecedence.ComputeInbound(parsed), Precedence = RoutePrecedence.ComputeInbound(parsed),
}); });
@ -175,7 +179,7 @@ namespace Swaggatherer
return false; return false;
} }
private static bool IsDuplicateTemplate(RouteEntry entry, List<RouteEntry> others) private bool IsDuplicateTemplate(RouteEntry entry, List<RouteEntry> others)
{ {
for (var j = 0; j < others.Count; j++) for (var j = 0; j < others.Count; j++)
{ {
@ -187,13 +191,20 @@ namespace Swaggatherer
for (var k = 0; k < entry.Template.Segments.Count; k++) for (var k = 0; k < entry.Template.Segments.Count; k++)
{ {
if (!string.Equals( if (!string.Equals(
entry.Template.Segments[k].Parts[0].Text, entry.Template.Segments[k].Parts[0].Text,
other.Template.Segments[k].Parts[0].Text, other.Template.Segments[k].Parts[0].Text,
StringComparison.OrdinalIgnoreCase)) StringComparison.OrdinalIgnoreCase))
{ {
isSame = false; isSame = false;
break; break;
} }
if (HttpMethods.HasValue() &&
!string.Equals(entry.Method, other.Method, StringComparison.OrdinalIgnoreCase))
{
isSame = false;
break;
}
} }
if (isSame) if (isSame)

View File

@ -12,8 +12,10 @@ namespace Swaggatherer
{ {
var setupEndpointsLines = new List<string>(); var setupEndpointsLines = new List<string>();
for (var i = 0; i < entries.Count; i++) for (var i = 0; i < entries.Count; i++)
{ {
setupEndpointsLines.Add($" _endpoints[{i}] = CreateEndpoint(\"{entries[i].Template.TemplateText}\");"); var entry = entries[i];
var httpMethodText = entry.Method == null ? string.Empty : $", \"{entry.Method.ToUpperInvariant()}\"";
setupEndpointsLines.Add($" _endpoints[{i}] = CreateEndpoint(\"{entry.Template.TemplateText}\"{httpMethodText});");
} }
var setupRequestsLines = new List<string>(); var setupRequestsLines = new List<string>();