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 }
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 }
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 }
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 }
/// <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(); } }