Skip to content

Commit e82d6a0

Browse files
authored
[fix] empty basePath routing #116 (#117)
1 parent b28916f commit e82d6a0

File tree

4 files changed

+52
-25
lines changed

4 files changed

+52
-25
lines changed

src/EdjCase.JsonRpc.Router/Defaults/DefaultRequestMatcher.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ namespace EdjCase.JsonRpc.Router.Defaults
1616
{
1717
internal class DefaultRequestMatcher : IRpcRequestMatcher
1818
{
19-
private static ConcurrentDictionary<RpcPath?, ConcurrentDictionary<RpcRequestSignature, IRpcMethodInfo[]>> requestToMethodCache { get; }
20-
= new ConcurrentDictionary<RpcPath?, ConcurrentDictionary<RpcRequestSignature, IRpcMethodInfo[]>>();
19+
private static ConcurrentDictionary<string, ConcurrentDictionary<RpcRequestSignature, IRpcMethodInfo[]>> requestToMethodCache { get; }
20+
= new ConcurrentDictionary<string, ConcurrentDictionary<RpcRequestSignature, IRpcMethodInfo[]>>();
2121

2222
private ILogger<DefaultRequestMatcher> logger { get; }
2323
private IRpcMethodProvider methodProvider { get; }
@@ -47,7 +47,7 @@ public IRpcMethodInfo GetMatchingMethod(RpcRequestSignature requestSignature)
4747
throw new RpcException(RpcErrorCode.MethodNotFound, $"No methods found for route");
4848
}
4949

50-
Span<IRpcMethodInfo> matches = this.FilterAndBuildMethodInfoByRequest(methods, requestSignature);
50+
Span<IRpcMethodInfo> matches = this.FilterAndBuildMethodInfoByRequest(context, methods, requestSignature);
5151
if (matches.Length == 1)
5252
{
5353
this.logger.RequestMatchedMethod();
@@ -85,11 +85,11 @@ public IRpcMethodInfo GetMatchingMethod(RpcRequestSignature requestSignature)
8585
throw new RpcException(RpcErrorCode.MethodNotFound, errorMessage);
8686
}
8787

88-
private IRpcMethodInfo[] FilterAndBuildMethodInfoByRequest(IReadOnlyList<IRpcMethodInfo> methods, RpcRequestSignature requestSignature)
88+
private IRpcMethodInfo[] FilterAndBuildMethodInfoByRequest(RpcContext context, IReadOnlyList<IRpcMethodInfo> methods, RpcRequestSignature requestSignature)
8989
{
9090
//If the request signature is found, it means we have the methods cached already
9191

92-
var rpcPath = this.contextAccessor.Get()?.Path;
92+
string rpcPath = context.Path?.ToString() ?? string.Empty;
9393
var rpcPathMethodsCache = DefaultRequestMatcher.requestToMethodCache.GetOrAdd(rpcPath, path => new ConcurrentDictionary<RpcRequestSignature, IRpcMethodInfo[]>());
9494
return rpcPathMethodsCache.GetOrAdd(requestSignature, BuildMethodCache);
9595
IRpcMethodInfo[] BuildMethodCache(RpcRequestSignature s)

src/EdjCase.JsonRpc.Router/RpcPath.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,9 @@ public RpcPath Clone()
249249
return new RpcPath(newComponents);
250250
}
251251

252-
public static implicit operator string(RpcPath path)
252+
public static implicit operator string?(RpcPath path)
253253
{
254-
return path.ToString();
254+
return path?.ToString();
255255
}
256256

257257
public static implicit operator RpcPath(string s)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
3+
namespace EdjCase.JsonRpc.Router.Tests.Controllers
4+
{
5+
public class MethodMatcherThreeController
6+
{
7+
public Guid GuidTypeMethod(Guid guid)
8+
{
9+
return guid;
10+
}
11+
}
12+
}

test/EdjCase.JsonRpc.Router.Tests/MethodMatcherTests.cs

+33-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using EdjCase.JsonRpc.Router.Abstractions;
1+
using EdjCase.JsonRpc.Router.Abstractions;
22
using EdjCase.JsonRpc.Router.Defaults;
33
using Microsoft.Extensions.DependencyInjection;
44
using Microsoft.Extensions.Logging;
@@ -19,31 +19,30 @@ namespace EdjCase.JsonRpc.Router.Tests
1919
{
2020
public class MethodMatcherTests
2121
{
22-
private readonly IReadOnlyDictionary<RpcPath, IReadOnlyList<IRpcMethodInfo>> methodData;
22+
private readonly StaticRpcMethodDataAccessor methodDataAccessor;
2323

2424
public MethodMatcherTests()
25-
{
26-
this.methodData = new Dictionary<RpcPath, IReadOnlyList<IRpcMethodInfo>>
27-
{
25+
{
26+
var baserouteData = typeof(MethodMatcherThreeController)
27+
.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
28+
.Select(DefaultRpcMethodInfo.FromMethodInfo)
29+
.ToList();
30+
31+
var routeData = new Dictionary<RpcPath, IReadOnlyList<IRpcMethodInfo>>
32+
{
2833
[nameof(MethodMatcherController)] = typeof(MethodMatcherController)
2934
.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
3035
.Select(DefaultRpcMethodInfo.FromMethodInfo)
31-
.ToList(),
36+
.ToList(),
3237
[nameof(MethodMatcherDuplicatesController)] = typeof(MethodMatcherDuplicatesController)
3338
.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
3439
.Select(DefaultRpcMethodInfo.FromMethodInfo)
35-
.ToList()
36-
};
37-
}
38-
39-
private StaticRpcMethodDataAccessor GetMethodDataAccessor()
40-
{
41-
return new StaticRpcMethodDataAccessor()
42-
{
43-
Value = new RpcRouteMetaData(new List<IRpcMethodInfo>(), this.methodData)
44-
};
40+
.ToList()
41+
};
42+
this.methodDataAccessor = new StaticRpcMethodDataAccessor() { Value = new RpcRouteMetaData(baserouteData, routeData)};
4543
}
4644

45+
4746
private DefaultRequestMatcher GetMatcher(RpcPath? path = null)
4847
{
4948

@@ -64,7 +63,7 @@ private DefaultRequestMatcher GetMatcher(RpcPath? path = null)
6463
#pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
6564

6665

67-
var methodProvider = new StaticRpcMethodProvider(this.GetMethodDataAccessor());
66+
var methodProvider = new StaticRpcMethodProvider(this.methodDataAccessor);
6867
return new DefaultRequestMatcher(logger.Object, methodProvider, rpcContextAccessor.Object, rpcParameterConverter);
6968
}
7069

@@ -82,7 +81,11 @@ public void GetMatchingMethod_WithRpcRoute()
8281
DefaultRequestMatcher path2Matcher = this.GetMatcher(path: typeof(MethodMatcherDuplicatesController).GetTypeInfo().Name);
8382
IRpcMethodInfo path2Match = path2Matcher.GetMatchingMethod(requestSignature);
8483
Assert.NotNull(path2Match);
85-
Assert.NotSame(path1Match, path2Match);
84+
Assert.NotSame(path1Match, path2Match);
85+
86+
DefaultRequestMatcher path3Matcher = this.GetMatcher(path: null);
87+
IRpcMethodInfo path3Match = path3Matcher.GetMatchingMethod(requestSignature);
88+
Assert.NotNull(path2Match);
8689
}
8790

8891
[Fact]
@@ -349,6 +352,18 @@ public void GetMatchingMethod__Dictionary_Request_With_Optional_Parameters__Matc
349352

350353
Assert.NotNull(methodInfo);
351354
Assert.Equal(methodName, methodInfo.Name);
355+
}
356+
357+
358+
[Fact]
359+
public void GetMatchingMethod_WithoutRpcRoute()
360+
{
361+
string methodName = nameof(MethodMatcherController.GuidTypeMethod);
362+
RpcRequestSignature requestSignature = RpcRequestSignature.Create(methodName, new[] { RpcParameterType.String });
363+
364+
DefaultRequestMatcher path3Matcher = this.GetMatcher(path: null);
365+
IRpcMethodInfo path3Match = path3Matcher.GetMatchingMethod(requestSignature);
366+
Assert.NotNull(path3Match);
352367
}
353368
}
354369

0 commit comments

Comments
 (0)