예제 #1
0
        public void TestAddToService1ParamCS_ByIdx()
        {
            const string testString = "how long is this?";
            var exptectedLength = testString.Length;
            const int testId = 29;
            const string testMethodName = "testMethod";
            var fun = new Func<string, int>(inputString => inputString.Length);

            // SETUP
            var rpcHost = new JAAM.RPC.RPCService();
            rpcHost.AddToServiceCS(testMethodName, "inputString", fun);

            // INVOKE
            var callResult = rpcHost.Invoke(0,new RpcRequest<string>(testMethodName, testString, testId));

            Assert.AreEqual(testId, callResult.Id); // make sure we got a result for the same ID we passed in
            Assert.AreEqual(exptectedLength, callResult.Result); // make sure the result we got matches the calculation
            Assert.IsNull(callResult.Error); // make sure we didn't error

        }
예제 #2
0
        public void TestAddToService1ParamCS_ByIdx()
        {
            const string testString      = "how long is this?";
            var          exptectedLength = testString.Length;
            const int    testId          = 29;
            const string testMethodName  = "testMethod";
            var          fun             = new Func <string, int>(inputString => inputString.Length);

            // SETUP
            var rpcHost = new JAAM.RPC.RPCService();

            rpcHost.AddToServiceCS(testMethodName, "inputString", fun);

            // INVOKE
            var callResult = rpcHost.Invoke(0, new RpcRequest <string>(testMethodName, testString, testId));

            Assert.AreEqual(testId, callResult.Id);              // make sure we got a result for the same ID we passed in
            Assert.AreEqual(exptectedLength, callResult.Result); // make sure the result we got matches the calculation
            Assert.IsNull(callResult.Error);                     // make sure we didn't error
        }
예제 #3
0
        public void TestAddToService2ParamCSExpectedFailBecauseParameterTypesDoNotMatchDelegateSignature()
        {
            const string testString     = "how long is this?";
            const int    testMul        = 23;
            const int    testId         = 29;
            const string testMethodName = "testMethod";
            var          fun            = new Func <string, int, int>((inputString, mul) => inputString.Length * mul);
            var          expectedResult = fun(testString, testMul);

            // SETUP
            var rpcHost = new JAAM.RPC.RPCService();

            rpcHost.AddToServiceCS(testMethodName, "inputString", "mul", fun);

            // INVOKE
            var callResult = rpcHost.Invoke(new RpcRequest <int, string>(testMethodName, testMul, testString, testId));

            Assert.IsNotNull(callResult.Error);                    // make sure we didn't error
            Assert.AreEqual(testId, callResult.Id);                // make sure we got a result for the same ID we passed in
            Assert.AreNotEqual(expectedResult, callResult.Result); // make sure the result we got matches the calculation
        }
예제 #4
0
        public void TestAddToService2ParamCSExpectedFailBecauseParameterTypesDoNotMatchDelegateSignature()
        {
            const string testString = "how long is this?";
            const int testMul = 23;
            const int testId = 29;
            const string testMethodName = "testMethod";
            var fun = new Func<string, int, int>((inputString, mul) => inputString.Length * mul);
            var expectedResult = fun(testString, testMul);

            // SETUP
            var rpcHost = new JAAM.RPC.RPCService();
            rpcHost.AddToServiceCS(testMethodName, "inputString", "mul", fun);

            // INVOKE
            var callResult = rpcHost.Invoke(new RpcRequest<int, string>(testMethodName, testMul, testString, testId));

            Assert.IsNotNull(callResult.Error); // make sure we didn't error
            Assert.AreEqual(testId, callResult.Id); // make sure we got a result for the same ID we passed in
            Assert.AreNotEqual(expectedResult, callResult.Result); // make sure the result we got matches the calculation
        }
예제 #5
0
        /// <summary>
        /// Invokes a method to handle a JsonRpc request.
        /// </summary>
        /// <param name="Rpc">JsonRpc Request to be processed</param>
        /// <param name="RpcContext">Optional context that will be available from within the jsonRpcMethod.</param>
        /// <returns></returns>
        public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null)
        {
            AddRpcContext(RpcContext);

            var preProcessingException = PreProcess(Rpc, RpcContext);

            if (preProcessingException != null)
            {
                return(new JsonResponse()
                {
                    Error = preProcessingException,
                    Id = Rpc.Id
                });
            }

            SMDService metadata     = null;
            var        haveMetadata = this.MetaData.Services.TryGetValue(Rpc.Method, out metadata);

            if (Rpc.Params is ICollection == false)
            {
                return(new JsonResponse()
                {
                    Result = null,
                    Error = new JsonRpcException(-32602,
                                                 "Invalid params", "The number of parameters could not be counted"),
                    Id = Rpc.Id
                });
            }

            bool isJObject = Rpc.Params is Newtonsoft.Json.Linq.JObject;
            bool isJArray  = Rpc.Params is Newtonsoft.Json.Linq.JArray;

            object[] parameters          = null;
            bool     expectsRefException = false;
            var      metaDataParamCount  = metadata.parameters.Count(x => x != null);

            var getCount   = Rpc.Params as ICollection;
            var loopCt     = getCount.Count;
            var paramCount = loopCt;

            if (paramCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount - 1].ObjectType.Name.Contains(typeof(JsonRpcException).Name))
            {
                paramCount++;
                expectsRefException = true;
            }
            parameters = new object[paramCount];

            if (isJArray)
            {
                var jarr = ((Newtonsoft.Json.Linq.JArray)Rpc.Params);
                //var loopCt = jarr.Count;
                //var pCount = loopCt;
                //if (pCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount].GetType() == typeof(JsonRpcException))
                //    pCount++;
                //parameters = new object[pCount];
                for (int i = 0; i < loopCt; i++)
                {
                    parameters[i] = CleanUpParameter(jarr[i], metadata.parameters[i]);
                }
            }
            else if (isJObject)
            {
                var jo = Rpc.Params as Newtonsoft.Json.Linq.JObject;
                //var loopCt = jo.Count;
                //var pCount = loopCt;
                //if (pCount == metaDataParamCount - 1 && metadata.parameters[metaDataParamCount].GetType() == typeof(JsonRpcException))
                //    pCount++;
                //parameters = new object[pCount];
                var asDict = jo as IDictionary <string, Newtonsoft.Json.Linq.JToken>;
                for (int i = 0; i < loopCt; i++)
                {
                    if (asDict.ContainsKey(metadata.parameters[i].Name) == false)
                    {
                        return(new JsonResponse()
                        {
                            Error = ProcessException(Rpc,
                                                     new JsonRpcException(-32602,
                                                                          "Invalid params",
                                                                          string.Format("Named parameter '{0}' was not present.",
                                                                                        metadata.parameters[i].Name)
                                                                          ))
                            , Id = Rpc.Id
                        });
                    }
                    parameters[i] = CleanUpParameter(jo[metadata.parameters[i].Name], metadata.parameters[i]);
                }
            }

            // Optional Parameter support
            // check if we still miss parameters compared to metadata which may include optional parameters.
            // if the rpc-call didn't supply a value for an optional parameter, we should be assinging the default value of it.
            if (parameters.Length < metaDataParamCount && metadata.defaultValues.Length > 0)     // rpc call didn't set values for all optional parameters, so we need to assign the default values for them.
            {
                var paramIndex         = parameters.Length;                                      // the index we should start storing default values of optional parameters.
                var missingParamsCount = metaDataParamCount - parameters.Length;                 // the amount of optional parameters without a value set by rpc-call.
                Array.Resize(ref parameters, parameters.Length + metadata.defaultValues.Length); // resize the array to include all optional parameters.

                // we need to add in reverse order as parameters can appear after all required parameters.
                // as some of the optional parameters could already have assigned their values in rpc-call,
                // by starting from the end we can make sure we only add the required default values.
                for (int k = missingParamsCount; k > 0; k--)
                {
                    var optionalParamIndex = k - 1;                                            // the index of the optional parameter we will be currently setting a default value.
                    parameters[paramIndex] = metadata.defaultValues[optionalParamIndex].Value; // set the default value for the optional parameter that rpc-call didn't set a value for.
                    paramIndex++;
                    paramCount++;                                                              // we need to increase the paramCount by one each time we add default-value for an optional parameter that rpc-call didn't set a value for.
                }
            }

            if (parameters.Length != metaDataParamCount)
            {
                return(new JsonResponse()
                {
                    Error = ProcessException(Rpc,
                                             new JsonRpcException(-32602,
                                                                  "Invalid params",
                                                                  string.Format("Expecting {0} parameters, and received {1}",
                                                                                metadata.parameters.Length,
                                                                                parameters.Length)
                                                                  )),
                    Id = Rpc.Id
                });
            }

            try
            {
                var response = _rpc.Invoke(new JAAM.RPC.RpcRequest(Rpc.Method, parameters, Rpc.Id.GetHashCode()));
                if (haveMetadata == false || metadata == null)
                {
                    return(new JsonResponse()
                    {
                        Result = null, Error = new JsonRpcException(-32601, "Method not found", "The method does not exist / is not available."), Id = Rpc.Id
                    });
                }

                if (response.Error != null)
                {
                    // this is not right yet..
                    var testException = (response.Error.data as Exception);
                    if (testException != null && testException.InnerException is JsonRpcException)
                    {
                        return(new JsonResponse()
                        {
                            Error = ProcessException(Rpc, testException.InnerException as JsonRpcException)
                        });
                    }
                    // this at least works a little.
                    return(new JsonResponse()
                    {
                        Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", response.Error)), Id = Rpc.Id
                    });
                }

                var results = response.Result;

                var last = parameters.Length > 0 ? parameters[paramCount - 1]:null;
                JsonRpcException contextException;
                if (Task.CurrentId.HasValue && RpcExceptions.TryRemove(Task.CurrentId.Value, out contextException))
                {
                    return(new JsonResponse()
                    {
                        Error = ProcessException(Rpc, contextException), Id = Rpc.Id
                    });
                }
                if (expectsRefException && last != null && last is JsonRpcException)
                {
                    return(new JsonResponse()
                    {
                        Error = ProcessException(Rpc, last as JsonRpcException), Id = Rpc.Id
                    });
                }

                return(new JsonResponse()
                {
                    Result = results
                });
            }
            catch (Exception ex)
            {
                if (ex is TargetParameterCountException)
                {
                    return(new JsonResponse()
                    {
                        Error = ProcessException(Rpc, new JsonRpcException(-32602, "Invalid params", ex))
                    });
                }

                // We really dont care about the TargetInvocationException, just pass on the inner exception
                if (ex is JsonRpcException)
                {
                    return(new JsonResponse()
                    {
                        Error = ProcessException(Rpc, ex as JsonRpcException)
                    });
                }
                if (ex.InnerException != null && ex.InnerException is JsonRpcException)
                {
                    return(new JsonResponse()
                    {
                        Error = ProcessException(Rpc, ex.InnerException as JsonRpcException)
                    });
                }
                else if (ex.InnerException != null)
                {
                    return(new JsonResponse()
                    {
                        Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex.InnerException))
                    });
                }

                return(new JsonResponse()
                {
                    Error = ProcessException(Rpc, new JsonRpcException(-32603, "Internal Error", ex))
                });
            }
            finally
            {
                RemoveRpcContext();
            }
        }