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());
 }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
            }
        }