Skip to content

Commit

Permalink
Merge branch 'refs/heads/master' into feature/CSHARP-77
Browse files Browse the repository at this point in the history
  • Loading branch information
OlgaStarkova-Tochka committed Sep 20, 2024
2 parents 6298a81 + d8d0c5c commit 24ea29d
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 23 deletions.
33 changes: 33 additions & 0 deletions src/Tochka.JsonRpc.Common/JsonRpcErrorCodes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace Tochka.JsonRpc.Common;

/// <summary>
/// Reserved predefined JSON-RPC error codes
/// </summary>
public static class JsonRpcErrorCodes
{
/// <summary>
/// Invalid JSON was received by the server.
/// An error occurred on the server while parsing the JSON text.
/// </summary>
public const int ParseError = -32700;

/// <summary>
/// The JSON sent is not a valid Request object
/// </summary>
public const int InvalidRequest = -32600;

/// <summary>
/// The method does not exist or is not available
/// </summary>
public const int MethodNotFound = -32601;

/// <summary>
/// Invalid method parameters
/// </summary>
public const int InvalidParams = -32602;

/// <summary>
/// Internal JSON-RPC error
/// </summary>
public const int InternalError = -32603;
}
6 changes: 6 additions & 0 deletions src/Tochka.JsonRpc.Common/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,9 @@ Tochka.JsonRpc.Common.Features.JsonRpcFeature.RawCall.set -> void
Tochka.JsonRpc.Common.Features.JsonRpcFeature.Response.get -> Tochka.JsonRpc.Common.Models.Response.IResponse?
Tochka.JsonRpc.Common.Features.JsonRpcFeature.Response.set -> void
const Tochka.JsonRpc.Common.JsonRpcConstants.OutgoingHttpRequestOptionMethodNameKey = "tochka_outgoing_http_request_method_name" -> string!
const Tochka.JsonRpc.Common.JsonRpcErrorCodes.InternalError = -32603 -> int
const Tochka.JsonRpc.Common.JsonRpcErrorCodes.InvalidParams = -32602 -> int
const Tochka.JsonRpc.Common.JsonRpcErrorCodes.InvalidRequest = -32600 -> int
const Tochka.JsonRpc.Common.JsonRpcErrorCodes.MethodNotFound = -32601 -> int
const Tochka.JsonRpc.Common.JsonRpcErrorCodes.ParseError = -32700 -> int
Tochka.JsonRpc.Common.JsonRpcErrorCodes
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ internal virtual List<OpenRpcServer> GetServers(Uri host)
var controllerSummary = actionDescriptor?.ControllerTypeInfo.GetXmlDocsSummary();
var route = apiDescription.RelativePath?.Split('#').First();

if (string.IsNullOrWhiteSpace(route) || $"/{route}" == serverOptions.RoutePrefix)
if (string.IsNullOrWhiteSpace(route) || $"/{route}" == serverOptions.RoutePrefix || servers.Any(x => x.Url.AbsolutePath.Contains(route, StringComparison.OrdinalIgnoreCase)))
{
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Tochka.JsonRpc.Server/Routing/JsonRpcMatcherPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ private static bool ValidateCandidates(CandidateSet candidates, ICall call)
for (var i = 0; i < candidates.Count; i++)
{
var candidate = candidates[i];
var jsonRpcMetadata = candidate.Endpoint.Metadata.GetMetadata<JsonRpcMethodAttribute>()!;
var methodMatches = call.Method == jsonRpcMetadata.Method;
var jsonRpcMetadata = candidate.Endpoint.Metadata.GetMetadata<JsonRpcMethodAttribute>();
var methodMatches = call.Method == jsonRpcMetadata?.Method;
candidates.SetValidity(i, methodMatches);
if (methodMatches)
{
Expand Down
16 changes: 10 additions & 6 deletions src/Tochka.JsonRpc.Server/Services/JsonRpcErrorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@ public JsonRpcErrorFactory(IOptions<JsonRpcServerOptions> options, ILogger<JsonR

/// <inheritdoc />
public IError ParseError(object? errorData) =>
new Error<object>(-32700, "Parse error", WrapExceptions(errorData));
new Error<object>(JsonRpcErrorCodes.ParseError, "Parse error", WrapExceptions(errorData));

/// <inheritdoc />
public IError InvalidRequest(object? errorData) =>
new Error<object>(-32600, "Invalid Request", WrapExceptions(errorData));
new Error<object>(JsonRpcErrorCodes.InvalidRequest, "Invalid Request", WrapExceptions(errorData));

/// <inheritdoc />
public IError MethodNotFound(object? errorData) =>
new Error<object>(-32601, "Method not found", WrapExceptions(errorData));
new Error<object>(JsonRpcErrorCodes.MethodNotFound, "Method not found", WrapExceptions(errorData));

/// <inheritdoc />
public IError InvalidParams(object? errorData) =>
new Error<object>(-32602, "Invalid params", WrapExceptions(errorData));
new Error<object>(JsonRpcErrorCodes.InvalidParams, "Invalid params", WrapExceptions(errorData));

/// <inheritdoc />
public IError InternalError(object? errorData) =>
new Error<object>(-32603, "Internal error", WrapExceptions(errorData));
new Error<object>(JsonRpcErrorCodes.InternalError, "Internal error", WrapExceptions(errorData));

/// <inheritdoc />
public IError ServerError(int code, object? errorData) =>
Expand Down Expand Up @@ -120,7 +120,11 @@ public virtual IError Error(int code, string message, object? errorData) =>
/// </summary>
/// <param name="code">error.code</param>
[ExcludeFromCodeCoverage]
protected static bool IsSpecial(int code) => code is -32700 or -32600 or -32601 or -32602 or -32603;
protected static bool IsSpecial(int code) => code is JsonRpcErrorCodes.ParseError
or JsonRpcErrorCodes.InvalidRequest
or JsonRpcErrorCodes.MethodNotFound
or JsonRpcErrorCodes.InvalidParams
or JsonRpcErrorCodes.InternalError;

/// <summary>
/// Check if code is reserved for server implementation in specification
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,11 @@ public void GetServersReturnsAllEndpoints()
{
var apiDescription1 = GetValidDescription();
var apiDescription2 = GetValidDescription();
var path = "default/path";
var firstPath = "first/path";
var secondPath = "second/path";
serverOptions.RoutePrefix = "/";
apiDescription1.RelativePath = $"{path}#{MethodName}";
apiDescription2.RelativePath = $"{path}#{MethodName}";
apiDescription1.RelativePath = $"{firstPath}#{MethodName}";
apiDescription2.RelativePath = $"{secondPath}#{MethodName}";

apiDescriptionsProviderMock.Setup(static p => p.ApiDescriptionGroups)
.Returns(new ApiDescriptionGroupCollection(new List<ApiDescriptionGroup>
Expand All @@ -157,6 +158,32 @@ public void GetServersReturnsAllEndpoints()
result.Should().HaveCount(2);
}

[Test]
public void GetServersSameRouteReturnsOnlyOne()
{
var apiDescription1 = GetValidDescription();
var apiDescription2 = GetValidDescription();
var samePath = "default/path";
serverOptions.RoutePrefix = "/";
apiDescription1.RelativePath = $"{samePath}#{MethodName}";
apiDescription2.RelativePath = $"{samePath}#{MethodName}";

apiDescriptionsProviderMock.Setup(static p => p.ApiDescriptionGroups)
.Returns(new ApiDescriptionGroupCollection(new List<ApiDescriptionGroup>
{
new(null, new[] { apiDescription1 }),
new(null, new[] { apiDescription2 }),
},
0))
.Verifiable();

var result = documentGeneratorMock.Object.GetServers(new Uri(Host));

apiDescriptionsProviderMock.Verify();
documentGeneratorMock.Verify();
result.Should().HaveCount(1);
}

[Test]
public void GetServersPathAndRoutePrefixSameReturnsEmptyServers()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void ParseError_WrapException()

var result = errorFactoryMock.Object.ParseError(errorData);

var expected = new Error<object>(-32700, "Parse error", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.ParseError, "Parse error", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand All @@ -56,7 +56,7 @@ public void InvalidRequest_WrapException()

var result = errorFactoryMock.Object.InvalidRequest(errorData);

var expected = new Error<object>(-32600, "Invalid Request", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.InvalidRequest, "Invalid Request", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand All @@ -72,7 +72,7 @@ public void MethodNotFound_WrapException()

var result = errorFactoryMock.Object.MethodNotFound(errorData);

var expected = new Error<object>(-32601, "Method not found", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.MethodNotFound, "Method not found", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand All @@ -88,7 +88,7 @@ public void InvalidParams_WrapException()

var result = errorFactoryMock.Object.InvalidParams(errorData);

var expected = new Error<object>(-32602, "Invalid params", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.InvalidParams, "Invalid params", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand All @@ -104,7 +104,7 @@ public void InternalError_WrapException()

var result = errorFactoryMock.Object.InternalError(errorData);

var expected = new Error<object>(-32603, "Internal error", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.InternalError, "Internal error", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand Down Expand Up @@ -215,7 +215,7 @@ public void Exception_JsonRpcMethodNotFoundException_ReturnMethodNotFoundError()

var result = errorFactoryMock.Object.Exception(exception);

var expected = new Error<object>(-32601, "Method not found", new { Method = methodName });
var expected = new Error<object>(JsonRpcErrorCodes.MethodNotFound, "Method not found", new { Method = methodName });
result.Should().BeEquivalentTo(expected);
}

Expand All @@ -241,7 +241,7 @@ public void Exception_JsonRpcFormatException_ReturnInvalidRequestError()

var result = errorFactoryMock.Object.Exception(exception);

var expected = new Error<object>(-32600, "Invalid Request", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.InvalidRequest, "Invalid Request", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand Down Expand Up @@ -274,7 +274,7 @@ public void HttpError_HttpCode400Or422_ReturnInvalidParamsError(int httpCode)

var result = errorFactoryMock.Object.HttpError(httpCode, errorData);

var expected = new Error<object>(-32602, "Invalid params", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.InvalidParams, "Invalid params", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand All @@ -291,7 +291,7 @@ public void HttpError_HttpCode401Or403_ReturnMethodNotFoundError(int httpCode)

var result = errorFactoryMock.Object.HttpError(httpCode, errorData);

var expected = new Error<object>(-32601, "Method not found", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.MethodNotFound, "Method not found", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand Down Expand Up @@ -323,7 +323,7 @@ public void HttpError_HttpCode415_ReturnParseError()

var result = errorFactoryMock.Object.HttpError(415, errorData);

var expected = new Error<object>(-32700, "Parse error", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.ParseError, "Parse error", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand All @@ -339,7 +339,7 @@ public void HttpError_HttpCode500_ReturnInternalError()

var result = errorFactoryMock.Object.HttpError(500, errorData);

var expected = new Error<object>(-32603, "Internal error", wrappedData);
var expected = new Error<object>(JsonRpcErrorCodes.InternalError, "Internal error", wrappedData);
result.Should().BeEquivalentTo(expected);
errorFactoryMock.Verify();
}
Expand Down

0 comments on commit 24ea29d

Please sign in to comment.