/// <summary> /// Method called just before allowing externals to select a response. /// </summary> protected override void InternalPreSelectResponse(RecordedDataSourceSelectorEventArgs e) { if (!AllowMatchingByChannel) return; var request = ConvertToJSon(e); // do nothing: if (request == null || !request.IsEnumerable) return; var channel = RecordedBayeuxDataSourceResponse.GetChannel(request); if (string.IsNullOrEmpty(channel)) return; // select matching response by channel: foreach (var response in e.Responses) { var bayeuxResponse = response as RecordedBayeuxDataSourceResponse; if (bayeuxResponse != null) { if (string.Compare(channel, bayeuxResponse.Channel, StringComparison.OrdinalIgnoreCase) == 0) { e.SelectedResponse = bayeuxResponse; DebugLog.WriteBayeuxLine(string.Concat("Selected response for channel: '", channel, "'")); return; } } } }
private IJSonObject ConvertToJSon(RecordedDataSourceSelectorEventArgs e) { if (e == null) { return(null); } var existingJSon = e.RequestDataAsJSon as IJSonObject; if (existingJSon != null) { return(existingJSon); } var data = ConvertToJSon(e.RequestDataAsString); e.RequestDataAsJSon = data; return(data); }
/// <summary> /// Method called just before allowing externals to select a response. /// </summary> protected override void InternalPreSelectResponse(RecordedDataSourceSelectorEventArgs e) { if (!AllowMatchingByChannel) { return; } var request = ConvertToJSon(e); // do nothing: if (request == null || !request.IsEnumerable) { return; } var channel = RecordedBayeuxDataSourceResponse.GetChannel(request); if (string.IsNullOrEmpty(channel)) { return; } // select matching response by channel: foreach (var response in e.Responses) { var bayeuxResponse = response as RecordedBayeuxDataSourceResponse; if (bayeuxResponse != null) { if (string.Compare(channel, bayeuxResponse.Channel, StringComparison.OrdinalIgnoreCase) == 0) { e.SelectedResponse = bayeuxResponse; DebugLog.WriteBayeuxLine(string.Concat("Selected response for channel: '", channel, "'")); return; } } } }
/// <summary> /// Method called just after selection of response performed, but before taking any other action. /// It might be used to: /// 1) update the data-source based on request data /// 2) update the response with request specific data /// 3) replace the whole response object /// 4) send some other extra notifications, when subclassed /// </summary> protected override void InternalPreProcessResponse(RecordedDataSourceSelectorEventArgs e) { // find fields inside the request: string id = ReadSharedFieldsAndID(ConvertToJSon(e)); // update token value, if allowed: if (!AllowUpdateTokenOnRequest) { UpdateTokenValue(); } // update response fields, depending if it is a single or array response: var response = e.SelectedResponse as RecordedBayeuxDataSourceResponse; if (response != null) { if (response.AsJSon != null) { UpdateSharedFields(e.RequestDataAsJSon as IJSonObject, response.AsJSon, id); } else { IJSonObject responseJSon = null; try { var reader = new JSonReader(response.AsString); responseJSon = reader.ReadAsJSonObject(); } catch (Exception ex) { DebugLog.WriteBayeuxLine("Response AsString is not in JSON format!"); DebugLog.WriteBayeuxException(ex); } UpdateSharedFields(e.RequestDataAsJSon as IJSonObject, responseJSon, id); } } }
private IJSonObject ConvertToJSon(RecordedDataSourceSelectorEventArgs e) { if (e == null) return null; var existingJSon = e.RequestDataAsJSon as IJSonObject; if (existingJSon != null) return existingJSon; var data = ConvertToJSon(e.RequestDataAsString); e.RequestDataAsJSon = data; return data; }
/// <summary> /// Method called just after selection of response performed, but before taking any other action. /// It might be used to: /// 1) update the data-source based on request data /// 2) update the response with request specific data /// 3) replace the whole response object /// 4) send some other extra notifications, when subclassed /// </summary> protected override void InternalPreProcessResponse(RecordedDataSourceSelectorEventArgs e) { // find fields inside the request: string id = ReadSharedFieldsAndID(ConvertToJSon(e)); // update token value, if allowed: if (!AllowUpdateTokenOnRequest) UpdateTokenValue(); // update response fields, depending if it is a single or array response: var response = e.SelectedResponse as RecordedBayeuxDataSourceResponse; if (response != null) { if (response.AsJSon != null) { UpdateSharedFields(e.RequestDataAsJSon as IJSonObject, response.AsJSon, id); } else { IJSonObject responseJSon = null; try { var reader = new JSonReader(response.AsString); responseJSon = reader.ReadAsJSonObject(); } catch (Exception ex) { DebugLog.WriteBayeuxLine("Response AsString is not in JSON format!"); DebugLog.WriteBayeuxException(ex); } UpdateSharedFields(e.RequestDataAsJSon as IJSonObject, responseJSon, id); } } }
/// <summary> /// Method called just after selection of response performed, but before taking any other action. /// It might be used to: /// 1) update the data-source based on request data /// 2) update the response with request specific data /// 3) replace the whole response object /// 4) send some other extra notifications, when subclassed /// </summary> protected virtual void InternalPreProcessResponse(RecordedDataSourceSelectorEventArgs e) { }
private void ReceiveResponse(RecordedDataSourceSelectorEventArgs e) { if (e == null) throw new InvalidOperationException("Somehow lost required state argument!"); DebugLog.WriteCoreLine("~~~> Waiting for stubbed response" + (string.IsNullOrEmpty(_url) ? string.Empty : string.Concat(" (", _url, ")"))); InternalPreSelectResponse(e); // allow external code to select the next response, // if there is no handler, automatically next one from the list will be taken: Event.Invoke(SelectResponse, this, e); SelectedIndex = e.NextResponseIndex; var response = e.SelectedResponse; if (response == null) { DebugLog.WriteCoreLine("Missing response object!"); _isActive = false; _eventDispatcher.Invoke(DataReceiveFailed, this, new HttpDataSourceEventArgs(this, HttpStatusCode.NotFound, "Not found response object, the request was adressed for")); return; } if (VerifyIfCancelled()) return; // now wait time specified inside the response: if (response.Delay > 0) { if (response.Delay > Timeout) { Thread.Sleep(Timeout); if (VerifyIfCancelled()) return; _isActive = false; DebugLog.WriteCoreLine(string.Concat("--> Request timeouted (data-source timeout: ", Timeout, " ms, response delay: ", response.Delay, " ms)!")); _eventDispatcher.Invoke(DataReceiveFailed, this, new HttpDataSourceEventArgs(this, HttpStatusCode.RequestTimeout, "Request timeouted due to huge response delay")); return; } Thread.Sleep(response.Delay); if (VerifyIfCancelled()) return; _isActive = false; } InternalPreProcessResponse(e); DebugLog.WriteCoreLine(string.Format(CultureInfo.InvariantCulture, "---> Received response (length: {0} bytes, at: {1}, waiting: {2:F2} sec) with status: {3} ({4}, {5}, {6})", response.Length, DateTime.Now, (DateTime.Now - e.SentAt).TotalSeconds, response.StatusCode, (int) response.StatusCode, response.StatusDescription, response.ContentType)); string category = string.Concat(DebugLog.CategoryCore, ".HttpDataSource.Receive", string.IsNullOrEmpty(response.ContentType) ? string.Empty : ".", response.ContentType); if (response.Length == 0) DebugLog.WriteCoreLine(NothingContentDescription); else if (response.AsString != null) DebugLog.WriteLine(category, response.AsString); else DebugLog.WriteLine(category, BinaryContentDescription); switch (e.ResponseType) { case HttpDataSourceResponseType.AsString: _eventDispatcher.Invoke(response.IsFailure ? DataReceiveFailed : DataReceived, this, new HttpDataSourceEventArgs(this, response.StatusCode, response.StatusDescription, response.AsString, null, null)); return; case HttpDataSourceResponseType.AsBinary: _eventDispatcher.Invoke(response.IsFailure ? DataReceiveFailed : DataReceived, this, new HttpDataSourceEventArgs(this, response.StatusCode, response.StatusDescription, null, response.AsBinary, null)); return; case HttpDataSourceResponseType.AsRawStream: using (var stream = new MemoryStream(response.AsBinary ?? new byte[0])) { _eventDispatcher.Invoke(response.IsFailure ? DataReceiveFailed : DataReceived, this, new HttpDataSourceEventArgs(this, response.StatusCode, response.StatusDescription, null, null, stream)); } return; default: throw new NotImplementedException("Invalid response type requested"); } }
private void ReceiveResponse(RecordedDataSourceSelectorEventArgs e) { if (e == null) { throw new InvalidOperationException("Somehow lost required state argument!"); } DebugLog.WriteCoreLine("~~~> Waiting for stubbed response" + (string.IsNullOrEmpty(_url) ? string.Empty : string.Concat(" (", _url, ")"))); InternalPreSelectResponse(e); // allow external code to select the next response, // if there is no handler, automatically next one from the list will be taken: Event.Invoke(SelectResponse, this, e); SelectedIndex = e.NextResponseIndex; var response = e.SelectedResponse; if (response == null) { DebugLog.WriteCoreLine("Missing response object!"); _isActive = false; _eventDispatcher.Invoke(DataReceiveFailed, this, new HttpDataSourceEventArgs(this, HttpStatusCode.NotFound, "Not found response object, the request was adressed for")); return; } if (VerifyIfCancelled()) { return; } // now wait time specified inside the response: if (response.Delay > 0) { if (response.Delay > Timeout) { Thread.Sleep(Timeout); if (VerifyIfCancelled()) { return; } _isActive = false; DebugLog.WriteCoreLine(string.Concat("--> Request timeouted (data-source timeout: ", Timeout, " ms, response delay: ", response.Delay, " ms)!")); _eventDispatcher.Invoke(DataReceiveFailed, this, new HttpDataSourceEventArgs(this, HttpStatusCode.RequestTimeout, "Request timeouted due to huge response delay")); return; } Thread.Sleep(response.Delay); if (VerifyIfCancelled()) { return; } _isActive = false; } InternalPreProcessResponse(e); DebugLog.WriteCoreLine(string.Format(CultureInfo.InvariantCulture, "---> Received response (length: {0} bytes, at: {1}, waiting: {2:F2} sec) with status: {3} ({4}, {5}, {6})", response.Length, DateTime.Now, (DateTime.Now - e.SentAt).TotalSeconds, response.StatusCode, (int)response.StatusCode, response.StatusDescription, response.ContentType)); string category = string.Concat(DebugLog.CategoryCore, ".HttpDataSource.Receive", string.IsNullOrEmpty(response.ContentType) ? string.Empty : ".", response.ContentType); if (response.Length == 0) { DebugLog.WriteCoreLine(NothingContentDescription); } else if (response.AsString != null) { DebugLog.WriteLine(category, response.AsString); } else { DebugLog.WriteLine(category, BinaryContentDescription); } switch (e.ResponseType) { case HttpDataSourceResponseType.AsString: _eventDispatcher.Invoke(response.IsFailure ? DataReceiveFailed : DataReceived, this, new HttpDataSourceEventArgs(this, response.StatusCode, response.StatusDescription, response.AsString, null, null)); return; case HttpDataSourceResponseType.AsBinary: _eventDispatcher.Invoke(response.IsFailure ? DataReceiveFailed : DataReceived, this, new HttpDataSourceEventArgs(this, response.StatusCode, response.StatusDescription, null, response.AsBinary, null)); return; case HttpDataSourceResponseType.AsRawStream: using (var stream = new MemoryStream(response.AsBinary ?? new byte[0])) { _eventDispatcher.Invoke(response.IsFailure ? DataReceiveFailed : DataReceived, this, new HttpDataSourceEventArgs(this, response.StatusCode, response.StatusDescription, null, null, stream)); } return; default: throw new NotImplementedException("Invalid response type requested"); } }