/// <summary>
 /// The method executed server side
 /// </summary>
 /// <param name="request"></param>
 public virtual void ExecuteRemoteAsync(AsyncExecutionRequest request) // this should be executing server side after encryption has been handled
 {
     Task.Run(() =>
     {
         AsyncCallbackService asyncCallback = _proxyFactory.GetProxy <AsyncCallbackService>(request.RespondToHostName, request.RespondToPort);
         ExecutionRequest execRequest       = new ExecutionRequest(request.ClassName, request.MethodName, "json")
         {
             ServiceProvider = ServiceProvider,
             Context         = HttpContext,
             JsonParams      = request.JsonParams
         };
         bool success = execRequest.Execute();
         AsyncExecutionResponse response = new AsyncExecutionResponse
         {
             Success = success,
             Request = request,
             Result  = execRequest.Result
         };
         if (!success)
         {
             if (execRequest?.Result is ValidationResult validation && validation.Success == false)
             {
                 response.ValidationFailure = new ValidationFailure {
                     Message = validation.Message, Failures = validation.ValidationFailures
                 };
                 response.Result = null;
             }
         }
         asyncCallback.RecieveAsyncExecutionResponse(response);
     });
 }
 /// <summary>
 /// The method executed server side
 /// </summary>
 /// <param name="request"></param>
 public virtual void ExecuteRemoteAsync(AsyncExecutionRequest request) // this should be executing server side after encryption has been handled
 {
     Task.Run(() =>
     {
         AsyncCallbackService asyncCallback = _proxyFactory.GetProxy <AsyncCallbackService>(request.RespondToHostName, request.RespondToPort, Logger);
         // This executes server side after the SecureChannel has decrypted and validated, need to set IsInitialized to true to
         // ensure the request doesn't reinitialize to a state where it believes it is an execution request
         // targeting SecureChannel since that is what is in the HttpContext.Request.Url
         ExecutionRequest execRequest = new ExecutionRequest
         {
             ClassName       = request.ClassName,
             MethodName      = request.MethodName,
             Ext             = "json",
             ServiceProvider = ServiceProvider,
             JsonParams      = request.JsonParams,
             IsInitialized   = true,
             Context         = HttpContext
         };
         bool success = execRequest.Execute();
         AsyncExecutionResponse response = new AsyncExecutionResponse
         {
             Success = success,
             Request = request,
             Result  = execRequest.Result
         };
         asyncCallback.RecieveAsyncExecutionResponse(response);
     });
 }
 public void InvokeAsync(AsyncExecutionRequest request, Action <AsyncExecutionResponse> responseHandler = null)
 {
     responseHandler = responseHandler ?? DefaultResponseHandler;
     if (!request.UseCachedResponse)
     {
         CallExecuteRemoteAsync(request, responseHandler);
     }
     else
     {
         AsyncExecutionResponseData response = CallbackService.GetCachedResponse(request.GetRequestHash());
         if (response != null && new Instant(DateTime.UtcNow).DiffInMinutes(response.Created.Value) <= request.ResponseMaxAgeInMinutes)
         {
             AsyncExecutionResponse result = response.CopyAs <AsyncExecutionResponse>();
             result.Success    = true;
             result.Request    = request;
             result.ResultJson = response.ResultJson;
             responseHandler(result);
         }
         else
         {
             if (response != null)
             {
                 CallbackService.AsyncCallbackRepository.Delete(response);
             }
             CallExecuteRemoteAsync(request, responseHandler);
         }
     }
 }
 public void RegisterPendingAsyncExecutionRequest(AsyncExecutionRequest request, Action <AsyncExecutionResponse> handler)
 {
     Args.ThrowIfNull(request);
     Args.ThrowIfNullOrEmpty(request.Cuid);
     lock (_serverLock)
     {
         if (_server == null)
         {
             _server = this.Serve(HostPrefix, Logger);
         }
     }
     SaveExecutionRequestData(request);
     if (!_pendingRequests.TryAdd(request.Cuid, handler))
     {
         Logger.Warning("Failed to register pending request: {0}", request.PropertiesToString());
         FireEvent(AddPendingFailed, new AsyncExecutionRequestEventArgs {
             Request = request
         });
     }
 }
        private void SaveExecutionRequestData(AsyncExecutionRequest request)
        {
            string             requestHash   = request.GetRequestHash();
            AsyncExecutionData executionData = AsyncCallbackRepository.OneAsyncExecutionDataWhere(c => c.RequestHash == requestHash);

            if (executionData == null)
            {
                executionData = new AsyncExecutionData
                {
                    RequestCuid = request.Cuid,
                    RequestHash = requestHash,
                    Requested   = new Instant(DateTime.UtcNow)
                };
                AsyncCallbackRepository.Save(executionData);
            }
            else
            {
                Logger.Warning("AsyncExecutionData was already persisted: Request.Cuid={0}, RequestHash={1}", executionData.RequestCuid, requestHash);
            }
            SaveRequestData(request, requestHash);
        }
        private void SaveRequestData(AsyncExecutionRequest request, string requestHash)
        {
            AsyncExecutionRequestData requestData = AsyncCallbackRepository.OneAsyncExecutionRequestDataWhere(c => c.RequestHash == requestHash);

            if (requestData == null)
            {
                requestData = new AsyncExecutionRequestData
                {
                    Cuid        = request.Cuid,
                    RequestHash = requestHash,
                    ClassName   = request.ClassName,
                    MethodName  = request.MethodName,
                    JsonParams  = request.JsonParams
                };
                Expect.AreEqual(requestHash, requestData.GetRequestHash());
                AsyncCallbackRepository.Save(requestData);
            }
            else
            {
                Logger.Warning("AsyncExecutionRequestData was already persisted: RequestHash={0}", requestHash);
            }
        }
 private void CallExecuteRemoteAsync(AsyncExecutionRequest request, Action <AsyncExecutionResponse> responseHandler)
 {
     CallbackService.RegisterPendingAsyncExecutionRequest(request, responseHandler);
     ExecuteRemoteAsync(request);
 }