示例#1
0
        /// <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);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
 private static void SetStatusResponse(IStatusResponse statusResponse,
                                       int statusCode, StatusMessage statusMsg, List <StatusDetail> statusDetails = null)
 {
     statusResponse.StatusCode    = statusCode;
     statusResponse.StatusDesc    = statusMsg.GetValue();
     statusResponse.StatusDetails = statusDetails;
 }
示例#5
0
 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);
        }
示例#7
0
        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();
            }
        }
示例#8
0
 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));
     }
 }
示例#9
0
 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();
     }
 }
示例#10
0
        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;
            }
        }
示例#11
0
 protected BaseAdapter(TFacade facade, IStatusResponse statusResp)
 {
     Facade     = facade;
     StatusResp = statusResp;
 }
示例#12
0
 /// <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);
 }
示例#13
0
 /// <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);
 }
示例#14
0
 public PlayerAdapter(IPlayerFacade facade, IStatusResponse statusResp) : base(facade, statusResp)
 {
 }
示例#15
0
        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);
            }
        }
示例#16
0
 //Status900 override
 public static void SetStatusResponse(this IStatusResponse statusResponse,
                                      Status900 status, StatusMessage statusMsg, List <StatusDetail> statusDetails = null) =>
 SetStatusResponse(statusResponse, status.ToInt32(), statusMsg, statusDetails);