Пример #1
0
        /// <summary>
        /// Process MasterCard rebate confirmation file job execution.
        /// </summary>
        /// <param name="details">
        /// Details of the job to be executed.
        /// </param>
        /// <param name="log">
        /// Log within which to log status of job processing.
        /// </param>
        /// <returns>
        /// A task to execute the  job.
        /// </returns>
        /// <remarks>
        /// Once complete, this job will schedule a corresponding MasterCardProcessRebateConfirmationJob.
        /// </remarks>
        public async Task Execute(ScheduledJobDetails details,
                                  CommerceLog log)
        {
            Log = log;
            Log.Verbose("Starting execution of job.\r\nDetails {0}", details);

            MasterCardRebateConfirmationBlobClient blobClient = MasterCardBlobClientFactory.MasterCardRebateConfirmationBlobClient(log);

            // Download files from MasterCard and upload them to the blob store.
            IFtpClient ftpClient = MasterCardFtpClientFactory.RebateConfirmationFtpClient(Log);

            string[] files = await ftpClient.DirectoryListAsync();

            if (files != null)
            {
                foreach (string fileName in files)
                {
                    using (MemoryStream memStream = new MemoryStream())
                    {
                        // Download the file from MasterCard.
                        await ftpClient.DownloadFileAsync(fileName, memStream).ConfigureAwait(false);

                        // Upload the file to the blob store.
                        memStream.Position = 0;
                        await blobClient.UploadAsync(memStream, fileName).ConfigureAwait(false);
                    }
                }
            }

            // Process all pending rebate confirmation files in the blob store.
            ICollection <string> fileNames = blobClient.RetrieveNamesOfPendingFiles();

            if (fileNames != null)
            {
                foreach (string fileName in fileNames)
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        // Download the file from the blob store.
                        memoryStream.Position = 0;
                        await blobClient.DownloadAsync(memoryStream, fileName).ConfigureAwait(false);

                        // Process the file.
                        memoryStream.Position = 0;
                        ISettlementFileProcessor rebateConfirmationProcessor = MasterCardFileProcessorFactory.MasterCardRebateConfirmationProcessor(memoryStream, fileName);
                        await rebateConfirmationProcessor.Process().ConfigureAwait(false);
                    }

                    // Mark the file as having been processed.
                    await blobClient.MarkAsCompleteAsync(fileName).ConfigureAwait(false);
                }
            }

            Log.Verbose("Execution of job {0} complete ", details.JobId);
        }
Пример #2
0
        public async Task Execute(ScheduledJobDetails details, CommerceLog log)
        {
            Log = log;

            Log.Verbose("Starting execution of job.\r\nDetails {0}", details);

            // Process rebate job for Visa.
            var visaProcessor = VisaSettlementProcessorFactory.VisaRebateProcessor();
            await visaProcessor.Process().ConfigureAwait(false);

            Log.Verbose("Exeuction of job {0} complete ", details.JobId);
        }
Пример #3
0
        /// <summary>
        /// Process Pts File Job Execution
        /// </summary>
        /// <param name="details">
        /// Details of the job we are executing here.
        /// </param>
        /// <param name="logger">
        /// Handle to the logger
        /// </param>
        public async Task Execute(ScheduledJobDetails details, CommerceLog logger)
        {
            Logger = logger;

            Logger.Verbose("Starting execution of job \r\n " +
                           "Details {0}", details);

            // Process PTS Job for FDC
            ISettlementFileProcessor ptsProcessor = FirstDataFileProcessorFactory.FirstDataPtsProcessor(OnPtsBuild);
            await ptsProcessor.Process().ConfigureAwait(false);

            Logger.Verbose("Exeuction of job {0} complete ", details.JobId);
        }
        /// <summary>
        /// Process MasterCard rebate file job execution.
        /// </summary>
        /// <param name="details">
        /// Details of the job to be executed.
        /// </param>
        /// <param name="log">
        /// Log within which to log status of job processing.
        /// </param>
        /// <returns>
        /// A task to execute the  job.
        /// </returns>
        public async Task Execute(ScheduledJobDetails details,
                                  CommerceLog log)
        {
            Log = log;

            Log.Verbose("Starting execution of job.\r\nDetails {0}", details);

            // Process rebate job for MasterCard.
            ISettlementFileProcessor masterCardProcessor = MasterCardFileProcessorFactory.MasterCardRebateProcessor(UploadRebateFile);
            await masterCardProcessor.Process().ConfigureAwait(false);

            Log.Verbose("Exeuction of job {0} complete ", details.JobId);
        }
        /// <summary>
        /// Process Amex Statement Credi File Job Execution
        /// </summary>
        /// <param name="details">
        /// Details of the job we are executing here.
        /// </param>
        /// <param name="logger">
        /// Handle to the logger
        /// </param>
        public async Task Execute(ScheduledJobDetails details, CommerceLog logger)
        {
            Logger = logger;

            Logger.Verbose("Starting execution of job \r\n Details {0}", details);

            // Process Statement Credit Acknowledgment files
            await ProcessStatementCreditResponse();

            // Process Statement Credit files
            StatementCreditFileBuilder builder = new StatementCreditFileBuilder();
            await builder.Build(OnStmtCreditFileBuild).ConfigureAwait(false);

            Logger.Verbose("Execution of job {0} complete ", details.JobId);
        }
Пример #6
0
        /// <summary>
        /// 1. Process the FDC Extract file.
        /// 2. Schedule the Process Pts Job
        /// </summary>
        /// <param name="details">
        /// Details of the job we are executing here.
        /// </param>
        /// <param name="logger">
        /// Handle to the logger
        /// </param>
        public async Task Execute(ScheduledJobDetails details, CommerceLog logger)
        {
            logger.Verbose("Starting execution of job \r\n " +
                           "Details {0}", details);

            string     connectionString = CloudConfigurationManager.GetSetting("Lomo.Commerce.Fdc.Blob.ConnectionString");
            IFtpClient ftpClient        = FirstDataFtpClientFactory.FirstDataExtractFtpClient(logger);

            FirstDataExtractBlobClient blobClient = FirstDataBlobClientFactory.FirstDataExtractBlobClient(connectionString, logger);

            string[] files = await ftpClient.DirectoryListAsync();

            if (files != null)
            {
                foreach (string fileName in files)
                {
                    MemoryStream memStream = new MemoryStream();
                    await ftpClient.DownloadFileAsync(fileName, memStream).ConfigureAwait(false);

                    // lets upload it to blob
                    memStream.Position = 0;
                    await blobClient.UploadAsync(memStream, fileName).ConfigureAwait(false);
                }
            }

            // Now try to run all the pending files in the blob
            ICollection <string> listOfFiles = blobClient.RetrieveFilesToProcess();

            if (listOfFiles != null)
            {
                foreach (string fileName in listOfFiles)
                {
                    MemoryStream memStream = new MemoryStream();
                    memStream.Position = 0;
                    await blobClient.DownloadAsync(memStream, fileName).ConfigureAwait(false);

                    memStream.Position = 0;
                    ISettlementFileProcessor extractProcessor = FirstDataFileProcessorFactory.FirstDataExtractProcessor(fileName, memStream);
                    await extractProcessor.Process().ConfigureAwait(false);

                    await blobClient.MarkAsProcessedAsync(fileName).ConfigureAwait(false);
                }
            }

            logger.Verbose("Execution of job {0} complete ", details.JobId);
        }
        /// <summary>
        /// Process Amex Transaction Log File Job Execution
        /// </summary>
        /// <param name="details">
        /// Details of the job we are executing here.
        /// </param>
        /// <param name="logger">
        /// Handle to the logger
        /// </param>
        public async Task Execute(ScheduledJobDetails details, CommerceLog logger)
        {
            logger.Verbose("Starting execution of job \r\n Details {0}", details);
            string connectionString = CloudConfigurationManager.GetSetting("Lomo.Commerce.Fdc.Blob.ConnectionString");
            AmexTransactionLogSftpClient     ftpClient  = new AmexTransactionLogSftpClient(logger);
            AmexTransactionLogFileBlobClient blobClient = AmexBlobFactory.TransactionLogBlobClient(connectionString, logger);

            string[] files = await ftpClient.DirectoryListAsync("AXP_MSF_TLOG", "outbox");

            if (files != null)
            {
                foreach (string fileName in files)
                {
                    MemoryStream memStream = new MemoryStream();
                    await ftpClient.DownloadFileAsync(fileName, memStream, "outbox").ConfigureAwait(false);

                    // lets upload it to blob
                    memStream.Position = 0;
                    await blobClient.UploadAsync(memStream, fileName).ConfigureAwait(false);
                }
            }

            ICollection <string> listOfFiles = blobClient.RetrieveFilesToProcess();

            if (listOfFiles != null)
            {
                foreach (string fileName in listOfFiles)
                {
                    MemoryStream memStream = new MemoryStream();
                    memStream.Position = 0;
                    await blobClient.DownloadAsync(memStream, fileName).ConfigureAwait(false);

                    memStream.Position = 0;
                    TransactionLogFileProcessor transactionLogFileProcessor = new TransactionLogFileProcessor()
                    {
                        TransactionLogFileName   = fileName,
                        TransactionLogFileStream = memStream
                    };
                    await transactionLogFileProcessor.Process().ConfigureAwait(false);

                    await blobClient.MarkAsProcessedAsync(fileName).ConfigureAwait(false);
                }
            }

            logger.Verbose("Execution of job {0} complete ", details.JobId);
        }
Пример #8
0
        /// <summary>
        /// Exponentially backoff the next run time of a job after every failure (Non-Terminal) upto a defined MAX.
        /// Currently, only one time jobs are exponentially backed off, and recurring jobs are just scheduled for next occurence.
        /// </summary>
        /// <param name="scheduler">
        /// Instance of the Scheduler
        /// </param>
        /// <param name="jobDetails">
        /// Scheduled Job Details.
        /// </param>
        /// <returns>
        /// Async Task Wrapper
        /// </returns>
        public static async Task ExponentiallyBackoffAsync(this IScheduler scheduler, ScheduledJobDetails jobDetails, CommerceLog log)
        {
            // this branch should not happen once we schedule the job once.
            if (jobDetails != null && jobDetails.Recurrence != null)
            {
                // if job is scheduled to run only once
                if (jobDetails.Recurrence.Count == 1)
                {
                    // initialize retry count if it does not exist
                    if (jobDetails.Payload == null)
                    {
                        jobDetails.Payload = new Dictionary <string, string>();
                        jobDetails.Payload["RetryCount"] = "0";
                    }
                    else if (!jobDetails.Payload.ContainsKey("RetryCount"))
                    {
                        jobDetails.Payload["RetryCount"] = "0";
                    }

                    int retryCount;
                    if (!int.TryParse(jobDetails.Payload["RetryCount"], out retryCount))
                    {
                        retryCount = 0;
                    }

                    //Important: Since the job is a run once job, so recurrence for the next retry is solely
                    // dependent on the retry interval. Past recurrence is immaterial.
                    jobDetails.Recurrence = new Recurrence()
                    {
                        Frequency = RecurrenceFrequency.Second,
                        Count     = 1,
                        Interval  = GetWaitTimeInSeconds(retryCount)
                    };

                    log.Verbose("Job Id {0} has been retried {1} times, back off to try the next time after {2} seconds",
                                jobDetails.JobId,
                                retryCount,
                                jobDetails.Recurrence.Interval);

                    // increment retry count in payload
                    jobDetails.Payload["RetryCount"] = (retryCount + 1).ToString(CultureInfo.InvariantCulture);

                    // schedule it to run later
                    await scheduler.UpdateJobAsync(jobDetails).ConfigureAwait(false);
                }
                else // recurring job
                {
                    // just mark current iteration as done. We will try again next time
                    await scheduler.CompleteJobIterationAsync(jobDetails).ConfigureAwait(false);
                }
            }
            else
            {
                log.Warning("After first run of job, job or recurrence should not be null.");
                await Task.Factory.StartNew(() => { }).ConfigureAwait(false);
            }
        }
Пример #9
0
        private async Task <AmexCardResponse> AddOrRemoveCardAsync <T>(T requestPayload, string requestUri, AmexOAuthResponse amexOAuthResponse)
        {
            if (amexOAuthResponse != null)
            {
                string     timestamp = ((int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds).ToString();
                string     nonce     = string.Concat(timestamp, ":AMEX");
                UriBuilder uri       = new UriBuilder(requestUri);

                //Format = timestamp \n timestamp:AMEX \n method \n path \n port \n\n
                string message = string.Format("{0}\n{1}\nPOST\n{2}\n{3}\n{4}\n\n", timestamp, nonce, Regex.Replace(HttpUtility.UrlEncode(uri.Path.ToLowerInvariant()), @"%[a-f0-9]{2}", c => c.Value.ToUpper()), uri.Host.ToLowerInvariant(), uri.Port);

                using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(amexOAuthResponse.MacKey)))
                {
                    string mac = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(message)));
                    // Format -> MAC id="access_token",ts="timestamp",nonce="timestamp:AMEX",mac="HMACSHA256 hash"
                    string    authorizationHeader = string.Format("MAC id=\"{0}\",ts=\"{1}\",nonce=\"{2}\",mac=\"{3}\"", amexOAuthResponse.AccessToken, timestamp, nonce, mac);
                    Stopwatch timer = Stopwatch.StartNew();

                    try
                    {
                        using (HttpClient httpClient = new HttpClient())
                        {
                            httpClient.DefaultRequestHeaders.Accept.Clear();
                            //httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("MAC", authorizationHeader.ToString());
                            httpClient.DefaultRequestHeaders.Add("Authorization", authorizationHeader.ToString());
                            httpClient.DefaultRequestHeaders.Add("X-AMEX-API-KEY", ConfigurationManager.AppSettings[AmexConstants.AmexOAuthClientId]);
                            httpClient.DefaultRequestHeaders.Add("X-AMEX-MSG-ID", CommerceLog.ActivityId.ToString("N"));

                            HttpResponseMessage response = await httpClient
                                                           .PostAsJsonAsync(requestUri, requestPayload)
                                                           .ConfigureAwait(false);

                            string content = await response.Content.ReadAsStringAsync();

                            if (response.IsSuccessStatusCode)
                            {
                                CommerceLog.Verbose("Received Amex AddOrRemoveCardAsync response. \r\nUri: {0} \r\nContent: {1}", requestUri, content);
                                return(JsonConvert.DeserializeObject <AmexCardResponse>(content));
                            }
                            else
                            {
                                CommerceLog.Critical("Unable to get Amex AddOrRemoveCardAsync response. \r\nUri: {0} \r\nStatus: {1} \r\nContent: {2}", null, requestUri, response.StatusCode, content);
                            }
                        }
                    }
                    finally
                    {
                        timer.Stop();
                        PerformanceInformation.Add(requestUri, string.Format("{0} ms", timer.ElapsedMilliseconds));
                    }
                }
            }

            return(null);
        }
Пример #10
0
        private async Task <AmexOAuthResponse> GetOAuthTokenAsync()
        {
            // unix epoch format
            string timestamp = ((int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds).ToString();
            string nonce     = string.Concat(timestamp, ":AMEX");
            string clientId  = ConfigurationManager.AppSettings[AmexConstants.AmexOAuthClientId];

            // Format -> client_id \n timestamp \n timestamp:AMEX \n grant
            string message = string.Format("{0}\n{1}\n{2}\nclient_credentials\n", clientId, timestamp, nonce);

            using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(ConfigurationManager.AppSettings[AmexConstants.AmexOAuthClientSecret])))
            {
                string mac = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(message)));
                // Format -> MAC id="client_id",ts="timestamp",nonce="timestamp:AMEX",mac="HMACSHA256 hash"
                string authenticationHeader = string.Format("MAC id=\"{0}\",ts=\"{1}\",nonce=\"{2}\",mac=\"{3}\"", clientId, timestamp, nonce, mac);

                Stopwatch timer = Stopwatch.StartNew();
                try
                {
                    using (HttpClient httpClient = new HttpClient())
                    {
                        httpClient.DefaultRequestHeaders.Accept.Clear();
                        httpClient.DefaultRequestHeaders.Add("Authentication", authenticationHeader);
                        httpClient.DefaultRequestHeaders.Add("X-AMEX-API-KEY", clientId);
                        HttpContent httpContent = new StringContent("grant_type=client_credentials&app_spec_info=Apigee&guid_type=privateguid");
                        httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
                        HttpResponseMessage response = await httpClient
                                                       .PostAsync(ConfigurationManager.AppSettings[AmexConstants.AmexOAuthUri], httpContent)
                                                       .ConfigureAwait(false);

                        string content = await response.Content.ReadAsStringAsync();

                        if (response.IsSuccessStatusCode)
                        {
                            CommerceLog.Verbose("Received Amex OAuth token. \r\nContent: {0}", content);
                            return(JsonConvert.DeserializeObject <AmexOAuthResponse>(content));
                        }
                        else
                        {
                            CommerceLog.Critical("Unable to get Amex OAuth token. \r\nStatus: {0} \r\nContent: {1}", null, response.StatusCode, content);
                        }
                    }
                }
                finally
                {
                    timer.Stop();
                    PerformanceInformation.Add("Amex OAuth API", string.Format("{0} ms", timer.ElapsedMilliseconds));
                }
            }

            return(null);
        }
Пример #11
0
        /// <summary>
        /// When the worker role starts, we do the following:
        /// 1. Initialize Logger to be used
        /// 2. Schedule Extract Processing job on startup if configured for.
        /// 3. Schedule Ping Job
        /// </summary>
        /// <remarks>
        /// If we schedule Extract Processing job at the same time everyday, we might get
        /// duplicate jobs to execute at the same time (which might be a problem when we have
        /// more than one instance of the role). We can revisit this later, but for now we will
        /// schedule it at the start.
        /// </remarks>
        /// <returns>
        /// boolean status about startup
        /// </returns>
        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections
            ServicePointManager.DefaultConnectionLimit = 100 * Environment.ProcessorCount;

            // Use only for debugging
            // TelemetryConfiguration.Active.TelemetryChannel.DeveloperMode = true;
            //TelemetryConfiguration.Active.InstrumentationKey = CloudConfigurationManager.GetSetting("APPINSIGHTS_INSTRUMENTATIONKEY");

            // Create a CommerceLog instance to funnel log entries to the log.
            LogInitializer.CreateLogInstance(CommerceWorkerConfig.Instance.LogVerbosity,
                                             CommerceWorkerConfig.Instance.ForceEventLog, CommerceLogSource,
                                             CommerceWorkerConfig.Instance);
            Log = new CommerceLog(Guid.NewGuid(), CommerceWorkerConfig.Instance.LogVerbosity, CommerceLogSource);
            ConfigChangeHandler = new ConfigChangeHandler(Log, ExemptConfigurationItems);

            // turn off processing jobs at start
            ProcessJobs = Convert.ToBoolean(CloudConfigurationManager.GetSetting(ProcessJobsPropertyKey));
            // role should not exit even after processing jobs stop
            ExitRole = false;

            // event handlers
            RoleEnvironment.Changing += RoleEnvironmentChanging;
            RoleEnvironment.Changed  += RoleEnvironmentChanged;

            if (!string.IsNullOrEmpty(ConcurrencyMonitorConnectionString))
            {
                Log.Verbose("Initializing Jobs.");
                using (ConcurrencyMonitor monitor = new ConcurrencyMonitor(ConcurrencyMonitorConnectionString))
                {
                    monitor.InvokeWithLease(() => PartnerJobInitializer.InitializeJobs(Scheduler));
                }
                Log.Verbose("Initialized Jobs.");
            }

            return(base.OnStart());
        }