public IHttpActionResult Polling([FromUri] string terminalToken, [FromBody] PollingDataDTO pollingData) { Logger.Info($"Polling: requested for {pollingData.ExternalAccountId} from a terminal {terminalToken} and addition to jobId {pollingData.AdditionToJobId}"); pollingData.JobId = terminalToken + "|" + pollingData.ExternalAccountId + pollingData.AdditionToJobId; RecurringJob.AddOrUpdate(pollingData.JobId, () => SchedullerHelper.ExecuteSchedulledJob(pollingData, terminalToken), "*/" + pollingData.PollingIntervalInMinutes + " * * * *"); if (pollingData.TriggerImmediately) { RecurringJob.Trigger(pollingData.JobId); } return(Ok()); }
public async Task ScheduleEvent(string externalAccountId, string minutes, bool triggerImmediately = false, string additionalConfigAttributes = null, string additionToJobId = null) { var hubAlarmsUrl = GetHubUrlWithApiVersion() + $"/alarms/polling?terminalToken={TerminalToken}"; var uri = new Uri(hubAlarmsUrl); var data = new PollingDataDTO() { Fr8AccountId = _userId, ExternalAccountId = externalAccountId, PollingIntervalInMinutes = minutes, TriggerImmediately = triggerImmediately, AdditionalConfigAttributes = additionalConfigAttributes, AdditionToJobId = additionToJobId }; await _restfulServiceClient.PostAsync <PollingDataDTO>(uri, data); }
public async Task <PollingDataDTO> Poll(PollingDataDTO pollingData) { if (string.IsNullOrEmpty(pollingData.AdditionalConfigAttributes)) { pollingData.Result = false; return(pollingData); } var attributesObject = JObject.Parse(pollingData.AdditionalConfigAttributes); var groupId = attributesObject["GroupId"]?.ToString(); var statId = attributesObject["StatId"]?.ToString(); if (string.IsNullOrEmpty(groupId) || string.IsNullOrEmpty(statId)) { pollingData.Result = false; return(pollingData); } if (string.IsNullOrEmpty(pollingData.Payload)) { //polling is called for the first time var latestStatWithValues = await GetLatestStatItem(pollingData.AuthToken, groupId, statId); pollingData.Payload = JsonConvert.SerializeObject(latestStatWithValues); } else { var statXCM = JsonConvert.DeserializeObject <StatXItemCM>(pollingData.Payload); var latestStatWithValues = await GetLatestStatItem(pollingData.AuthToken, groupId, statId); //check value by value to see if a difference exist. if (StatXUtilities.CompareStatsForValueChanges(statXCM, latestStatWithValues)) { var eventReportContent = new EventReportCM { EventNames = "StatXValueChange_" + statId.Substring(0, 18), EventPayload = new CrateStorage(Crate.FromContent("StatXValueChange", latestStatWithValues)), Manufacturer = "StatX", ExternalAccountId = pollingData.ExternalAccountId }; pollingData.Payload = JsonConvert.SerializeObject(latestStatWithValues); await _hubReporter.Broadcast(Crate.FromContent("Standard Event Report", eventReportContent)); } } pollingData.Result = true; return(pollingData); }
public async Task <PollingDataDTO> ProcessPollingRequest([FromBody] PollingDataDTO pollingData) { GDrivePollingType gDrivePollingType; if (string.IsNullOrEmpty(pollingData.AdditionToJobId)) { return(await _gmailPolling.Poll(pollingData)); } else if (Enum.TryParse <GDrivePollingType>(pollingData.AdditionToJobId, out gDrivePollingType)) { return(await _gdrivePolling.Poll(pollingData, gDrivePollingType)); } else { throw new ApplicationException("Unable to process polling request: invalid polling object type"); } }
public async Task <PollingDataDTO> Poll(PollingDataDTO pollingData) { var config = _docuSignManager.SetUp(pollingData.AuthToken); EnvelopesApi api = new EnvelopesApi((Configuration)config.Configuration); List <DocuSignEnvelopeCM_v2> changed_envelopes = new List <DocuSignEnvelopeCM_v2>(); // 1. Poll changes var changed_envelopes_info = api.ListStatusChanges(config.AccountId, new EnvelopesApi.ListStatusChangesOptions() { fromDate = DateTime.UtcNow.AddMinutes(-Convert.ToInt32(pollingData.PollingIntervalInMinutes)).ToString("o") }); foreach (var envelope in changed_envelopes_info.Envelopes) { var envelopeCM = new DocuSignEnvelopeCM_v2() { EnvelopeId = envelope.EnvelopeId, Status = envelope.Status, StatusChangedDateTime = DateTime.Parse(envelope.StatusChangedDateTime), ExternalAccountId = JToken.Parse(pollingData.AuthToken)["Email"].ToString(), }; changed_envelopes.Add(envelopeCM); } // 2. Check if we processed these envelopes before and if so - retrieve them //TODO: add overlapping minute handling var recorded_crates = new List <DocuSignEnvelopeCM_v2>(); // var recorded_crates = await _hubCommunicator.GetStoredManifests(curFr8UserId, changed_envelopes); // 3. Fill polled envelopes with data changed_envelopes = FillChangedEnvelopesWithData(config, changed_envelopes); // 4. Exclude envelopes that came from a 1 minute overlap var envelopesToNotify = ExcludeCollisions(changed_envelopes, recorded_crates); // 5. Push envelopes to event controller await PushEnvelopesToTerminalEndpoint(envelopesToNotify); pollingData.Result = true; return(pollingData); }
private static async Task <bool> RenewAuthToken(PollingDataDTO pollingData, string terminalToken) { using (var uow = ObjectFactory.GetInstance <IUnitOfWork>()) { var terminalDO = await ObjectFactory.GetInstance <ITerminal>().GetByToken(terminalToken); if (terminalDO == null) { throw new Exception("No terminal was found with token: " + terminalToken); } var token = uow.AuthorizationTokenRepository.FindTokenByExternalAccount(pollingData.ExternalAccountId, terminalDO.Id, pollingData.Fr8AccountId); if (token != null) { pollingData.AuthToken = token.Token; return(true); } } return(false); }
private static async Task <PollingDataDTO> RequestPolling(PollingDataDTO pollingData, string terminalToken, IRestfulServiceClient _client) { try { var terminalService = ObjectFactory.GetInstance <ITerminal>(); using (var uow = ObjectFactory.GetInstance <IUnitOfWork>()) { var terminal = uow.TerminalRepository.GetQuery().FirstOrDefault(a => a.Secret == terminalToken); var url = terminal.Endpoint + "/terminals/" + terminal.Name + "/polling_notifications"; Logger.Info($"Polling: executing request for {pollingData?.ExternalAccountId} from {Server.ServerUrl} to a terminal {terminal?.Name} at {terminal?.Endpoint}"); using (var client = new HttpClient()) { foreach (var header in terminalService.GetRequestHeaders(terminal, pollingData?.Fr8AccountId)) { client.DefaultRequestHeaders.Add(header.Key, header.Value); } try { var response = await _client.PostAsync <PollingDataDTO, PollingDataDTO>(new Uri(url), pollingData); return(response); } catch (Exception exception) { Logger.Info($"Polling: problem with terminal polling request for {pollingData?.ExternalAccountId} from {Server.ServerUrl} to a terminal {terminal?.Name}. Exception: {exception.Message}"); return(null); } } } } catch (Exception exception) { Logger.Info($"Polling: problem with terminal polling request for {pollingData?.ExternalAccountId} from {Server.ServerUrl} to a terminal. Exception: {exception.Message}"); return(null); } }
public async Task <PollingDataDTO> Poll(PollingDataDTO pollingData, GDrivePollingType pollingType) { var googleAuthToken = JsonConvert.DeserializeObject <GoogleAuthDTO>(pollingData.AuthToken); var driveService = await _googleDrive.CreateDriveService(googleAuthToken); string startPageToken; if (string.IsNullOrEmpty(pollingData.Payload)) { var response = driveService.Changes.GetStartPageToken().Execute(); startPageToken = response.StartPageTokenValue; } else { startPageToken = pollingData.Payload; } var changedFiles = new Dictionary <string, string>(); var pageToken = startPageToken; while (pageToken != null) { var request = driveService.Changes.List(pageToken); request.Fields = "changes,kind,newStartPageToken,nextPageToken"; request.Spaces = "drive"; var changes = request.Execute(); foreach (var change in changes.Changes) { if (!string.IsNullOrEmpty(change.File.MimeType) && change.File.MimeType.ToUpper() == _fileTypes[pollingType]) { if (!changedFiles.ContainsKey(change.FileId)) { changedFiles.Add(change.FileId, change.File.Name); } } } if (!string.IsNullOrEmpty(changes.NewStartPageToken)) { startPageToken = changes.NewStartPageToken; } pageToken = changes.NextPageToken; } if (changedFiles.Count > 0) { var changedFilesCM = new KeyValueListCM(); foreach (var pair in changedFiles) { changedFilesCM.Values.Add(new KeyValueDTO(pair.Key, pair.Value)); } var eventReportContent = new EventReportCM { EventNames = _eventNames[pollingType], EventPayload = new CrateStorage(Crate.FromContent("ChangedFiles", changedFilesCM)), Manufacturer = "Google", ExternalAccountId = pollingData.ExternalAccountId }; Logger.Info("Polling for Google Drive: changed files of type \"" + pollingType.ToString() + "\""); await _reporter.Broadcast(Crate.FromContent("Standard Event Report", eventReportContent)); } pollingData.Payload = startPageToken; return(pollingData); }
public async Task <PollingDataDTO> Poll(PollingDataDTO pollingData) { Logger.Info($"Polling for Gmail was launched {pollingData.ExternalAccountId}"); var serv = new GoogleGmail(); var googleAuthToken = JsonConvert.DeserializeObject <GoogleAuthDTO>(pollingData.AuthToken); var service = await serv.CreateGmailService(googleAuthToken); if (string.IsNullOrEmpty(pollingData.Payload)) { //Polling is called for the first time //we have no history id to synchronise partitially, so we request the last message from the inbox UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(pollingData.ExternalAccountId); request.RequestParameters["maxResults"] = new Parameter() { DefaultValue = "1", Name = "maxResults", ParameterType = "query" }; var list = request.Execute(); //then we have to get its details and historyId (to use with history listing API method) pollingData.Payload = GetHistoryId(service, list.Messages.FirstOrDefault().Id, pollingData.ExternalAccountId); Logger.Info($"Polling for Gmail {pollingData.ExternalAccountId}: remembered the last email in the inbox"); } else { var request = service.Users.History.List(pollingData.ExternalAccountId); request.StartHistoryId = ulong.Parse(pollingData.Payload); var result = request.Execute(); Logger.Info($"Polling for Gmail {pollingData.ExternalAccountId}: received a history of changes"); if (result.History != null) { foreach (var historyRecord in result.History) { if (historyRecord.MessagesAdded != null) { foreach (var mail in historyRecord.MessagesAdded.Reverse()) { //TODO: make a batch request for emails, instead of calling one by one var email = GetEmail(service, mail.Message.Id, pollingData.ExternalAccountId); var eventReportContent = new EventReportCM { EventNames = "GmailInbox", EventPayload = new CrateStorage(Crate.FromContent("GmailInbox", email)), Manufacturer = "Google", ExternalAccountId = pollingData.ExternalAccountId }; pollingData.Payload = email.MessageID; Logger.Info("Polling for Gmail: got a new email, broadcasting an event to the Hub"); await _reporter.Broadcast(Crate.FromContent("Standard Event Report", eventReportContent)); } } } } else { Logger.Info($"Polling for Gmail {pollingData.ExternalAccountId}: no new emails"); } } pollingData.Result = true; return(pollingData); }
public async Task <PollingDataDTO> ProcessPollingRequest(PollingDataDTO pollingData) { return(await _polling.Poll(pollingData)); }
public static void ExecuteSchedulledJob(PollingDataDTO pollingData, string terminalToken) { IRestfulServiceClient _client = new RestfulServiceClient(); try { //renewing token if (!RenewAuthToken(pollingData, terminalToken).Result) { RecurringJob.RemoveIfExists(pollingData.JobId); Logger.Info($"Polling: token is missing, removing the job for {pollingData.ExternalAccountId}"); } var request = RequestPolling(pollingData, terminalToken, _client); var result = request.Result; if (result != null) { if (!result.Result) { Logger.Info($"Polling: got result for {pollingData.ExternalAccountId} from a terminal {terminalToken}. Deschedulling the job"); if (pollingData.RetryCounter > 3) { Logger.Info($"Polling: for {pollingData.ExternalAccountId} from a terminal {terminalToken}. Deschedulling the job"); RecurringJob.RemoveIfExists(pollingData.JobId); } else { pollingData.RetryCounter++; Logger.Info($"Polling: got result for {pollingData.ExternalAccountId} from a terminal {terminalToken}. Starting Retry {pollingData.RetryCounter}"); RecurringJob.AddOrUpdate(pollingData.JobId, () => SchedullerHelper.ExecuteSchedulledJob(result, terminalToken), "*/" + result.PollingIntervalInMinutes + " * * * *"); } } else { Logger.Info($"Polling: got result for {pollingData.ExternalAccountId} from a terminal {terminalToken}. Success"); RecurringJob.AddOrUpdate(pollingData.JobId, () => SchedullerHelper.ExecuteSchedulledJob(result, terminalToken), "*/" + result.PollingIntervalInMinutes + " * * * *"); } } else { Logger.Info($"Polling: no result for {pollingData.ExternalAccountId} from a terminal {terminalToken}. Terminal didn't answer"); //we didn't get any response from the terminal (it might have not started yet, for example) Let's give it one more chance, and if it will fail - the job will be descheduled cause of Result set to false; if (pollingData.Result) //was the job successfull last time we polled? { Logger.Info($"Polling: no result for {pollingData.ExternalAccountId} from a terminal {terminalToken}. Last polling was successfull"); //in case of ongoing deployment when we have a minimal polling interval, could happen to remove the job. Add default polling interval of 10 minutes in this case as retry pollingData.Result = false; RecurringJob.AddOrUpdate(pollingData.JobId, () => SchedullerHelper.ExecuteSchedulledJob(pollingData, terminalToken), "*/" + pollingData.PollingIntervalInMinutes + " * * * *"); } else { if (pollingData.RetryCounter > 20) { Logger.Info($"Polling: no result for {pollingData.ExternalAccountId} from a terminal {terminalToken}. Remove Job"); //last polling was unsuccessfull, so let's deschedulle it RecurringJob.RemoveIfExists(pollingData.JobId); } else { Logger.Info($"Polling: no result for {pollingData.ExternalAccountId} from a terminal {terminalToken}. Retry Counter {pollingData.RetryCounter}"); pollingData.RetryCounter++; RecurringJob.AddOrUpdate(pollingData.JobId, () => SchedullerHelper.ExecuteSchedulledJob(pollingData, terminalToken), "*/" + pollingData.PollingIntervalInMinutes + " * * * *"); } } } } catch (Exception ex) { if (pollingData != null && !string.IsNullOrWhiteSpace(pollingData.JobId)) { RecurringJob.RemoveIfExists(pollingData.JobId); } Logger.Error("Scheduled job failed", ex); } }