Skip to content

Commit 32bc2ca

Browse files
tchowiceKielekRassKysolomchenko
authored
[Instrumentation.AspNet] Fix multiple routes of same template in attribute-based routing (#2250)
Co-authored-by: Piotr Kiełkowicz <[email protected]> Co-authored-by: Rasmus Kuusmann <[email protected]> Co-authored-by: Yevhenii Solomchenko <[email protected]>
1 parent 8a062aa commit 32bc2ca

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
* Updated OpenTelemetry core component version(s) to `1.10.0`.
1010
([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317))
1111

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

1418
Released 2024-Jun-18

src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ internal sealed class HttpRequestRouteHelper
2828
{
2929
// WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http.
3030

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

3538
_ = this.routeFetcher.TryFetch(subRouteData, out var route);

test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public enum QueryRedactionDisableBehavior
4141
[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}")]
4242
[InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")]
4343
[InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")]
44+
[InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 5, "subroute/{customerId}", "GET subroute/{customerId}")]
4445
[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
4546
[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
4647
[InlineData("http://localhost/", "http", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option

test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4+
using System.Net.Http;
45
using System.Web;
56
using System.Web.Routing;
67

@@ -40,6 +41,32 @@ public static HttpContext BuildHttpContext(string url, int routeType, string? ro
4041
"MS_SubRoutes",
4142
value);
4243
break;
44+
case 5: // Multi-method attribute routing WebAPI.
45+
routeData = new RouteData();
46+
var httpMethods = new[] { HttpMethod.Get, HttpMethod.Put, HttpMethod.Delete };
47+
48+
var multiMethodSubroutes = httpMethods.Select(method => new
49+
{
50+
Route = new
51+
{
52+
RouteTemplate = routeTemplate,
53+
DataTokens = new Dictionary<string, object>
54+
{
55+
["actions"] = new[]
56+
{
57+
new
58+
{
59+
SupportedHttpMethods = new[] { method },
60+
},
61+
},
62+
},
63+
},
64+
}).ToArray();
65+
66+
routeData.Values.Add(
67+
"MS_SubRoutes",
68+
multiMethodSubroutes);
69+
break;
4370
default:
4471
throw new NotSupportedException();
4572
}

0 commit comments

Comments
 (0)