From 7aba48ca27967d5b3ec86c7b6e208dca13deadc9 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Wed, 11 Jul 2018 21:23:38 -0700 Subject: [PATCH] Add support for httpmethods in swaggatherer --- .../Matchers/MatcherBenchmarkBase.cs | 12 +++++++-- .../Swaggatherer/SwaggathererApplication.cs | 25 +++++++++++++------ benchmarks/Swaggatherer/Template.cs | 6 +++-- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/benchmarks/Microsoft.AspNetCore.Routing.Performance/Matchers/MatcherBenchmarkBase.cs b/benchmarks/Microsoft.AspNetCore.Routing.Performance/Matchers/MatcherBenchmarkBase.cs index a2032b3c48..1ab67c9235 100644 --- a/benchmarks/Microsoft.AspNetCore.Routing.Performance/Matchers/MatcherBenchmarkBase.cs +++ b/benchmarks/Microsoft.AspNetCore.Routing.Performance/Matchers/MatcherBenchmarkBase.cs @@ -2,10 +2,12 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing.EndpointConstraints; using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Routing.Matchers @@ -23,15 +25,21 @@ namespace Microsoft.AspNetCore.Routing.Matchers return services.BuildServiceProvider(); } - internal static MatcherEndpoint CreateEndpoint(string template) + internal static MatcherEndpoint CreateEndpoint(string template, string httpMethod = null) { + var metadata = new List(); + if (httpMethod != null) + { + metadata.Add(new HttpMethodEndpointConstraint(new string[] { httpMethod, })); + } + return new MatcherEndpoint( (next) => (context) => Task.CompletedTask, template, new RouteValueDictionary(), new RouteValueDictionary(), 0, - EndpointMetadataCollection.Empty, + new EndpointMetadataCollection(metadata), template); } diff --git a/benchmarks/Swaggatherer/SwaggathererApplication.cs b/benchmarks/Swaggatherer/SwaggathererApplication.cs index 570ec6d344..5cebbf96a2 100644 --- a/benchmarks/Swaggatherer/SwaggathererApplication.cs +++ b/benchmarks/Swaggatherer/SwaggathererApplication.cs @@ -18,6 +18,7 @@ namespace Swaggatherer { 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); InputDirectory = Option("-d", "input directory", CommandOptionType.SingleValue); Output = Option("-o", "output", CommandOptionType.SingleValue); @@ -29,6 +30,9 @@ namespace Swaggatherer public CommandOption InputDirectory { get; } + // Support multiple endpoints that are distinguished only by http method. + public CommandOption HttpMethods { get; } + public CommandOption Output { get; } private int InvokeCore() @@ -55,6 +59,7 @@ namespace Swaggatherer Input.Values.AddRange(Directory.EnumerateFiles(InputDirectory.Value(), "*.json", SearchOption.AllDirectories)); } + Console.WriteLine($"Processing {Input.Values.Count} files..."); var entries = new List(); 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); entries.RemoveAt(i); - break; } } @@ -96,7 +100,7 @@ namespace Swaggatherer matches.Add(entry); } - + // 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 // but with a minimum of 5 characters to avoid collisions. @@ -128,14 +132,14 @@ namespace Swaggatherer } catch (JsonReaderException ex) { - Out.WriteLine("Error reading: {0}"); + Out.WriteLine($"Error reading: {input}"); Out.WriteLine(ex); return new JObject(); } } } - private static void ParseEntries(JObject input, List entries) + private void ParseEntries(JObject input, List entries) { var basePath = ""; if (input["basePath"] is JProperty basePathProperty) @@ -153,7 +157,7 @@ namespace Swaggatherer var parsed = TemplateParser.Parse(template); entries.Add(new RouteEntry() { - Method = method.Name, + Method = HttpMethods.HasValue() ? method.Name.ToString() : null, Template = parsed, Precedence = RoutePrecedence.ComputeInbound(parsed), }); @@ -175,7 +179,7 @@ namespace Swaggatherer return false; } - private static bool IsDuplicateTemplate(RouteEntry entry, List others) + private bool IsDuplicateTemplate(RouteEntry entry, List others) { for (var j = 0; j < others.Count; j++) { @@ -187,13 +191,20 @@ namespace Swaggatherer for (var k = 0; k < entry.Template.Segments.Count; k++) { if (!string.Equals( - entry.Template.Segments[k].Parts[0].Text, + entry.Template.Segments[k].Parts[0].Text, other.Template.Segments[k].Parts[0].Text, StringComparison.OrdinalIgnoreCase)) { isSame = false; break; } + + if (HttpMethods.HasValue() && + !string.Equals(entry.Method, other.Method, StringComparison.OrdinalIgnoreCase)) + { + isSame = false; + break; + } } if (isSame) diff --git a/benchmarks/Swaggatherer/Template.cs b/benchmarks/Swaggatherer/Template.cs index 761be89a92..9c05aa5867 100644 --- a/benchmarks/Swaggatherer/Template.cs +++ b/benchmarks/Swaggatherer/Template.cs @@ -12,8 +12,10 @@ namespace Swaggatherer { var setupEndpointsLines = new List(); 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();