예제 #1
0
        public void GetMatchingMethod_ListParam_Match_Snake_Case(string parameterNameCase)
        {
            DefaultRequestMatcher matcher = this.GetMatcher();

            IEnumerable <KeyValuePair <string, RpcParameterType> > parameters = new[]
            {
                new KeyValuePair <string, RpcParameterType>(parameterNameCase, RpcParameterType.String)
            };

            string        methodName       = nameof(MethodMatcherController.SnakeCaseParams);
            var           requestSignature = RpcRequestSignature.Create(methodName, parameters);
            RpcMethodInfo methodInfo       = matcher.GetMatchingMethod(requestSignature);


            Assert.NotNull(methodInfo);
            MethodInfo expectedMethodInfo = typeof(MethodMatcherController).GetMethod(methodName) !;

            Assert.Equal(expectedMethodInfo, methodInfo.MethodInfo);
            Assert.Single(methodInfo.Parameters);

            Assert.False(methodInfo.Parameters[0].IsOptional);
            Assert.Equal(typeof(string), methodInfo.Parameters[0].RawType);
            Assert.Equal(RpcParameterType.String, methodInfo.Parameters[0].Type);
            Assert.True(RpcUtil.NamesMatch(methodInfo.Parameters[0].Name, parameterNameCase));
        }
예제 #2
0
        public void Create_NullDictParam_Valid()
        {
            string methodName = "Test";
            var    signature  = RpcRequestSignature.Create(methodName, parameters: (IEnumerable <KeyValuePair <string, RpcParameterType> >?)null);

            Assert.Equal(methodName, signature.GetMethodName().ToString());
            Assert.False(signature.HasParameters);
            Assert.False(signature.IsDictionary);
            Assert.Empty(signature.ParametersAsList);
        }
예제 #3
0
        public void SimpleIterationSetup()
        {
            var parameters = new Dictionary <string, RpcParameterType>
            {
                { "a", RpcParameterType.Number },
                { "b", RpcParameterType.Boolean },
                { "c", RpcParameterType.String }
            };

            this.requestsignature = RpcRequestSignature.Create(nameof(MethodClass.SimpleParamsNoReturn), parameters);
        }
예제 #4
0
        public void Create_EmptyDictParam_Valid()
        {
            string methodName = "Test";
            var    parameters = new Dictionary <string, RpcParameterType>();
            var    signature  = RpcRequestSignature.Create(methodName, parameters);

            Assert.Equal(methodName, signature.GetMethodName().ToString());
            Assert.False(signature.HasParameters);
            Assert.True(signature.IsDictionary);
            this.AssertDictsEqual(parameters, signature.ParametersAsDict);
        }
예제 #5
0
        public void Create_MultiListParam_Valid()
        {
            string methodName = "Test";

            RpcParameterType[] parameters = new[] { RpcParameterType.String, RpcParameterType.Boolean, RpcParameterType.Null, RpcParameterType.Number, RpcParameterType.Object };
            var signature = RpcRequestSignature.Create(methodName, parameters);

            Assert.Equal(methodName, signature.GetMethodName().ToString());
            Assert.True(signature.HasParameters);
            Assert.False(signature.IsDictionary);
            Assert.Equal(parameters, signature.ParametersAsList);
        }
예제 #6
0
        public void Create_EmptyListParam_Valid()
        {
            string methodName = "Test";

            RpcParameterType[] parameters = new RpcParameterType[0];
            var signature = RpcRequestSignature.Create(methodName, parameters);

            Assert.Equal(methodName, signature.GetMethodName().ToString());
            Assert.False(signature.HasParameters);
            Assert.False(signature.IsDictionary);
            Assert.Equal(parameters, signature.ParametersAsList);
        }
예제 #7
0
        public void GetMatchingMethod_SimpleMulitParam_DictMatch()
        {
            DefaultRequestMatcher matcher = this.GetMatcher();

            var parameters = new Dictionary <string, RpcParameterType>
            {
                { "a", RpcParameterType.Number },
                { "b", RpcParameterType.Boolean },
                { "c", RpcParameterType.String },
                { "d", RpcParameterType.Object },
                { "e", RpcParameterType.Null }
            };
            string        methodName       = nameof(MethodMatcherController.SimpleMulitParam);
            var           requestSignature = RpcRequestSignature.Create(methodName, parameters);
            RpcMethodInfo methodInfo       = matcher.GetMatchingMethod(requestSignature);


            Assert.NotNull(methodInfo);
            MethodInfo expectedMethodInfo = typeof(MethodMatcherController).GetMethod(methodName) !;

            Assert.Equal(expectedMethodInfo, methodInfo.MethodInfo);
            Assert.Equal(5, methodInfo.Parameters.Length);

            Assert.False(methodInfo.Parameters[0].IsOptional);
            Assert.Equal(typeof(int), methodInfo.Parameters[0].RawType);
            Assert.Equal(RpcParameterType.Number, methodInfo.Parameters[0].Type);
            Assert.Equal("a", methodInfo.Parameters[0].Name);

            Assert.False(methodInfo.Parameters[1].IsOptional);
            Assert.Equal(typeof(bool), methodInfo.Parameters[1].RawType);
            Assert.Equal(RpcParameterType.Boolean, methodInfo.Parameters[1].Type);
            Assert.Equal("b", methodInfo.Parameters[1].Name);

            Assert.False(methodInfo.Parameters[2].IsOptional);
            Assert.Equal(typeof(string), methodInfo.Parameters[2].RawType);
            Assert.Equal(RpcParameterType.String, methodInfo.Parameters[2].Type);
            Assert.Equal("c", methodInfo.Parameters[2].Name);

            Assert.False(methodInfo.Parameters[3].IsOptional);
            Assert.Equal(typeof(object), methodInfo.Parameters[3].RawType);
            Assert.Equal(RpcParameterType.Object, methodInfo.Parameters[3].Type);
            Assert.Equal("d", methodInfo.Parameters[3].Name);

            Assert.True(methodInfo.Parameters[4].IsOptional);
            Assert.Equal(typeof(int?), methodInfo.Parameters[4].RawType);
            Assert.Equal(RpcParameterType.Object, methodInfo.Parameters[4].Type);
            Assert.Equal("e", methodInfo.Parameters[4].Name);
        }
예제 #8
0
        public void GetMatchingMethod_GuidParameter_Match()
        {
            string methodName = nameof(MethodMatcherController.GuidTypeMethod);

            DefaultRequestMatcher matcher   = this.GetMatcher(path: typeof(MethodMatcherController).GetTypeInfo().Name);
            var            requestSignature = RpcRequestSignature.Create(methodName, new[] { RpcParameterType.String });
            IRpcMethodInfo methodInfo       = matcher.GetMatchingMethod(requestSignature);

            Assert.NotNull(methodInfo);
            Assert.Equal(methodName, methodInfo.Name);
            Assert.Single(methodInfo.Parameters);
            Assert.False(methodInfo.Parameters[0].IsOptional);
            Assert.Equal(typeof(Guid), methodInfo.Parameters[0].RawType);
            Assert.Equal(RpcParameterType.Object, methodInfo.Parameters[0].Type);
            Assert.Equal("guid", methodInfo.Parameters[0].Name);
        }
예제 #9
0
        public void GetMatchingMethod_WithRpcRoute()
        {
            string methodName = nameof(MethodMatcherController.GuidTypeMethod);
            RpcRequestSignature requestSignature = RpcRequestSignature.Create(methodName, new[] { RpcParameterType.String });

            DefaultRequestMatcher path1Matcher = this.GetMatcher(path: typeof(MethodMatcherController).GetTypeInfo().Name);
            IRpcMethodInfo        path1Match   = path1Matcher.GetMatchingMethod(requestSignature);

            Assert.NotNull(path1Match);


            DefaultRequestMatcher path2Matcher = this.GetMatcher(path: typeof(MethodMatcherDuplicatesController).GetTypeInfo().Name);
            IRpcMethodInfo        path2Match   = path2Matcher.GetMatchingMethod(requestSignature);

            Assert.NotNull(path2Match);
            Assert.NotSame(path1Match, path2Match);
        }
예제 #10
0
        public void Create_MultiDictParam_Valid()
        {
            string methodName = "Test";
            var    parameters = new Dictionary <string, RpcParameterType>
            {
                ["String"]  = RpcParameterType.String,
                ["Boolean"] = RpcParameterType.Boolean,
                ["Null"]    = RpcParameterType.Null,
                ["Number"]  = RpcParameterType.Number,
                ["Object"]  = RpcParameterType.Object,
            };
            var signature = RpcRequestSignature.Create(methodName, parameters);

            Assert.Equal(methodName, signature.GetMethodName().ToString());
            Assert.True(signature.HasParameters);
            Assert.True(signature.IsDictionary);
            this.AssertDictsEqual(parameters, signature.ParametersAsDict);
        }
예제 #11
0
        public void GetMatchingMethod_ListParam_Match()
        {
            DefaultRequestMatcher matcher = this.GetMatcher(path: typeof(MethodMatcherController).GetTypeInfo().Name);

            RpcParameterType[] parameters   = new[] { RpcParameterType.Object };
            string             methodName   = nameof(MethodMatcherController.List);
            var            requestSignature = RpcRequestSignature.Create(methodName, parameters);
            IRpcMethodInfo methodInfo       = matcher.GetMatchingMethod(requestSignature);


            Assert.NotNull(methodInfo);
            Assert.Equal(methodName, methodInfo.Name);
            Assert.Single(methodInfo.Parameters);

            Assert.False(methodInfo.Parameters[0].IsOptional);
            Assert.Equal(typeof(List <string>), methodInfo.Parameters[0].RawType);
            Assert.Equal(RpcParameterType.Object, methodInfo.Parameters[0].Type);
            Assert.Equal("values", methodInfo.Parameters[0].Name);
        }
예제 #12
0
        public void GetMatchingMethod_CulturallyInvariantComparison()
        {
            DefaultRequestMatcher matcher = this.GetMatcher(path: typeof(MethodMatcherController).GetTypeInfo().Name);

            RpcParameterType[] parameters = Array.Empty <RpcParameterType>();
            string             methodName = nameof(MethodMatcherController.IsLunchTime);
            // Use lowercase version of method name when making request.
            var methodNameLower  = methodName.ToLowerInvariant();
            var requestSignature = RpcRequestSignature.Create(methodNameLower, parameters);
            var previousCulture  = System.Globalization.CultureInfo.CurrentCulture;

            // Switch to a culture that would result in lowercasing 'I' to
            // U+0131, if not done with invariant culture.
            System.Globalization.CultureInfo.CurrentCulture = new System.Globalization.CultureInfo("az");
            IRpcMethodInfo methodInfo = matcher.GetMatchingMethod(requestSignature);

            Assert.NotNull(methodInfo);
            Assert.Equal(methodName, methodInfo.Name);
            System.Globalization.CultureInfo.CurrentCulture = previousCulture;
        }
예제 #13
0
        public void GetMatchingMethod_SimpleMulitParam_ListMatch()
        {
            DefaultRequestMatcher matcher = this.GetMatcher(path: typeof(MethodMatcherController).GetTypeInfo().Name);

            RpcParameterType[] parameters   = new[] { RpcParameterType.Number, RpcParameterType.Boolean, RpcParameterType.String, RpcParameterType.Object, RpcParameterType.Null };
            string             methodName   = nameof(MethodMatcherController.SimpleMulitParam);
            var            requestSignature = RpcRequestSignature.Create(methodName, parameters);
            IRpcMethodInfo methodInfo       = matcher.GetMatchingMethod(requestSignature);


            Assert.NotNull(methodInfo);
            Assert.Equal(methodName, methodInfo.Name);
            Assert.Equal(5, methodInfo.Parameters.Count);

            Assert.False(methodInfo.Parameters[0].IsOptional);
            Assert.Equal(typeof(int), methodInfo.Parameters[0].RawType);
            Assert.Equal(RpcParameterType.Number, methodInfo.Parameters[0].Type);
            Assert.Equal("a", methodInfo.Parameters[0].Name);

            Assert.False(methodInfo.Parameters[1].IsOptional);
            Assert.Equal(typeof(bool), methodInfo.Parameters[1].RawType);
            Assert.Equal(RpcParameterType.Boolean, methodInfo.Parameters[1].Type);
            Assert.Equal("b", methodInfo.Parameters[1].Name);

            Assert.False(methodInfo.Parameters[2].IsOptional);
            Assert.Equal(typeof(string), methodInfo.Parameters[2].RawType);
            Assert.Equal(RpcParameterType.String, methodInfo.Parameters[2].Type);
            Assert.Equal("c", methodInfo.Parameters[2].Name);

            Assert.False(methodInfo.Parameters[3].IsOptional);
            Assert.Equal(typeof(object), methodInfo.Parameters[3].RawType);
            Assert.Equal(RpcParameterType.Object, methodInfo.Parameters[3].Type);
            Assert.Equal("d", methodInfo.Parameters[3].Name);

            Assert.True(methodInfo.Parameters[4].IsOptional);
            Assert.Equal(typeof(int?), methodInfo.Parameters[4].RawType);
            Assert.Equal(RpcParameterType.Object, methodInfo.Parameters[4].Type);
            Assert.Equal("e", methodInfo.Parameters[4].Name);
        }
예제 #14
0
 public void ComplexIterationSetup()
 {
     this.requestsignature = RpcRequestSignature.Create(nameof(MethodClass.ComplexParamNoReturn), new[] { RpcParameterType.Object });
 }
예제 #15
0
 public void IterationSetup()
 {
     this.requestsignature = RpcRequestSignature.Create(nameof(MethodClass.NoParamsNoReturn));
 }
예제 #16
0
        /// <summary>
        /// Call the incoming Rpc request method and gives the appropriate response
        /// </summary>
        /// <param name="request">Rpc request</param>
        /// <param name="path">Rpc path that applies to the current request</param>
        /// <param name="routeContext">The context of the current rpc request</param>
        /// <returns>An Rpc response for the request</returns>
        public async Task <RpcResponse?> InvokeRequestAsync(RpcRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            this.logger.InvokingRequest(request.Id);
            RpcResponse rpcResponse;

            try
            {
                RpcMethodInfo rpcMethod;
                using (var requestSignature = RpcRequestSignature.Create(request))
                {
                    rpcMethod = this.rpcRequestMatcher.GetMatchingMethod(requestSignature);
                }

                bool isAuthorized = await this.authorizationHandler.IsAuthorizedAsync(rpcMethod.MethodInfo);

                if (isAuthorized)
                {
                    object[] realParameters = this.ParseParameters(request.Parameters, rpcMethod.Parameters);

                    this.logger.InvokeMethod(request.Method);
                    IRpcContext routeContext = this.contextAccessor.Value !;
                    object?     result       = await this.InvokeAsync(rpcMethod.MethodInfo, realParameters, request, routeContext.RequestServices);

                    this.logger.InvokeMethodComplete(request.Method);

                    if (result is IRpcMethodResult methodResult)
                    {
                        rpcResponse = methodResult.ToRpcResponse(request.Id);
                    }
                    else
                    {
                        rpcResponse = new RpcResponse(request.Id, result);
                    }
                }
                else
                {
                    var authError = new RpcError(RpcErrorCode.InvalidRequest, "Unauthorized");
                    rpcResponse = new RpcResponse(request.Id, authError);
                }
            }
            catch (Exception ex)
            {
                const string errorMessage = "An Rpc error occurred while trying to invoke request.";
                this.logger.LogException(ex, errorMessage);
                RpcError error;
                if (ex is RpcException rpcException)
                {
                    error = rpcException.ToRpcError(this.serverConfig.Value.ShowServerExceptions);
                }
                else
                {
                    error = new RpcError(RpcErrorCode.InternalError, errorMessage, ex);
                }
                rpcResponse = new RpcResponse(request.Id, error);
            }

            if (request.Id.HasValue)
            {
                this.logger.FinishedRequest(request.Id.ToString());
                //Only give a response if there is an id
                return(rpcResponse);
            }
            //TODO make no id run in a non-blocking way
            this.logger.FinishedRequestNoId();
            return(null);
        }