/// <summary> /// Process the request and all the responses (including errors) will be wrapped in json response /// The resolver will perform necessary checking against the request based on custom method attributes being requested and request information /// </summary> /// <param name="requestJson"></param> /// <returns></returns> private string ProcessRequest(JsonRpcRequestHeader requestHeader, string requestJson) { try { var request = JsonConvert.DeserializeObject<JsonRpcRequest>(requestJson); try { if (request != null) { ValidateRequest(request); // Perform pre processing // If no exception thrown then continue the method invocation PreprocessRequest(requestHeader, request); // When freezed, just discard the requests if (!_frozen) { foreach (var resolver in _resolvers) { // Perform method call with authorization // We pass the decision to resolver since it has knowledge about the method attributes if (resolver.HasMethod(request.Method)) return resolver.CallMethod(requestHeader, request, (requiredRoles) => AuthorizeMethod(requestHeader, request, requiredRoles), () => LogMethodCall(requestHeader, request)); } } throw new MethodNotFoundException(String.Format("Method {0} is not found", request.Method)); } throw new InvalidRequestExeption("Invalid request"); } catch (JsonRpcException ex) { return JsonRpcResponse.CreateJsonError(request.Id, ex.Code, ex.Message, ex.Message); } catch (ApplicationException ex) // this could be application logic error thrown from the service method { return JsonRpcResponse.CreateJsonError(request.Id, -1, ex.Message, ex.Message); } } catch (System.Exception ex) // this should be json related error { LogError(ex); return String.Empty; } }
/// <summary> /// Any preprocessing could be handled here. E.g decrypt, unzipped etc /// </summary> /// <param name="request"></param> private void PreprocessRequest(JsonRpcRequestHeader requestHeader, JsonRpcRequest request) { foreach (var proc in _requestProcessors) { proc.ProcessRequest(requestHeader, request); } }
private void AuthorizeMethod(JsonRpcRequestHeader requestHeader, JsonRpcRequest request, string requiredRoles) { // TODO: Provide the authorization for method call here if (_methodCallAuthorizer != null) { _methodCallAuthorizer.Authorize(requestHeader, request); } }
/// <summary> /// Logs method invocation /// </summary> /// <param name="requestHeader"></param> /// <param name="request"></param> private void LogMethodCall(JsonRpcRequestHeader requestHeader, JsonRpcRequest request) { Logger.Instance.Info(String.Format("{0} {1} {2}", requestHeader.User, requestHeader.IPAddress, request.Method)); if (_methodCallLogger != null) { _methodCallLogger.Log(requestHeader, request); } }
public string CallMethod(JsonRpcRequestHeader requestHeader, JsonRpcRequest request, Action<string> methodAuthorizer, Action methodLogger ) { var responseJson = String.Empty; var authorizeMethodCall = false; var logMethodCall = false; var requiredRoles = String.Empty; // NOTES: Translate any exception to JsonRpcException try { try { if (_callableMethods[request.Method] != null) { // NOTES: request.Method is combined key not just the bare method name var mi = MethodInfo.GetMethodFromHandle(_callableMethods[request.Method]); // Collects the arguments var methodParams = new List<object>(); foreach (var pi in mi.GetParameters()) { if (pi.ParameterType.IsPrimitive || pi.ParameterType == typeof(String) || pi.ParameterType.IsValueType) { methodParams.Add(request.Params[pi.Position]); } else { var paramObj = JsonConvert.DeserializeObject(request.Params[pi.Position].ToString(), pi.ParameterType); methodParams.Add(paramObj); } } // No need to check attribute type that has been done during loading var attr = FetchOrCacheMethodAttribute(mi); logMethodCall = attr.LogCall; authorizeMethodCall = attr.Authorize; requiredRoles = attr.RequiredRoles; var td = _taskDescriptors[request.Method]; td.LastInvokedBy = requestHeader.User; td.LastInvoked = DateTime.UtcNow; // Authorize when demanded in attribute if (authorizeMethodCall) methodAuthorizer(requiredRoles); var ret = mi.Invoke(_handler, methodParams.ToArray()); // Log invocation when demanded in attribute if (logMethodCall) methodLogger(); responseJson = JsonRpcResponse.CreateJsonResponse(request.Id, ret); } else { throw new MethodNotFoundException(String.Format("Method: {0} not found", request.Method)); } } catch (ArgumentException ex) { throw new InvalidParametersException(ex.Message); } catch (Exception ex) { if (ex.InnerException != null) throw new ServerErrorException(ex.InnerException.Message); throw new ServerErrorException(ex.Message); } } catch (JsonRpcException ex) { if (logMethodCall && methodLogger != null) { methodLogger(); } responseJson = WrapException(request.Id, ex.Code, ex.Message, ex); } return responseJson; }