Skip to content

Commit

Permalink
[Instrumentation.AspNet] Fix multiple routes of same template in attr…
Browse files Browse the repository at this point in the history
…ibute-based routing (#2250)

Co-authored-by: Piotr Kiełkowicz <pkiekowicz@splunk.com>
Co-authored-by: Rasmus Kuusmann <rkuusmann@splunk.com>
Co-authored-by: Yevhenii Solomchenko <ysolomchenko@splunk.com>
  • Loading branch information
4 people authored Nov 18, 2024
1 parent 8a062aa commit 32bc2ca
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
* Updated OpenTelemetry core component version(s) to `1.10.0`.
([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317))

* Fixed an issue in ASP.NET instrumentation where route extraction failed for
attribute-based routing with multiple HTTP methods sharing the same route template.
([#2250](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2250))

## 1.9.0-beta.1

Released 2024-Jun-18
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ internal sealed class HttpRequestRouteHelper
{
// WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http.

if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1)
if (msSubRoutes is Array attributeRouting && attributeRouting.Length >= 1)
{
// There could be more than one subroute, each with a different method.
// But the template is the same across them, so we simply take the template
// from the first route.
var subRouteData = attributeRouting.GetValue(0);

_ = this.routeFetcher.TryFetch(subRouteData, out var route);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public enum QueryRedactionDisableBehavior
[InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, null, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")]
[InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")]
[InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")]
[InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 5, "subroute/{customerId}", "GET subroute/{customerId}")]
[InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered
[InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception
[InlineData("http://localhost/", "http", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option
Expand Down
27 changes: 27 additions & 0 deletions test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Net.Http;
using System.Web;
using System.Web.Routing;

Expand Down Expand Up @@ -40,6 +41,32 @@ public static HttpContext BuildHttpContext(string url, int routeType, string? ro
"MS_SubRoutes",
value);
break;
case 5: // Multi-method attribute routing WebAPI.
routeData = new RouteData();
var httpMethods = new[] { HttpMethod.Get, HttpMethod.Put, HttpMethod.Delete };

var multiMethodSubroutes = httpMethods.Select(method => new
{
Route = new
{
RouteTemplate = routeTemplate,
DataTokens = new Dictionary<string, object>
{
["actions"] = new[]
{
new
{
SupportedHttpMethods = new[] { method },
},
},
},
},
}).ToArray();

routeData.Values.Add(
"MS_SubRoutes",
multiMethodSubroutes);
break;
default:
throw new NotSupportedException();
}
Expand Down

0 comments on commit 32bc2ca

Please sign in to comment.