/// <summary> /// End extend (async). /// </summary> /// <param name="asyncResult">async result</param> /// <returns>extended calendar hash chain</returns> public CalendarHashChain EndExtend(IAsyncResult asyncResult) { HAAsyncResult ar = GetHAAsyncResult(asyncResult); HAExtendRequestRunner runner = GetRequestRunner <HAExtendRequestRunner>(ar); return(runner.EndExtend(ar)); }
/// <summary> /// Ends HA request and returns the first successful sub-service response. /// </summary> /// <typeparam name="T">Type of response to be returned</typeparam> /// <param name="haAsyncResult">HA async result</param> /// <returns></returns> protected T EndRequest <T>(HAAsyncResult haAsyncResult) where T : class { if (_subServiceFirstResultsWaitHandle != null) { // notify that end request is called _endCallWaitHandle?.Set(); // wait for first successful sub-service result if (!_subServiceFirstResultsWaitHandle.WaitOne(_requestTimeout)) { throw new HAKsiServiceException("HA service request timed out."); } } object[] results = EndRequestMulti(haAsyncResult); if (results.Length == 0) { throw new HAKsiServiceException("All sub-requests failed.", SubServiceErrors); } foreach (object obj in results) { T result = obj as T; if (result != null) { return(result); } } throw new HAKsiServiceException("Could not get request response of type " + typeof(T) + Environment.NewLine + "Available responses: " + Environment.NewLine + ResultTlvsToString(results)); }
/// <summary> /// End create signature (async) /// </summary> /// <param name="asyncResult">async result</param> /// <returns>KSI signature</returns> public IKsiSignature EndSign(IAsyncResult asyncResult) { HAAsyncResult ar = GetHAAsyncResult(asyncResult); HASignRequestRunner runner = GetRequestRunner <HASignRequestRunner>(ar); return(runner.EndSign(ar)); }
/// <summary> /// Get sign request response payload (async). /// </summary> /// <param name="asyncResult">async result</param> /// <returns>Request response payload</returns> public SignRequestResponsePayload GetSignResponsePayload(IAsyncResult asyncResult) { HAAsyncResult ar = GetHAAsyncResult(asyncResult); HASignRequestRunner requestRunner = GetRequestRunner <HASignRequestRunner>(ar); return(requestRunner.GetSignResponsePayload(ar)); }
private static T GetRequestRunner <T>(HAAsyncResult haAsyncResult) where T : class { T runner = haAsyncResult.RequestRunner as T; if (runner == null) { throw new HAKsiServiceException(string.Format("Invalid async result. Containing invalid request runner of type {0}; Expected type: {1}", haAsyncResult.RequestRunner.GetType(), typeof(T))); } return(runner); }
private void RunSubService(HAAsyncResult haAsyncResult, int serviceIndex) { IKsiService service = GetService(serviceIndex); try { IAsyncResult asyncResult = SubServiceBeginRequest(service); if (!asyncResult.AsyncWaitHandle.WaitOne(_requestTimeout)) { throw new HAKsiServiceException("Sub-service request timed out."); } if (_endCallWaitHandle != null) { // We need to wait HA service end call (eg. EndSign) // Mark HA async request as complete haAsyncResult.SetComplete(); // Wait for HA service end call. if (!_endCallWaitHandle.WaitOne(_requestTimeout)) { throw new HAKsiServiceException("Wait end call timed out."); } } object subServiceEndRequest = SubServiceEndRequest(service, asyncResult); lock (_resultTlvLock) { _resultTlvs.Add(subServiceEndRequest); } _subServiceFirstResultsWaitHandle?.Set(); if (haAsyncResult.IsCompleted) { return; } if (!_returnAllResponses) { haAsyncResult.SetComplete(); return; } } catch (Exception ex) { HandleException(ex, service); } CheckComplete(haAsyncResult); }
/// <summary> /// Ends HA request and returns responses of all successful sub-service requests. /// </summary> /// <param name="haAsyncResult">HA async result</param> /// <returns></returns> public object[] EndRequestMulti(HAAsyncResult haAsyncResult) { if (!haAsyncResult.IsCompleted) { if (!haAsyncResult.AsyncWaitHandle.WaitOne(_requestTimeout)) { throw new HAKsiServiceException("HA service request timed out."); } } lock (_resultTlvLock) { return(_resultTlvs.ToArray()); } }
private static HAAsyncResult GetHAAsyncResult(IAsyncResult asyncResult) { if (asyncResult == null) { throw new ArgumentNullException(nameof(asyncResult)); } HAAsyncResult ar = asyncResult as HAAsyncResult; if (ar == null) { throw new HAKsiServiceException("Invalid " + nameof(asyncResult) + ", could not cast to correct object."); } return(ar); }
private void CheckComplete(HAAsyncResult haAsyncResult) { if (_returnAllResponses) { if (ResultTlvCount + SubServiceErrors.Count == _subServices.Count) { haAsyncResult.SetComplete(); _subServiceFirstResultsWaitHandle?.Set(); } } else { if (SubServiceErrors.Count >= _subServices.Count) { haAsyncResult.SetComplete(); _subServiceFirstResultsWaitHandle?.Set(); } } }
/// <summary> /// Ends HA aggregator configuration request and returns consolidated successful sub-service configurations. /// </summary> /// <param name="asyncResult"></param> /// <returns></returns> public AggregatorConfig EndGetAggregatorConfig(HAAsyncResult asyncResult) { object[] list = EndRequestMulti(asyncResult); AggregatorConfig config = null; foreach (object obj in list) { AggregatorConfig conf = obj as AggregatorConfig; if (conf == null) { throw new HAKsiServiceException(string.Format("Invalid request result object. Expected type: AggregatorConfig; Received type: {0}", obj?.GetType().ToString() ?? "")); } config = MergeConfigs(config, conf); } return(config); }
/// <summary> /// End get additional extender configuration data (async) /// </summary> /// <param name="asyncResult"></param> /// <returns>Extender configuration data</returns> public ExtenderConfig EndGetExtenderConfig(IAsyncResult asyncResult) { HAAsyncResult haAsyncResult = GetHAAsyncResult(asyncResult); HAExtenderConfigRequestRunner runner = GetRequestRunner <HAExtenderConfigRequestRunner>(haAsyncResult); ExtenderConfig config = runner.EndGetExtenderConfig(haAsyncResult); if (config == null) { lock (_extenderConfigChangedLock) { _currentExtenderConfigList.Clear(); _currentExtenderConfig = null; } HAKsiServiceException ex = new HAKsiServiceException("Could not get extender configuration.", runner.SubServiceErrors); Logger.Warn(ex); ExtenderConfigChangedEventArgs extenderConfigChangedEventArgs = new ExtenderConfigChangedEventArgs(ex, this); ExtenderConfigChanged?.Invoke(this, extenderConfigChangedEventArgs); throw ex; } // if sub-service config request failed then remove corresponding config from cache foreach (HAKsiSubServiceException ex in runner.SubServiceErrors) { if (ex.ThrownBySubService == null) { continue; } lock (_extenderConfigChangedLock) { if (_currentExtenderConfigList.ContainsKey(ex.ThrownBySubService)) { _currentExtenderConfigList.Remove(ex.ThrownBySubService); RecalculateExtenderConfig(); } } } return(config); }
/// <summary> /// Begin HA request. /// </summary> /// <param name="callback">callback when HA request is finished</param> /// <param name="asyncState">callback async state object</param> /// <param name="waitEndCall">If true then HA end request call (eg. EndSign) is waited before sub-service end request call can be made.</param> /// <returns></returns> public virtual HAAsyncResult BeginRequest(AsyncCallback callback, object asyncState, bool waitEndCall = false) { if (_subServices.Count == 0) { throw new HAKsiServiceException("Sub-services are missing."); } HAAsyncResult haAsyncResult = new HAAsyncResult(callback, asyncState, this); if (waitEndCall) { _endCallWaitHandle = new ManualResetEvent(false); _subServiceFirstResultsWaitHandle = new ManualResetEvent(false); } for (int index = 0; index < _subServices.Count; index++) { _runSubServiceDelegate.BeginInvoke(haAsyncResult, index, EndRunSubService, null); } CheckComplete(haAsyncResult); return(haAsyncResult); }
/// <summary> /// Ends HA extending request and returns the first successful sub-service extending response. /// </summary> /// <param name="haAsyncResult">HA async result</param> public CalendarHashChain EndExtend(HAAsyncResult haAsyncResult) { return(EndRequest <CalendarHashChain>(haAsyncResult)); }
/// <summary> /// Ends HA signing request and returns the first successful sub-service signing response. /// </summary> /// <param name="haAsyncResult">HA async result</param> public SignRequestResponsePayload GetSignResponsePayload(HAAsyncResult haAsyncResult) { _returnResponsePayload = true; return(EndRequest <SignRequestResponsePayload>(haAsyncResult)); }
/// <summary> /// Ends HA signing request and returns the first successful sub-service signing response. /// </summary> /// <param name="haAsyncResult">HA async result</param> public IKsiSignature EndSign(HAAsyncResult haAsyncResult) { return(EndRequest <KsiSignature>(haAsyncResult)); }