public static List <ScheduledJobInfo> GetAllJobsList()
        {
            var list = new List <ScheduledJobInfo>();

            if (!bInitialized)
            {
                return(list);
            }
            var jobGroups   = sched.GetJobGroupNames().Result;
            var runninglist = GetRunningJobs();

            foreach (string group in jobGroups)
            {
                var keys = sched.GetJobKeys(GroupMatcher <JobKey> .GroupEquals(group));
                foreach (JobKey key in keys.Result)
                {
                    IJobDetail detail = sched.GetJobDetail(key).Result;
                    if (detail == null)
                    {
                        continue;
                    }
                    var jobview = new ScheduledJobInfo();
                    jobview.Name  = detail.Key.Name;
                    jobview.Group = detail.Key.Group;
                    if (runninglist.ContainsKey(jobview.Group + jobview.Name))
                    {
                        jobview.IsRunning = true;
                    }
                    string strMessage = detail.JobDataMap.GetString("log");
                    jobview.Log = strMessage;
                    var trigs = sched.GetTriggersOfJob(detail.Key).Result;
                    if (trigs != null)
                    {
                        foreach (ITrigger trigger in trigs)
                        {
                            DateTimeOffset?prev = trigger.GetPreviousFireTimeUtc();
                            if (prev.HasValue)
                            {
                                jobview.PrevTime = prev.Value.DateTime.ToBinary();
                            }
                            DateTimeOffset?next = trigger.GetNextFireTimeUtc();
                            if (next.HasValue)
                            {
                                jobview.NextTime = next.Value.DateTime.ToBinary();
                            }
                            var crontrig = trigger as ICronTrigger;
                            if (crontrig != null)
                            {
                                jobview.Schedule = crontrig.CronExpressionString;
                            }
                        }
                    }

                    list.Add(jobview);
                }
            }

            return(list);
        }
        private async Task ValidatePayload(ScheduledJobInfo scheduledJobInfo)
        {
            IDictionary <string, string> payload = scheduledJobInfo.JobPayload;

            if (payload == null)
            {
                throw new ArgumentNullException($"{nameof(ProvisionMerchantsFromMasterCard)} {scheduledJobInfo.JobId} has an empty payload");
            }
            if (!payload.ContainsKey(JobConstants.ContainerName))
            {
                throw new ArgumentException(
                          $"Payload for {nameof(ProvisionMerchantsFromMasterCard)} {scheduledJobInfo.JobId} is missing the blob container name");
            }
            if (!payload.ContainsKey(JobConstants.BlobName))
            {
                throw new ArgumentException(
                          $"Payload for {nameof(ProvisionMerchantsFromMasterCard)} {scheduledJobInfo.JobId} is missing the blob name");
            }
            if (!payload.ContainsKey(JobConstants.ProviderId))
            {
                throw new ArgumentException(
                          $"Payload for {nameof(ProvisionMerchantsFromMasterCard)} {scheduledJobInfo.JobId} is missing the provider id for the merchants");
            }

            string providerId = payload[JobConstants.ProviderId];

            if (string.IsNullOrWhiteSpace(providerId))
            {
                throw new ArgumentException($"ProviderId is empty in {nameof(ProvisionMerchantsFromMasterCard)} {scheduledJobInfo.JobId}");
            }

            provider = await EarnRepository.Instance.GetProviderAsync(providerId).ConfigureAwait(false);

            if (provider == null)
            {
                throw new ArgumentException($"Provider {providerId} does not exist");
            }

            if (!payload.ContainsKey(JobConstants.MerchantFileType))
            {
                throw new ArgumentException(
                          $"Payload for {nameof(ProvisionMerchantsFromMasterCard)} {scheduledJobInfo.JobId} is missing the merchant file type info for the merchants");
            }

            MerchantFileType merchantFileType;

            if (!Enum.TryParse <MerchantFileType>(payload[JobConstants.MerchantFileType], out merchantFileType))
            {
                throw new ArgumentException(
                          $"Payload for {nameof(ProvisionMerchantsFromMasterCard)} {scheduledJobInfo.JobId} has an invalid merchant filetype info for the merchants");
            }
            if (merchantFileType != DataModel.MerchantFileType.MasterCardProvisioning)
            {
                throw new ArgumentException(
                          $"Payload for {nameof(ProvisionMerchantsFromMasterCard)} {scheduledJobInfo.JobId} has an invalid value for merchant filetype info for the merchants");
            }
        }
Exemple #3
0
        public void Schedule(Expression <Action> job, string correlationId, DateTime scheduledDate)
        {
            var jobId = BackgroundJob.Schedule(job, scheduledDate);

            var info = new ScheduledJobInfo
            {
                CorrelationId = correlationId,
                JobId         = jobId,
                ExecutionDate = scheduledDate
            };

            this._repository.AddAndSave <ScheduledJobInfo, Guid>(info);
        }
 private ScheduledJobView CreateJobView(int i, ScheduledJobInfo job)
 {
     return(new ScheduledJobView
     {
         Id = i,
         IsRunning = job.IsRunning,
         Name = job.Name,
         Group = job.Group,
         PrevDate = new DateTime(job.PrevTime, DateTimeKind.Utc),
         NextDate = new DateTime(job.NextTime, DateTimeKind.Utc),
         Schedule = job.Schedule,
         Log = job.Log
     });
 }
        public void Cleanup(Guid jobInfoId)
        {
            ScheduledJobInfo jobInfo = _db.ScheduledJobInfos.Find(jobInfoId);

            if (jobInfo == null)
            {
                Console.WriteLine(
                    $"{nameof(ScheduledJobCleaner)}.{nameof(Cleanup)} called with id {jobInfoId} but no such job exists - skipping"
                    );
                return;
            }

            _db.ScheduledJobInfos.Remove(jobInfo);
        }
Exemple #6
0
        private async Task RunAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                Log.Verbose("Checking for scheduled jobs in the earn jobs queue...");
                try
                {
                    CloudQueueMessage message = await azureQueue.DequeueMessageAsync().ConfigureAwait(false);

                    if (message != null)
                    {
                        string messageInfo = message.AsString;
                        await azureQueue.DeleteMessageAsync(message.Id, message.PopReceipt).ConfigureAwait(false);

                        XDocument xDoc          = XDocument.Parse(messageInfo);
                        var       messageEement = xDoc.Descendants().FirstOrDefault(d => d.Name == "Message");
                        if (messageEement != null)
                        {
                            ScheduledJobInfo scheduledJobInfo =
                                JsonConvert.DeserializeObject <ScheduledJobInfo>(messageEement.Value);
                            Log.Info("JobType {0} found in the queue", scheduledJobInfo.JobType.ToString());
                            IScheduledJob scheduledJob = JobManager.GetJobByType(scheduledJobInfo.JobType);
                            JobManager.DeleteJob(scheduledJobInfo.JobId);
                            Log.Info($"Deleted the azure scheduler job {scheduledJobInfo.JobId}");
                            var executeAsync = scheduledJob?.ExecuteAsync(scheduledJobInfo);
                            if (executeAsync != null)
                            {
                                await executeAsync;
                            }

                            Log.Info("Finished executing the earn job : {0}", scheduledJobInfo.ToString());
                        }
                        else
                        {
                            Log.Error("Invalid Payload in the job message : {0}", messageInfo);
                        }
                    }
                    else
                    {
                        Log.Info("No job found in the earn jobs queue...");
                    }
                }
                catch (Exception exception)
                {
                    Log.Error(exception, "Error in processing the earn job");
                }

                await Task.Delay(TimeSpan.FromSeconds(30));
            }
        }
        private void ScheduleJob(IDelayedJobDescriptor descriptor, IBackgroundJobClient jobClient)
        {
            string jobId = descriptor.Schedule(jobClient);

            ScheduledJobInfo jobInfo = new ScheduledJobInfo()
            {
                JobId = jobId,
                RunAt = descriptor.GetIntendedRunAt()
            };

            descriptor.GetJobInfoReference().Value = jobInfo;
            _db.ScheduledJobInfos.Add(jobInfo);

            jobClient.ContinueJobWith <ScheduledJobCleaner>(jobId, cleaner => cleaner.Cleanup(jobInfo.Id));
        }
        private async Task <HttpStatusCode> ScheduleNextJob(JobType jobType, IDictionary <string, string> jobPayload)
        {
            ScheduledJobInfo scheduledJobInfo = new ScheduledJobInfo
            {
                JobId            = Guid.NewGuid().ToString(),
                JobScheduledTime = DateTime.UtcNow,
                JobType          = jobType,
                JobPayload       = jobPayload
            };
            HttpStatusCode scheduleJobTask = await azureScheduler.ScheduleQueueTypeJobAsync(schedulerQueueInfo.AccountName, schedulerQueueInfo.QueueName, schedulerQueueInfo.SasToken,
                                                                                            JsonConvert.SerializeObject(scheduledJobInfo),
                                                                                            scheduledJobInfo.JobId);

            return(scheduleJobTask);
        }
Exemple #9
0
        public async Task ExecuteAsync(ScheduledJobInfo scheduledJobInfo)
        {
            this.jobInfo = scheduledJobInfo;
            await ValidatePayload().ConfigureAwait(false);

            MemoryStream memoryStream = await DownloadMerchantFileFromBlobAsync().ConfigureAwait(false);

            IList <Merchant> lstMerchants = await ProcessMerchantFileAsync(memoryStream).ConfigureAwait(false);

            if (lstMerchants.Any())
            {
                Log.Info($"Total Merchants to update : {lstMerchants.Count}");
                await EarnRepository.Instance.UpdateAsync(lstMerchants).ConfigureAwait(false);

                Log.Info("Finished updating merchants");
            }

            scheduledJobInfo.JobCompletedTime = DateTime.UtcNow;
        }
Exemple #10
0
        public async Task ExecuteAsync(ScheduledJobInfo scheduledJobInfo)
        {
            IDictionary <string, string> payload = scheduledJobInfo.JobPayload;

            if (payload == null)
            {
                throw new ArgumentNullException($"VisaMerchantLookupJob {scheduledJobInfo.JobId} has an empty payload");
            }
            if (!payload.ContainsKey(ProviderId))
            {
                throw new ArgumentException(
                          $"Payload for VisaMerchantLookupJob {scheduledJobInfo.JobId} is missing the provider id");
            }

            if (string.IsNullOrWhiteSpace(payload[ProviderId]))
            {
                throw new ArgumentException($"ProviderId is empty in VisaMerchantLookupJob {scheduledJobInfo.JobId}");
            }

            Provider provider = await EarnRepository.Instance.GetProviderAsync(payload[ProviderId]).ConfigureAwait(false);

            if (provider == null)
            {
                throw new Exception($"Provider id {payload[ProviderId]} not found");
            }

            Log.Info("Retrieving list of merchants for provider {0}", payload[ProviderId]);
            var merchants = await EarnRepository.Instance.GetMerchantsForProviderAsync(payload[ProviderId]);

            if (merchants == null || !merchants.Any())
            {
                throw new Exception($"VisaMerchantLookupJob failed. Provider {payload[ProviderId]} does not have any merchants");
            }

            Log.Info("Calling Visa endpoint to look up mids for {0} merchants", merchants.Count());
            await CallVisaToGetMids(provider, merchants).ConfigureAwait(false);
        }
        public static Dictionary <string, ScheduledJobInfo> GetRunningJobs()
        {
            var list = new Dictionary <string, ScheduledJobInfo>();

            if (!bInitialized)
            {
                return(list);
            }
            var ilist = sched.GetCurrentlyExecutingJobs();

            Task.WaitAll(ilist);
            foreach (IJobExecutionContext ic in ilist.Result)
            {
                var view = new ScheduledJobInfo();
                view.Group = ic.JobDetail.Key.Group;
                view.Name  = ic.JobDetail.Key.Name;
                if (!list.ContainsKey(view.Group + view.Name))
                {
                    list.Add(view.Group + view.Name, view);
                }
            }

            return(list);
        }
Exemple #12
0
 public JobKey getJobKeyForJobDescription(ScheduledJobInfo aJobDescription)
 {
     return(new JobKey(aJobDescription.Name, aJobDescription.Group));
 }
        public async Task ExecuteAsync(ScheduledJobInfo scheduledJobInfo)
        {
            IDictionary <string, string> payload = scheduledJobInfo.JobPayload;

            if (payload == null)
            {
                throw new ArgumentNullException($"SyncOfferWithCommerceJob {scheduledJobInfo.JobId} has an empty payload");
            }
            if (!payload.ContainsKey(JobConstants.OfferId))
            {
                throw new ArgumentException(
                          $"Payload for SyncOfferWithCommerceJob {scheduledJobInfo.JobId} is missing the offer id");
            }
            string offerId = payload[JobConstants.OfferId];

            if (string.IsNullOrWhiteSpace(offerId))
            {
                throw new ArgumentException($"OfferId is empty in SyncOfferWithCommerceJob {scheduledJobInfo.JobId}");
            }
            Offer offerInDb = await EarnRepository.Instance.GetOfferAsync(offerId).ConfigureAwait(false);

            if (offerInDb == null)
            {
                throw new Exception($"SyncOfferWithCommerceJob failed. OfferId {offerId} does not exists");
            }
            var offerProvider = await EarnRepository.Instance.GetProviderAsync(offerInDb.ProviderId).ConfigureAwait(false);

            if (offerProvider == null)
            {
                throw new Exception($"SyncOfferWithCommerceJob failed. ProviderId {offerInDb.ProviderId} does not exists");
            }
            var offerMerchants = await EarnRepository.Instance.GetMerchantsForProviderAsync(offerProvider.Id).ConfigureAwait(false);

            if (offerMerchants == null || !offerMerchants.Any())
            {
                throw new Exception($"SyncOfferWithCommerceJob failed. There are no merchants attached the offer provider {offerProvider.Id}");
            }

            // commerce storage client
            IRetryPolicy retryPolicy      = new ExponentialRetry(TimeSpan.FromSeconds(6), 4);
            string       connectionString = CloudConfigurationManager.GetSetting("CommerceStorageConnectionString");

            MerchantRegistrationAzureBlob = new AzureBlob(connectionString, retryPolicy);

            var merchantsNotFullyRegisteredInCommerce = offerMerchants.Where(offerMerchant => offerMerchant.Payments
                                                                             .Any(payment => payment.SyncedWithCommerce == false));

            if (merchantsNotFullyRegisteredInCommerce.Any())
            {
                Tuple <bool, List <Merchant> > registerResult = await RegisterOfferWithCommerceAsync(offerInDb, offerProvider, merchantsNotFullyRegisteredInCommerce).ConfigureAwait(false);

                if (registerResult.Item1 && registerResult.Item2.Any())
                {
                    //Updates to a merchant basically is updating the payment mid of the merchant to indicate
                    //whether the mid was successfully registered in commerce or not
                    Log.Info("Updating the payments inside merchants to mark the sync status with commerce");
                    await EarnRepository.Instance.UpdateAsync <Merchant>(registerResult.Item2);
                }
            }
            else
            {
                Log.Info($"All Mids of merchants associated with offer {offerId} are already synced with commerce");
            }

            scheduledJobInfo.JobCompletedTime = DateTime.UtcNow;
        }
        public async Task ExecuteAsync(ScheduledJobInfo scheduledJobInfo)
        {
            // validate the job info
            IDictionary <string, string> payload = scheduledJobInfo.JobPayload;

            if (payload == null)
            {
                throw new ArgumentNullException($"ProvisionAmexMidsJob {scheduledJobInfo.JobId} has an empty payload");
            }
            if (!payload.ContainsKey(JobConstants.ContainerName))
            {
                throw new ArgumentException($"ProvisionAmexMidsJob {scheduledJobInfo.JobId} is missing the blob container name");
            }
            blobContainer = payload[JobConstants.ContainerName];
            if (string.IsNullOrWhiteSpace(blobContainer))
            {
                throw new ArgumentException($"ProvisionAmexMidsJob {scheduledJobInfo.JobId} has invalid blob container name");
            }
            if (!payload.ContainsKey(JobConstants.BlobName))
            {
                throw new ArgumentException($"ProvisionAmexMidsJob {scheduledJobInfo.JobId} is missing the blob name");
            }
            merchantFileName = payload[JobConstants.BlobName];
            if (string.IsNullOrWhiteSpace(merchantFileName))
            {
                throw new ArgumentException($"ProvisionAmexMidsJob {scheduledJobInfo.JobId} has invalid blob name");
            }
            if (!payload.ContainsKey(JobConstants.ProviderId))
            {
                throw new ArgumentException($"ProvisionAmexMidsJob {scheduledJobInfo.JobId} is missing the provider id");
            }
            string providerId = payload[JobConstants.ProviderId];

            if (string.IsNullOrWhiteSpace(providerId))
            {
                throw new ArgumentException($"ProvisionAmexMidsJob {scheduledJobInfo.JobId} has invalid provider id");
            }
            provider = await EarnRepository.Instance.GetProviderAsync(providerId).ConfigureAwait(false);

            if (provider == null)
            {
                throw new ArgumentException($"ProvisionAmexMidsJob {scheduledJobInfo.JobId}: Provider {providerId} does not exist");
            }
            if (payload.ContainsKey(JobConstants.Author))
            {
                author = payload[JobConstants.Author];
            }

            // process the job
            MemoryStream memoryStream = await DownloadMerchantFileFromBlobAsync().ConfigureAwait(false);

            Tuple <IList <Merchant>, IList <Merchant> > merchants = await ProcessMerchantFileAsync(memoryStream).ConfigureAwait(false);

            // Need to do Visa lookup for the newly added merchants
            //if (merchants.Item1.Any())
            //{
            //    Log.Info($"Total Merchants to add : {merchants.Item1.Count}");
            //    // need to validate before creating new merchants
            //    await EarnRepository.Instance.AddMerchantsInBatchAsync(merchants.Item1).ConfigureAwait(false);
            //    Log.Info("Finished adding merchants");
            //}

            if (merchants.Item2.Any())
            {
                Log.Info($"Total Merchants to update : {merchants.Item2.Count}");
                await EarnRepository.Instance.UpdateAsync(merchants.Item2).ConfigureAwait(false);

                Log.Info("Finished updating merchants");
            }

            scheduledJobInfo.JobCompletedTime = DateTime.UtcNow;
        }
Exemple #15
0
        public async Task <IHttpActionResult> CreateOrUpdate([FromBody] Offer offer, bool active = false)
        {
            Guid guid;

            if (string.IsNullOrWhiteSpace(offer.ProviderId) || !Guid.TryParse(offer.ProviderId, out guid))
            {
                Log.Warn("Invalid provider id");
                return(BadRequest("Invalid provider id"));
            }

            Log.Info("Serving OfferController CreateOrUpdate");
            try
            {
                Provider provider = (await EarnRepository.Instance.GetProviderAsync(offer.ProviderId));
                if (provider == null)
                {
                    Log.Warn("Provider not found");
                    return(NotFound());
                }

                bool result;
                bool isNew;

                if (active)
                {
                    offer.StartDate = DateTime.UtcNow;
                    offer.EndDate   = DateTime.MaxValue;
                }
                else
                {
                    offer.StartDate = offer.EndDate = DateTime.MinValue;
                }

                if (string.IsNullOrWhiteSpace(offer.Id))
                {
                    isNew    = true;
                    offer.Id = Guid.NewGuid().ToString();
                    result   = await EarnRepository.Instance.CreateAsync(new List <Offer> {
                        offer
                    });
                }
                else
                {
                    isNew = false;
                    if (!Guid.TryParse(offer.Id, out guid))
                    {
                        Log.Warn("Invalid offer id");
                        return(BadRequest("Invalid Offer Id"));
                    }

                    // check if this offer exists
                    Offer previousOffer = (await EarnRepository.Instance.GetOfferAsync(offer.Id));
                    if (previousOffer == null)
                    {
                        Log.Warn("Offer not found");
                        return(NotFound());
                    }

                    result = await EarnRepository.Instance.UpdateAsync(new List <Offer> {
                        offer
                    });
                }

                if (active)
                {
                    //If the offer is active, update the provider with the active offer
                    Log.Verbose("Setting offer {0} as active for the provider {1}", offer.Id, offer.ProviderId);
                    provider.OfferId = offer.Id;
                    result          &= await EarnRepository.Instance.UpdateAsync(new List <Provider> {
                        provider
                    });

                    Log.Verbose("Scheduling the job to register the offer with commerce");
                    //Schedule the job to register the offer, provider and merchant mids with commerce
                    X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                    store.Open(OpenFlags.ReadOnly);
                    X509Certificate2 subscriptionCertificate = store.Certificates.Find(X509FindType.FindByThumbprint, ConfigurationManager.AppSettings["SchedulerCertificateThumbprint"], false)[0];
                    store.Close();

                    AzureScheduler azureScheduler = new AzureScheduler(subscriptionCertificate,
                                                                       ConfigurationManager.AppSettings["SchedulerSubscriptionId"],
                                                                       ConfigurationManager.AppSettings["SchedulerCloudServiceId"],
                                                                       ConfigurationManager.AppSettings["SchedulerJobCollectionName"]);

                    string           jobId            = Guid.NewGuid().ToString();
                    ScheduledJobInfo scheduledJobInfo = new ScheduledJobInfo
                    {
                        JobId            = jobId,
                        JobType          = JobType.SyncOfferWithCommerce,
                        JobScheduledTime = DateTime.UtcNow,
                        JobPayload       = new Dictionary <string, string>
                        {
                            { JobConstants.OfferId, offer.Id }
                        }
                    };

                    HttpStatusCode scheduleJobTask = await azureScheduler.ScheduleQueueTypeJobAsync(ConfigurationManager.AppSettings["SchedulerStorageAccountName"],
                                                                                                    ConfigurationManager.AppSettings["SchedulerQueueName"],
                                                                                                    ConfigurationManager.AppSettings["SchedulerSasToken"],
                                                                                                    JsonConvert.SerializeObject(scheduledJobInfo),
                                                                                                    jobId);

                    if (scheduleJobTask == HttpStatusCode.OK || scheduleJobTask == HttpStatusCode.Created)
                    {
                        Log.Verbose("Successfully scheduled the job to register the offer with commerce");
                    }
                }

                if (result)
                {
                    if (isNew)
                    {
                        Log.Verbose("Offer created - id {0}", offer.Id);
                        return(Created(result.ToString(), offer));
                    }

                    Log.Verbose("Offer updated - id {0}", offer.Id);

                    return(Ok(offer));
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Failed processing OfferController CreateOrUpdate");
                return(InternalServerError(ex));
            }

            return(InternalServerError());
        }
        public async Task ExecuteAsync(ScheduledJobInfo scheduledJobInfo)
        {
            await ValidatePayload(scheduledJobInfo).ConfigureAwait(false);

            IDictionary <string, string> payload = scheduledJobInfo.JobPayload;
            string merchantFileName = payload[JobConstants.BlobName];
            string blobContainer    = payload[JobConstants.ContainerName];
            string providerId       = payload[JobConstants.ProviderId];

            MemoryStream ms = await GetMerchantsFromBlobAsync(merchantFileName, blobContainer).ConfigureAwait(false);

            MerchantFileProcessor             merchantFileProcessor = MerchantProcessorFactory.GetMerchantFileProcessor(merchantFileName);
            Tuple <string, IList <Merchant> > provisioningData      = merchantFileProcessor.ImportMasterCardProvisioningFile(ms);

            if (provisioningData == null)
            {
                throw new Exception("Error in processing the mastercard provisioning file. Unable to provision merchants");
            }

            string           masterCardMerchantsProvisioningDate = provisioningData.Item1;
            IList <Merchant> lstProvisionedMerchants             = provisioningData.Item2;

            if (lstProvisionedMerchants.Any())
            {
                //Update the provider with the MasterCard merchant provisioning file date info. This is needed
                //at the time of exporting the file back to MasterCard.
                if (provider.ExtendedAttributes == null)
                {
                    provider.ExtendedAttributes = new Dictionary <string, string>();
                }
                if (!provider.ExtendedAttributes.ContainsKey(MerchantConstants.MCProvisioningDate))
                {
                    provider.ExtendedAttributes.Add(MerchantConstants.MCProvisioningDate, masterCardMerchantsProvisioningDate);
                }
                else
                {
                    provider.ExtendedAttributes[MerchantConstants.MCProvisioningDate] = masterCardMerchantsProvisioningDate;
                }
                await EarnRepository.Instance.UpdateAsync <Provider>(new List <Provider> {
                    provider
                });

                Log.Info($"Updated the provider {providerId} with the MasterCard provisioning date");

                //Add the new merchants to db.
                //TODO: As of now, the code can handle only new merchant additions from the MC file.
                //Need to add support to handle updates and deletes

                foreach (Merchant merchant in lstProvisionedMerchants)
                {
                    merchant.Id         = Guid.NewGuid().ToString();
                    merchant.ProviderId = provider.Id;
                    GeoCodeMerchantLocation(merchant);
                    if (merchant.ExtendedAttributes == null)
                    {
                        merchant.ExtendedAttributes = new Dictionary <string, string>();
                    }
                    string masterCardId = MasterCardIdGenerator.GetUniqueId(provider, merchant, "P");
                    Log.Info($"Generated mastercardid {masterCardId} for merchant {merchant.Name}");
                    merchant.ExtendedAttributes.Add(MerchantConstants.MCID, masterCardId);
                }

                Log.Info($"Total Merchants to add to db {lstProvisionedMerchants.Count}");
                await EarnRepository.Instance.AddMerchantsInBatchAsync(lstProvisionedMerchants);

                Log.Info($"Successfully added {lstProvisionedMerchants.Count} merchants to db");

                scheduledJobInfo.JobCompletedTime = DateTime.UtcNow;
            }
            else
            {
                Log.Warn("Provisioning file from MasterCard has 0 merchants");
            }
        }
        public async Task <IHttpActionResult> ImportMerchants([FromBody] ImportMerchantsModel merchantImportModel)
        {
            if (merchantImportModel == null)
            {
                return(BadRequest());
            }

            Log.Info($"MerchantController ImportMerchants. Payload {merchantImportModel.ToString()}");
            Guid guid;

            string errorMessage = null;

            if (string.IsNullOrWhiteSpace(merchantImportModel.ProviderId) || !Guid.TryParse(merchantImportModel.ProviderId, out guid))
            {
                errorMessage = "Invalid ProviderId";
                Log.Error(errorMessage);
                return(BadRequest(errorMessage));
            }

            if (string.IsNullOrWhiteSpace(merchantImportModel.FileName))
            {
                errorMessage = "Missing merchant file name";
                Log.Error(errorMessage);
                return(BadRequest(errorMessage));
            }

            if (!merchantImportModel.FileName.EndsWith(".xlsx", StringComparison.InvariantCultureIgnoreCase) &&
                !merchantImportModel.FileName.EndsWith(".csv", StringComparison.InvariantCultureIgnoreCase))
            {
                errorMessage = "Invalid file extension for merchant file";
                Log.Error(errorMessage);
                return(BadRequest(errorMessage));
            }

            try
            {
                var provider = (await EarnRepository.Instance.GetProviderAsync(merchantImportModel.ProviderId));
                if (provider == null)
                {
                    Log.Warn("Provider not found");
                    return(NotFound());
                }

                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                store.Open(OpenFlags.ReadOnly);
                X509Certificate2 subscriptionCertificate = store.Certificates.Find(X509FindType.FindByThumbprint, ConfigurationManager.AppSettings["SchedulerCertificateThumbprint"], false)[0];
                store.Close();

                AzureScheduler azureScheduler = new AzureScheduler(subscriptionCertificate,
                                                                   ConfigurationManager.AppSettings["SchedulerSubscriptionId"],
                                                                   ConfigurationManager.AppSettings["SchedulerCloudServiceId"],
                                                                   ConfigurationManager.AppSettings["SchedulerJobCollectionName"]);

                string           jobId            = Guid.NewGuid().ToString();
                ScheduledJobInfo scheduledJobInfo = new ScheduledJobInfo
                {
                    JobId            = jobId,
                    JobScheduledTime = DateTime.UtcNow,
                    JobPayload       = new Dictionary <string, string>
                    {
                        { JobConstants.ProviderId, merchantImportModel.ProviderId },
                        { JobConstants.ContainerName, ConfigurationManager.AppSettings["SchedulerStorageContainerName"] },
                        { JobConstants.BlobName, merchantImportModel.FileName },
                        { JobConstants.MerchantFileType, merchantImportModel.MerchantFileType.ToString() },
                        { JobConstants.Author, merchantImportModel.Author }
                    }
                };

                if (merchantImportModel.MerchantFileType == MerchantFileType.MasterCardAuth || merchantImportModel.MerchantFileType == MerchantFileType.MasterCardClearing)
                {
                    Log.Info($"Scheduling MasterCard Job for handling file type {merchantImportModel.MerchantFileType.ToString()}");
                    //Do not call visa MID lookup API if we are importing mastercard auth file. Merchant address from mastercard clearing file is always treated as ground truth
                    //Merchant address being the important parameter for MID lookup, it will be done at the time of clearing file import
                    string runVisaLookup = (merchantImportModel.MerchantFileType == MerchantFileType.MasterCardAuth) ? "false" : ConfigurationManager.AppSettings["RunVisaLookup"];

                    scheduledJobInfo.JobType = JobType.ProvisionMasterCardMid;
                    scheduledJobInfo.JobPayload.Add(JobConstants.RunVisaLookup, runVisaLookup);
                }
                else if (merchantImportModel.MerchantFileType == MerchantFileType.Visa)
                {
                    Log.Info($"Scheduling Visa Job for handling file type {merchantImportModel.MerchantFileType.ToString()}");
                    scheduledJobInfo.JobType = JobType.ProvisionRewardNetworkVisaMid;
                }
                else if (merchantImportModel.MerchantFileType == MerchantFileType.Amex)
                {
                    Log.Info($"Scheduling Amex Job for handling file type {merchantImportModel.MerchantFileType.ToString()}");
                    scheduledJobInfo.JobType = JobType.ProvisionAmexMid;
                }

                HttpStatusCode scheduleJobTask = await azureScheduler.ScheduleQueueTypeJobAsync(ConfigurationManager.AppSettings["SchedulerStorageAccountName"],
                                                                                                ConfigurationManager.AppSettings["SchedulerQueueName"],
                                                                                                ConfigurationManager.AppSettings["SchedulerSasToken"],
                                                                                                JsonConvert.SerializeObject(scheduledJobInfo),
                                                                                                jobId);

                if (scheduleJobTask == HttpStatusCode.OK || scheduleJobTask == HttpStatusCode.Created)
                {
                    Log.Info($"Successfully scheduled job");
                    return(Ok(jobId));
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Failed processing MerchantController ImportMerchants");
                return(InternalServerError(ex));
            }

            return(InternalServerError());
        }
Exemple #18
0
        public async Task ExecuteAsync(ScheduledJobInfo scheduledJobInfo)
        {
            IDictionary <string, string> payload = scheduledJobInfo.JobPayload;

            if (payload == null)
            {
                throw new ArgumentNullException($"VisaMerchantLookupJob {scheduledJobInfo.JobId} has an empty payload");
            }
            if (!payload.ContainsKey(ProviderId))
            {
                throw new ArgumentException(
                          $"Payload for VisaMerchantLookupJob {scheduledJobInfo.JobId} is missing the provider id");
            }

            if (string.IsNullOrWhiteSpace(payload[ProviderId]))
            {
                throw new ArgumentException($"ProviderId is empty in VisaMerchantLookupJob {scheduledJobInfo.JobId}");
            }

            provider = await EarnRepository.Instance.GetProviderAsync(payload[ProviderId]).ConfigureAwait(false);

            if (provider == null)
            {
                throw new Exception($"Provider id {payload[ProviderId]} not found");
            }
            string feedInformation = null;

            if (provider.ExtendedAttributes != null && provider.ExtendedAttributes.ContainsKey(JobConstants.FeedInformation))
            {
                feedInformation = provider.ExtendedAttributes[JobConstants.FeedInformation];
            }
            if (string.IsNullOrEmpty(feedInformation))
            {
                throw new Exception($"Reward network feed information is missing in {provider.Id}");
            }
            RewardNetworkFeedInformation rnFeedInformation = JsonConvert.DeserializeObject <RewardNetworkFeedInformation>(feedInformation);

            if (string.IsNullOrWhiteSpace(rnFeedInformation.Url))
            {
                throw new Exception($"Feed information is missing the reward network url");
            }
            if (string.IsNullOrWhiteSpace(rnFeedInformation.UserName))
            {
                throw new Exception($"Feed information is missing the reward network username");
            }
            if (string.IsNullOrWhiteSpace(rnFeedInformation.Password))
            {
                throw new Exception($"Feed information is missing the reward network password");
            }

            MemoryStream ms = await DownloadFeedFileAsync(rnFeedInformation).ConfigureAwait(false);

            IList <Merchant> lstMerchants = await ParseFeedFileAsync(ms).ConfigureAwait(false);

            if (lstMerchants != null)
            {
                IList <Merchant> lstNewMerchants = await LookForNewMerchantsAsync(provider, lstMerchants).ConfigureAwait(false);

                if (lstNewMerchants.Any())
                {
                    await EnrichMerchantInformationAsync(lstMerchants, rnFeedInformation).ConfigureAwait(false);

                    await EarnRepository.Instance.AddMerchantsInBatchAsync(lstNewMerchants).ConfigureAwait(false);

                    Log.Info("Finished adding reward network merchants to db");
                }
            }
            scheduledJobInfo.JobCompletedTime = DateTime.UtcNow;
        }