/// <summary> /// Handles generating a response to a request sent to a request-response controller action on the server /// </summary> public async Task <ActionResult> HandleRequestAsync(ActionRequest request) { var action = serviceMap.GetActionDefintion(request.Controller, request.Action); if (action == null) { return(new ActionResult { StatusCode = StatusCode.ActionNotFound, Message = $"Could not find service {request.Controller}/{request.Action}" }); } var controllerInstance = serviceProvider.GetService(action.ControllerType) as ServiceController; var actionResult = await action.InvokeFunction(controllerInstance, request); if (action.Compress) { actionResult.Contents = LZ4Codec.Wrap(actionResult.Contents); actionResult.IsCompressed = true; } return(actionResult); }
/// <summary> /// Deserializes the service action parameter into the expected type and /// dynamically invokes the action method on the passed in controller instance /// and returns the result of the action. /// </summary> /// <param name="controller">The controller instance to invoke the action on</param> /// <param name="parameter">The serialized bytes of the parameter to the controller action to invoke</param> /// <returns>Returns an async task to await the untyped result of the controller action that was invoked. /// This is expected to be a generic variant of ServiceResponse where the generic /// parameter is serializable by protobuf.</returns> public async Task <ActionResult> InvokeFunction(ServiceController controller, ActionRequest request) { byte[] parameter = request.Contents; if (HasParameter) { object parameterInstance; try { using (var mem = new MemoryStream(parameter)) { if (request.IsCompressed) { using (var lz4stream = new LZ4Stream(mem, LZ4StreamMode.Decompress)) { parameterInstance = Serializer.Deserialize(ParameterType, lz4stream); } } else { parameterInstance = Serializer.Deserialize(ParameterType, mem); } } } catch (ProtoException ex) { return(new ActionResult { Message = $"Could not understand the parameter {ParameterName} when deserializing - " + ex.ToString(), StatusCode = StatusCode.BadRequest }); } if (isAsync) { return(await(Task <ActionResult>) invoker(controller, parameterInstance)); } else { return((ActionResult)invoker(controller, parameterInstance)); } } if (isAsync) { return(await(Task <ActionResult>) invoker(controller, new object[] { })); } else { return((ActionResult)invoker(controller, new object[] { })); } }