/// <summary> /// Send all sessions which have been finished previously. /// </summary> /// <param name="context">The state's context</param> /// <returns>The last status response received.</returns> private IStatusResponse SendFinishedSessions(IBeaconSendingContext context) { IStatusResponse statusResponse = null; // check if there's finished Sessions to be sent -> immediately send beacon(s) of finished Sessions var finishedSessions = context.GetAllFinishedAndConfiguredSessions(); foreach (var session in finishedSessions) { if (session.IsDataSendingAllowed) { statusResponse = session.SendBeacon(context.HttpClientProvider, context); if (!BeaconSendingResponseUtil.IsSuccessfulResponse(statusResponse)) { // something went wrong, if (BeaconSendingResponseUtil.IsTooManyRequestsResponse(statusResponse) || !session.IsEmpty) { break; // sending did not work, break out for now and retry it later } } } // session was sent - so remove it from beacon cache context.RemoveSession(session); session.ClearCapturedData(); } return(statusResponse); }
/// <summary> /// Send new session requests for all sessions where we currently don't have a multiplicity configuration. /// </summary> /// <param name="context">The state context.</param> /// <returns>The last status response received.</returns> private IStatusResponse SendNewSessionRequests(IBeaconSendingContext context) { IStatusResponse statusResponse = null; var notConfiguredSessions = context.GetAllNotConfiguredSessions(); foreach (var session in notConfiguredSessions) { if (!session.CanSendNewSessionRequest) { // already exceeded the maximum number of session requests, disable any further data collecting session.DisableCapture(); continue; } statusResponse = context.GetHttpClient().SendNewSessionRequest(context); if (BeaconSendingResponseUtil.IsSuccessfulResponse(statusResponse)) { var updatedAttributes = context.UpdateFrom(statusResponse); var newConfiguration = ServerConfiguration.From(updatedAttributes); session.UpdateServerConfiguration(newConfiguration); } else if (BeaconSendingResponseUtil.IsTooManyRequestsResponse(statusResponse)) { // server is currently overloaded, return immediately break; } else { // any other unsuccessful response session.DecreaseNumRemainingSessionRequests(); } } return(statusResponse); }
/// <summary> /// Check if the send interval (configured by server) has expired and start to send open sessions if it has expired. /// </summary> /// <param name="context">The state's context</param> /// <returns>The last status response received.</returns> private IStatusResponse SendOpenSessions(IBeaconSendingContext context) { IStatusResponse statusResponse = null; var currentTimestamp = context.CurrentTimestamp; if (currentTimestamp <= context.LastOpenSessionBeaconSendTime + context.SendInterval) { return(null); // some time left until open sessions need to be sent } var openSessions = context.GetAllOpenAndConfiguredSessions(); foreach (var session in openSessions) { if (session.IsDataSendingAllowed) { statusResponse = session.SendBeacon(context.HttpClientProvider, context); if (BeaconSendingResponseUtil.IsTooManyRequestsResponse(statusResponse)) { // server is currently overloaded, return immediately break; } } else { session.ClearCapturedData(); } } // update open session send timestamp context.LastOpenSessionBeaconSendTime = currentTimestamp; return(statusResponse); }
private static void SetStatusResponse(IStatusResponse statusResponse, int statusCode, StatusMessage statusMsg, List <StatusDetail> statusDetails = null) { statusResponse.StatusCode = statusCode; statusResponse.StatusDesc = statusMsg.GetValue(); statusResponse.StatusDetails = statusDetails; }
public TriviaAdapter ( ITriviaFacade triviaFacade, IPlayerFacade playerFacade, IStatusResponse statusResp, IMapper mapper ) : base(triviaFacade, statusResp) { _playerFacade = playerFacade; _mapper = mapper; }
public void Setup() { mockResponse = Substitute.For <IStatusResponse>(); mockResponse.ResponseCode.Returns(StatusResponse.HttpOk); mockResponse.IsErroneousResponse.Returns(false); mockHttpClient = Substitute.For <IHttpClient>(); mockHttpClient.SendStatusRequest(Arg.Any <IAdditionalQueryParameters>()).Returns(mockResponse); mockContext = Substitute.For <IBeaconSendingContext>(); mockContext.GetHttpClient().Returns(mockHttpClient); }
private static void HandleStatusResponse(IBeaconSendingContext context, IStatusResponse statusResponse) { if (statusResponse == null) { return; // nothing to handle } context.HandleStatusResponse(statusResponse); if (!context.IsCaptureOn) { // capturing is turned off -> make state transition context.NextState = new BeaconSendingCaptureOffState(); } }
protected virtual IActionResult GenerateResponse(IStatusResponse response, bool isCreated = false) { if (response.IsSuccess) { if (isCreated) { return(CreatedAtAction("Get", new { id = response.EntityId })); } else { return(Ok(response.EntityId)); } } else { return(GenerateProblemResult(response.StatusCode, response.ErrorMessage)); } }
private static void HandleStatusResponse(IBeaconSendingContext context, IStatusResponse statusResponse) { if (statusResponse != null) { // handle status response, even if it's erroneous // if it's an erroneous response capturing is disabled context.HandleStatusResponse(statusResponse); } if (BeaconSendingResponseUtil.IsTooManyRequestsResponse(statusResponse)) { // received "too many requests" response // in this case stay in capture off state and use the retry-after delay for sleeping context.NextState = new BeaconSendingCaptureOffState(statusResponse.GetRetryAfterInMilliseconds()); } else if (BeaconSendingResponseUtil.IsSuccessfulResponse(statusResponse) && context.IsCaptureOn) { // capturing is re-enabled again, but only if we received a response from the server context.NextState = new BeaconSendingCaptureOnState(); } }
public async Task InvokeAsync(HttpContext context, IStatusResponse statusResponse) { //Set IStatusResponse on response headers at end of request session context.Response.OnStarting(state => { string statusRespStr = JsonSerializer.Serialize(statusResponse); context.Response.Headers.Add(SRR.HeaderKey, statusRespStr); return(Task.CompletedTask); }, context); try { await _next(context); } catch (Exception ex) { //Typically would log whatever exception was thrown to a permanent place //Low-key just didn't want to impl a Logger NuGet .csproj that worked with a Logger.json file List <StatusDetail> details = new List <StatusDetail>() { new StatusDetail() { Code = Status.Status900.UnknownCode.ToInt32(), Desc = Status.StatusMessage.UnknownCode.GetValue() }, new StatusDetail() { Code = Status.Status900.UnknownCode.ToInt32(), Desc = ex.Message } }; statusResponse.SetStatusResponse(Status.Status500.FatalError, Status.StatusMessage.FatalError, details); context.Response.StatusCode = (int)HttpStatusCode.NoContent; context.Response.ContentLength = 0; context.Response.Body = Stream.Null; } }
protected BaseAdapter(TFacade facade, IStatusResponse statusResp) { Facade = facade; StatusResp = statusResp; }
/// <summary> /// Test if the given <paramref name="response"/> is a "too many requests" response. /// </summary> /// <remarks> /// A "too many requests" response is an HTTP response with response code 429. /// </remarks> /// <param name="response">The given response to check whether it is a "too many requests" response or not.</param> /// <returns><code>true</code> if response indicates too many requests, <code>false</code> otherwise.</returns> internal static bool IsTooManyRequestsResponse(IStatusResponse response) { return(response != null && response.ResponseCode == StatusResponse.HttpTooManyRequests); }
/// <summary> /// Test if given <paramref name="response"/> is a successful response. /// </summary> /// <param name="response">The given response to check whether it is successful or not.</param> /// <returns><code>true</code> if response is successful, <code>false</code> otherwise.</returns> internal static bool IsSuccessfulResponse(IStatusResponse response) { return(response != null && !response.IsErroneousResponse); }
public PlayerAdapter(IPlayerFacade facade, IStatusResponse statusResp) : base(facade, statusResp) { }
public async Task InvokeAsync(HttpContext context, IStatusResponse statusResp) { List <StatusDetail> statusDetails; //Get Token from header if (!context.Request.Headers.TryGetValue(TokenMan.RequestHeaderKey, out StringValues headerVal)) { FailForMissingToken(); return; } string token = headerVal.FirstOrDefault(); if (string.IsNullOrWhiteSpace(token)) { FailForMissingToken(); return; } //---Validations--- //Signature validation bool isValid = TokenMan.ValidateTokenSignature(token); if (!isValid) { statusDetails = new List <StatusDetail>() { new StatusDetail() { Code = Status300.TandemTokenNotValid.ToInt32(), Desc = StatusMessage.TandemTokenNotValid.GetValue() } }; statusResp.SetStatusResponse(Status500.BadRequest, StatusMessage.BadRequest, statusDetails); return; } //Expired validation isValid = !TokenMan.TokenIsExpired(token); if (!isValid) { statusDetails = new List <StatusDetail>() { new StatusDetail() { Code = Status300.TandemTokenNotValid.ToInt32(), Desc = StatusMessage.TandemTokenNotValid.GetValue() } }; statusResp.SetStatusResponse(Status500.BadRequest, StatusMessage.BadRequest, statusDetails); return; } //Token valid, proceed await _next(context); //LOCAL HELPER FUNCTION void FailForMissingToken() { statusDetails = new List <StatusDetail>() { new StatusDetail() { Code = Status300.TandemTokenNotFound.ToInt32(), Desc = StatusMessage.TandemTokenNotFound.GetValue() } }; statusResp.SetStatusResponse(Status500.BadRequest, StatusMessage.BadRequest, statusDetails); } }
//Status900 override public static void SetStatusResponse(this IStatusResponse statusResponse, Status900 status, StatusMessage statusMsg, List <StatusDetail> statusDetails = null) => SetStatusResponse(statusResponse, status.ToInt32(), statusMsg, statusDetails);