private void HandleTimeSyncResponses(IBeaconSendingContext context, List <long> timeSyncOffsets) { // time sync requests were *not* successful // -OR- // time sync requests are not supported by the server (e.g. AppMon) // -> use 0 as cluster time offset if (timeSyncOffsets.Count < TIME_SYNC_REQUESTS) { HandleErroneousTimeSyncRequest(context); return; } // initialize time provider with cluster time offset context.InitializeTimeSync(ComputeClusterTimeOffset(timeSyncOffsets), true); // update the last sync time context.LastTimeSyncTime = context.CurrentTimestamp; // perform transition to next state SetNextState(context); }
protected override void DoExecute(IBeaconSendingContext context) { if (!IsTimeSyncRequired(context)) { // make state transition based on configuration - since time sync does not need to be supported or might not be required SetNextState(context); return; } // execute time sync requests - note during initial sync it might be possible // that the time sync capability is disabled. var timeSyncOffsets = ExecuteTimeSyncRequests(context); HandleTimeSyncResponses(context, timeSyncOffsets); // set init complete if initial time sync if (IsInitialTimeSync) { context.InitCompleted(true); } }
public void Setup() { currentTime = 1; lastTimeSyncTime = 1; openSessions = new List <Session>(); finishedSessions = new Queue <Session>(); // http client httpClient = Substitute.For <IHTTPClient>(); // provider timingProvider = Substitute.For <ITimingProvider>(); timingProvider.ProvideTimestampInMilliseconds().Returns(x => { return(++currentTime); }); // every access is a tick httpClientProvider = Substitute.For <IHTTPClientProvider>(); httpClientProvider.CreateClient(Arg.Any <HTTPClientConfiguration>()).Returns(x => httpClient); // context context = Substitute.For <IBeaconSendingContext>(); context.HTTPClientProvider.Returns(x => httpClientProvider); context.GetHTTPClient().Returns(x => httpClient); context.LastTimeSyncTime.Returns(x => currentTime); // always return the current time to prevent re-sync context.IsCaptureOn.Returns(true); // beacon sender beaconSender = new BeaconSender(config, httpClientProvider, timingProvider); // return true by default context.IsTimeSyncSupported.Returns(true); // current time getter context.CurrentTimestamp.Returns(x => timingProvider.ProvideTimestampInMilliseconds()); // last time sycn getter + setter context.LastTimeSyncTime = Arg.Do <long>(x => lastTimeSyncTime = x); context.LastTimeSyncTime = lastTimeSyncTime; // sessions context.GetAllOpenSessions().Returns(openSessions); context.GetNextFinishedSession().Returns(x => (finishedSessions.Count == 0) ? null : finishedSessions.Dequeue()); }
/// <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 StatusResponse SendNewSessionRequests(IBeaconSendingContext context) { StatusResponse statusResponse = null; var newSessions = context.NewSessions; foreach (var newSession in newSessions) { if (!newSession.CanSendNewSessionRequest) { // already exceeded the maximum number of session requests, disable any further data collecting var currentConfiguration = newSession.BeaconConfiguration; var newConfiguration = new BeaconConfiguration(0, currentConfiguration.DataCollectionLevel, currentConfiguration.CrashReportingLevel); newSession.UpdateBeaconConfiguration(newConfiguration); continue; } statusResponse = context.GetHTTPClient().SendNewSessionRequest(); if (BeaconSendingResponseUtil.IsSuccessfulResponse(statusResponse)) { var currentConfiguration = newSession.BeaconConfiguration; var newConfiguration = new BeaconConfiguration(statusResponse.Multiplicity, currentConfiguration.DataCollectionLevel, currentConfiguration.CrashReportingLevel); newSession.UpdateBeaconConfiguration(newConfiguration); } else if (BeaconSendingResponseUtil.IsTooManyRequestsResponse(statusResponse)) { // server is currently overloaded, return immediately break; } else { // any other unsuccessful response newSession.DecreaseNumNewSessionRequests(); } } return(statusResponse); }
internal static StatusResponse SendStatusRequest(IBeaconSendingContext context, int numRetries, int initialRetryDelayInMillis) { StatusResponse statusResponse = null; var sleepTimeInMillis = initialRetryDelayInMillis; var retry = 0; while (true) { statusResponse = context.GetHTTPClient().SendStatusRequest(); if (statusResponse != null || retry >= numRetries || context.IsShutdownRequested) { break; } // if no (valid) status response was received -> sleep and double the delay for each retry context.Sleep(sleepTimeInMillis); sleepTimeInMillis *= 2; retry++; } return(statusResponse); }
/// <summary> /// Execute the current state /// /// In case shutdown was requested, a state transition is performed by this method to the <code>ShutdownState</code> /// </summary> /// <param name="context"></param> public void Execute(IBeaconSendingContext context) { #if !NETCOREAPP1_0 try { #endif DoExecute(context); #if !NETCOREAPP1_0 } catch (System.Threading.ThreadInterruptedException) { // call on interruped OnInterrupted(context); // request shutdown context.RequestShutdown(); } #endif if (context.IsShutdownRequested) { context.CurrentState = ShutdownState; } }
public void Setup() { currentTime = 0; lastStatusCheckTime = -1; logger = Substitute.For <ILogger>(); httpClient = Substitute.For <IHTTPClient>(); context = Substitute.For <IBeaconSendingContext>(); context.GetHTTPClient().Returns(httpClient); // default return success httpClient.SendStatusRequest().Returns(new StatusResponse(logger, string.Empty, 200, new Dictionary <string, List <string> >())); // return true by default context.IsTimeSyncSupported.Returns(true); // current time getter context.CurrentTimestamp.Returns(x => { return(++currentTime); }); // last time sycn getter + setter context.LastStatusCheckTime = Arg.Do <long>(x => lastStatusCheckTime = x); context.LastStatusCheckTime = lastStatusCheckTime; // init with -1 }
protected override void DoExecute(IBeaconSendingContext context) { // end open sessions -> will be flushed afterwards var openSessions = context.GetAllOpenSessions(); foreach (var openSession in openSessions) { openSession.End(); } // flush finished (and previously ended) sessions var finishedSession = context.GetNextFinishedSession(); while (finishedSession != null) { finishedSession.SendBeacon(context.HTTPClientProvider); finishedSession.ClearCapturedData(); finishedSession = context.GetNextFinishedSession(); } // make last state transition to terminal state context.CurrentState = new BeaconSendingTerminalState(); }
protected override void DoExecute(IBeaconSendingContext context) { context.DisableCapture(); var currentTime = context.CurrentTimestamp; var delta = (int)(STATUS_CHECK_INTERVAL - (currentTime - context.LastStatusCheckTime)); if (delta > 0 && !context.IsShutdownRequested) { // still have some time to sleep context.Sleep(delta); } // send the status request var statusResponse = BeaconSendingRequestUtil.SendStatusRequest(context, STATUS_REQUEST_RETRIES, INITIAL_RETRY_SLEEP_TIME_MILLISECONDS); // process the response HandleStatusResponse(context, statusResponse); // update the last status check time in any case context.LastStatusCheckTime = currentTime; }
public void Setup() { currentTime = 0; lastTimeSyncTime = -1; httpClient = Substitute.For <IHTTPClient>(); context = Substitute.For <IBeaconSendingContext>(); context.GetHTTPClient().Returns(httpClient); // return true by default context.IsTimeSyncSupported.Returns(true); // current time getter context.CurrentTimestamp.Returns(x => { return(++currentTime); }); // last time sycn getter + setter context.LastTimeSyncTime = Arg.Do <long>(x => lastTimeSyncTime = x); context.LastTimeSyncTime = lastTimeSyncTime; // init with -1 // by default return erroneous responses httpClient.SendTimeSyncRequest() .Returns(new TimeSyncResponse(Substitute.For <ILogger>(), string.Empty, Response.HttpBadRequest, new Dictionary <string, List <string> >())); }
public void Setup() { httpClient = Substitute.For <IHTTPClient>(); finishedSessions = new Queue <Session>(); openSessions = new List <Session>(); // provider timingProvider = Substitute.For <ITimingProvider>(); httpClientProvider = Substitute.For <IHTTPClientProvider>(); httpClientProvider.CreateClient(Arg.Any <HTTPClientConfiguration>()).Returns(x => httpClient); // context context = Substitute.For <IBeaconSendingContext>(); context.GetHTTPClient().Returns(httpClient); context.HTTPClientProvider.Returns(httpClientProvider); // beacon sender beaconSender = new BeaconSender(context); // sessions context.GetAllOpenSessions().Returns(openSessions); context.GetNextFinishedSession().Returns(x => (finishedSessions.Count == 0) ? null : finishedSessions.Dequeue()); }
protected override void DoExecute(IBeaconSendingContext context) { // every two hours a time sync shall be performed if (BeaconSendingTimeSyncState.IsTimeSyncRequired(context)) { // transition to time sync state. if cature on is still true after time sync we will end up in the CaputerOnState again context.CurrentState = new BeaconSendingTimeSyncState(); return; } context.Sleep(); statusResponse = null; // send all finished sessions SendFinishedSessions(context); // check if we need to send open sessions & do it if necessary SendOpenSessions(context); // check if send interval spent -> send current beacon(s) of open Sessions HandleStatusResponse(context, statusResponse); }
protected override void DoExecute(IBeaconSendingContext context) { // first get all sessions that do not have any multiplicity explicitely set context.NewSessions.ForEach(newSession => { var currentConfiguration = newSession.BeaconConfiguration; newSession.UpdateBeaconConfiguration( new BeaconConfiguration(1, currentConfiguration.DataCollectionLevel, currentConfiguration.CrashReportingLevel)); }); // end all open sessions -> will be flushed afterwards context.OpenAndConfiguredSessions.ForEach(openSession => { openSession.End(); }); // flush already finished (and previously ended) sessions var tooManyRequestsReceived = false; context.FinishedAndConfiguredSessions.ForEach(finishedSession => { if (!tooManyRequestsReceived && finishedSession.IsDataSendingAllowed) { var statusResponse = finishedSession.SendBeacon(context.HTTPClientProvider); if (BeaconSendingResponseUtil.IsTooManyRequestsResponse(statusResponse)) { tooManyRequestsReceived = true; } } finishedSession.ClearCapturedData(); context.RemoveSession(finishedSession); }); // make last state transition to terminal state context.NextState = new BeaconSendingTerminalState(); }
public void Setup() { var mockResponse = Substitute.For <IStatusResponse>(); mockResponse.ResponseCode.Returns(StatusResponse.HttpOk); mockResponse.IsErroneousResponse.Returns(false); mockSession1Open = Substitute.For <ISessionInternals>(); mockSession1Open.IsDataSendingAllowed.Returns(true); mockSession1Open.SendBeacon(Arg.Any <IHttpClientProvider>(), Arg.Any <IAdditionalQueryParameters>()) .Returns(mockResponse); mockSession2Open = Substitute.For <ISessionInternals>(); mockSession2Open.IsDataSendingAllowed.Returns(true); mockSession2Open.SendBeacon(Arg.Any <IHttpClientProvider>(), Arg.Any <IAdditionalQueryParameters>()) .Returns(mockResponse); mockSession3Closed = Substitute.For <ISessionInternals>(); mockSession3Closed.IsDataSendingAllowed.Returns(true); mockSession3Closed.SendBeacon(Arg.Any <IHttpClientProvider>(), Arg.Any <IAdditionalQueryParameters>()) .Returns(mockResponse); var mockHttpClient = Substitute.For <IHttpClient>(); mockContext = Substitute.For <IBeaconSendingContext>(); mockContext.GetHttpClient().Returns(mockHttpClient); mockContext.GetAllNotConfiguredSessions().Returns(new List <ISessionInternals>()); mockContext.GetAllOpenAndConfiguredSessions().Returns(new List <ISessionInternals> { mockSession1Open, mockSession2Open }); mockContext.GetAllFinishedAndConfiguredSessions().Returns(new List <ISessionInternals> { mockSession3Closed, mockSession2Open, mockSession1Open }); }
protected override void DoExecute(IBeaconSendingContext context) { context.RequestShutdown(); }
/// <summary> /// Performs cleanup on interrupt if necessary /// </summary> internal virtual void OnInterrupted(IBeaconSendingContext context) { // default -> do nothing }
/// <summary> /// Executes the current state /// </summary> /// <param name="context">The state's context</param> protected abstract void DoExecute(IBeaconSendingContext context);
public void Setup() { httpClient = Substitute.For <IHTTPClient>(); context = Substitute.For <IBeaconSendingContext>(); context.GetHTTPClient().Returns(httpClient); }
public void Setup() { httpClient = Substitute.For <IHTTPClient>(); context = Substitute.For <IBeaconSendingContext>(); }
internal BeaconSender(IBeaconSendingContext context) { this.context = context; }
public void SetUp() { context = Substitute.For <IBeaconSendingContext>(); }
internal override void OnInterrupted(IBeaconSendingContext context) { context.InitCompleted(false); }
public void Setup() { mockContext = Substitute.For <IBeaconSendingContext>(); }
internal BeaconSender(ILogger logger, IBeaconSendingContext context) { this.logger = logger; this.context = context; }