public async Task AddPayment(T model, CancellationToken cancellationToken)
        {
            logger.LogDebug($"Adding object: {Describe(model)} Transaction: {transactionProvider.Current.TransactionId}");
            await queue.EnqueueAsync(transactionProvider.Current, model, cancellationToken);

            logger.LogDebug($"Object {Describe(model)} of type {typeof(T)} added to cache. Transaction {transactionProvider.Current.TransactionId}.");
        }
示例#2
0
        public async Task Handle(IdentifiedRemovedLearningAim message, IMessageHandlerContext context)
        {
            logger.LogDebug($"Processing 'IdentifiedRemovedLearningAim' message.");
            ((ExecutionContext)executionContext).JobId = message.JobId.ToString();

            var key = apprenticeshipKeyService.GenerateApprenticeshipKey(
                message.Ukprn,
                message.Learner.ReferenceNumber,
                message.LearningAim.FrameworkCode,
                message.LearningAim.PathwayCode,
                message.LearningAim.ProgrammeType,
                message.LearningAim.StandardCode,
                message.LearningAim.Reference,
                message.CollectionPeriod.AcademicYear,
                message.ContractType);

            var actorId = new ActorId(key);
            var actor   = proxyFactory.CreateActorProxy <IRequiredPaymentsService>(new Uri("fabric:/SFA.DAS.Payments.RequiredPayments.ServiceFabric/RequiredPaymentsServiceActorService"), actorId);
            IReadOnlyCollection <PeriodisedRequiredPaymentEvent> requiredPayments = await actor.RefundRemovedLearningAim(message, CancellationToken.None).ConfigureAwait(false);

            logger.LogDebug($"Got {requiredPayments?.Count ?? 0} required payments.");
            if (requiredPayments != null)
            {
                await Task.WhenAll(requiredPayments.Select(context.Publish)).ConfigureAwait(false);
            }
            logger.LogInfo($"Successfully processed IdentifiedRemovedLearningAim event for Actor Id {actorId}");
        }
示例#3
0
        public async Task Handle(PeriodEndStoppedEvent message, IMessageHandlerContext context)
        {
            logger.LogInfo($"Processing Month End Event for Message Id : {context.MessageId}");

            await context.SendLocal(new ProcessMonthEndAct1CompletionPaymentCommand { CollectionPeriod = message.CollectionPeriod }).ConfigureAwait(false);

            var currentExecutionContext = (ESFA.DC.Logging.ExecutionContext)executionContext;

            currentExecutionContext.JobId = message.JobId.ToString();

            logger.LogDebug($"Processing period end event. Collection: {message.CollectionPeriod.Period:00}-{message.CollectionPeriod.AcademicYear}, job: {message.JobId}");
            var commands = await periodEndService.GenerateProviderMonthEndCommands(message).ConfigureAwait(false);

            if (!commands.Any())
            {
                logger.LogWarning($"No Provider Ukprn found for period end payment {message.CollectionPeriod.Period:00}-{message.CollectionPeriod.AcademicYear}, job: {message.JobId}");
                return;
            }

            foreach (var command in commands)
            {
                logger.LogDebug($"Sending month end command for provider: {command.Ukprn}");
                await context.SendLocal(command).ConfigureAwait(false);
            }

            logger.LogInfo($"Successfully processed Period End Event for {message.CollectionPeriod.Period:00}-{message.CollectionPeriod.AcademicYear}, job: {message.JobId}");
        }
示例#4
0
        public async Task RecordNewJob(RecordEarningsJob earningsJobRequest, CancellationToken cancellationToken = default(CancellationToken))
        {
            logger.LogDebug($"Now recording new provider earnings job.  Job Id: {earningsJobRequest.JobId}, Ukprn: {earningsJobRequest.Ukprn}.");
            var jobDetails = new JobModel
            {
                JobType           = JobType.EarningsJob,
                StartTime         = earningsJobRequest.StartTime,
                CollectionPeriod  = earningsJobRequest.CollectionPeriod,
                AcademicYear      = earningsJobRequest.CollectionYear,
                Ukprn             = earningsJobRequest.Ukprn,
                DcJobId           = earningsJobRequest.JobId,
                IlrSubmissionTime = earningsJobRequest.IlrSubmissionTime,
                Status            = JobStatus.InProgress,
                LearnerCount      = earningsJobRequest.LearnerCount
            };
            var isNewJob = await jobStorageService.StoreNewJob(jobDetails, CancellationToken.None);

            logger.LogDebug($"Finished storing new job: {jobDetails.Id} for dc job id: {jobDetails.DcJobId}, Ukprn: {earningsJobRequest.Ukprn}. Now storing the job messages.");
            await RecordJobInProgressMessages(earningsJobRequest.JobId, earningsJobRequest.GeneratedMessages, cancellationToken).ConfigureAwait(false);

            logger.LogDebug($"Finished storing new job messages for job: {jobDetails.Id} for dc job id: {jobDetails.DcJobId}, Ukprn: {earningsJobRequest.Ukprn}.");
            if (isNewJob)
            {
                SendTelemetry(earningsJobRequest, jobDetails);
            }
            logger.LogInfo($"Finished saving the job info.  DC Job Id: {earningsJobRequest.JobId}, Ukprn: {earningsJobRequest.Ukprn}.");
        }
        public async Task HandleEmployerProviderPriorityChange(EmployerChangedProviderPriority message)
        {
            try
            {
                using (var operation =
                           telemetry.StartOperation("LevyFundedService.HandleEmployerProviderPriorityChange",
                                                    message.EventId.ToString()))
                {
                    var stopwatch = Stopwatch.StartNew();
                    paymentLogger.LogDebug(
                        $"Storing EmployerChangedProviderPriority event for {Id},  Account Id: {message.EmployerAccountId}");
                    await employerProviderPriorityStorageService.StoreEmployerProviderPriority(message)
                    .ConfigureAwait(false);

                    paymentLogger.LogInfo(
                        $"Finished Storing EmployerChangedProviderPriority event for {Id},  Account Id: {message.EmployerAccountId}");
                    TrackInfrastructureEvent("LevyFundedService.HandleEmployerProviderPriorityChange", stopwatch);
                    telemetry.StopOperation(operation);
                }
            }
            catch (Exception ex)
            {
                paymentLogger.LogError(
                    $"Error while handling EmployerChangedProviderPriority event for {Id},  Account Id: {message.EmployerAccountId} Error:{ex.Message}",
                    ex);
                throw;
            }
        }
 public Task Begin()
 {
     logger.LogVerbose($"Creating state manager transaction.");
     ((ReliableStateManagerTransactionProvider)reliableStateManagerTransactionProvider).Current = stateManager.CreateTransaction();
     logger.LogDebug($"Creating state manager transaction.Transaction Id: {reliableStateManagerTransactionProvider.Current.TransactionId}");
     return(Task.CompletedTask);
 }
示例#7
0
        public async Task Handle(ApprenticeshipContractType1EarningEvent message, IMessageHandlerContext context)
        {
            if (message.Learner == null || message.Learner?.Uln == 0)
            {
                throw new InvalidOperationException("Invalid 'ApprenticeshipContractType1EarningEvent' received. Learner was null or Uln was 0.");
            }
            var uln        = message.Learner.Uln;
            var learnerRef = message.Learner.ReferenceNumber;

            logger.LogDebug($"Processing DataLockProxyProxyService event for learner with learner ref {learnerRef}");
            var actorId = new ActorId(uln.ToString());

            logger.LogVerbose($"Creating actor proxy for learner with learner ref {learnerRef}");
            var actor = proxyFactory.CreateActorProxy <IDataLockService>(new Uri("fabric:/SFA.DAS.Payments.DataLocks.ServiceFabric/DataLockServiceActorService"), actorId);

            logger.LogDebug($"Actor proxy created for learner with " +
                            $"JobId: {message.JobId} and LearnRefNumber: {learnerRef}");

            logger.LogVerbose($"Calling actor proxy to handle earning for learner with learner ref {learnerRef}");
            var dataLockEvents = await actor.HandleEarning(message, CancellationToken.None).ConfigureAwait(false);

            logger.LogDebug($"Earning handled for learner with learner ref {learnerRef}");

            if (dataLockEvents != null)
            {
                var summary = string.Join(", ", dataLockEvents.GroupBy(e => e.GetType().Name).Select(g => $"{g.Key}: {g.Count()}"));
                logger.LogVerbose($"Publishing data lock event for learner with learner ref {learnerRef}: {summary}");
                await Task.WhenAll(dataLockEvents.Select(context.Publish)).ConfigureAwait(false);

                logger.LogDebug($"Data lock event published for learner with learner ref {learnerRef}");
            }

            logger.LogInfo($"Successfully processed DataLockProxyProxyService event for Actor for learner {learnerRef}");
        }
示例#8
0
        public async Task RunAsync(CancellationToken cancellationToken)
        {
            var initialised = false;

            try
            {
                logger.LogDebug("Starting the Job Context Manager service.");
                jobContextManager.OpenAsync(cancellationToken);
                initialised = true;
                logger.LogInfo("Started the Job Context Manager service.");
                await Task.Delay(Timeout.Infinite, cancellationToken);
            }
            catch (Exception exception) when(!(exception is TaskCanceledException))
            {
                logger.LogError($"Error running DC job context manager. Error: {exception.Message}.", exception);
                throw;
            }
            finally
            {
                if (initialised)
                {
                    logger.LogDebug("Closing the job context manager.");
                    await jobContextManager.CloseAsync();

                    logger.LogInfo("Closed job context manager.");
                }
            }
        }
        public async Task <ReadOnlyCollection <PeriodisedRequiredPaymentEvent> > RefundLearningAim(IdentifiedRemovedLearningAim identifiedRemovedLearningAim, IDataCache <PaymentHistoryEntity[]> paymentHistoryCache, CancellationToken cancellationToken)
        {
            logger.LogDebug($"Now processing request to generate refunds for learning aim: learner: {identifiedRemovedLearningAim.Learner.ReferenceNumber}, Aim: {identifiedRemovedLearningAim.LearningAim.Reference}");
            if (await duplicateEarningEventService.IsDuplicate(identifiedRemovedLearningAim, cancellationToken))
            {
                logger.LogWarning($"Duplicate Identified Removed Learning Aim found for learner with JobId: {identifiedRemovedLearningAim.JobId}, " +
                                  $"Learner Ref Number: {identifiedRemovedLearningAim.Learner.ReferenceNumber}, Aim: {identifiedRemovedLearningAim.LearningAim.Reference}");
                return(new List <PeriodisedRequiredPaymentEvent>().AsReadOnly());
            }

            var cacheItem = await paymentHistoryCache.TryGet(CacheKeys.PaymentHistoryKey, cancellationToken)
                            .ConfigureAwait(false);

            if (!cacheItem.HasValue)
            {
                throw new InvalidOperationException("No payment history found in the cache.");
            }

            var historicPayments = cacheItem.Value.Select(mapper.Map <PaymentHistoryEntity, Payment>).ToList();

            logger.LogDebug($"Got {historicPayments.Count} historic payments. Now generating refunds per transaction type.");

            var requiredPaymentEvents = historicPayments.GroupBy(historicPayment => historicPayment.TransactionType)
                                        .SelectMany(group => CreateRefundPayments(identifiedRemovedLearningAim, group.ToList(), group.Key, cacheItem))
                                        .ToList();

            return(requiredPaymentEvents.AsReadOnly());
        }
示例#10
0
        public async Task BuildMetrics(long ukprn, long jobId, short academicYear, byte collectionPeriod, CancellationToken cancellationToken)
        {
            try
            {
                logger.LogDebug($"Building metrics for job: {jobId}, provider: {ukprn}, Academic year: {academicYear}, Collection period: {collectionPeriod}");
                var stopwatch         = Stopwatch.StartNew();
                var submissionSummary = submissionSummaryFactory.Create(ukprn, jobId, academicYear, collectionPeriod);
                var dcEarningsTask    = dcMetricsDataContextFactory.CreateContext(academicYear).GetEarnings(ukprn, academicYear, collectionPeriod, cancellationToken);

                var dasEarningsTask               = submissionRepository.GetDasEarnings(ukprn, jobId, cancellationToken);
                var dataLocksTask                 = submissionRepository.GetDataLockedEarnings(ukprn, jobId, cancellationToken);
                var dataLocksTotalTask            = submissionRepository.GetDataLockedEarningsTotal(ukprn, jobId, cancellationToken);
                var dataLocksAlreadyPaid          = submissionRepository.GetAlreadyPaidDataLockedEarnings(ukprn, jobId, cancellationToken);
                var requiredPaymentsTask          = submissionRepository.GetRequiredPayments(ukprn, jobId, cancellationToken);
                var heldBackCompletionAmountsTask = submissionRepository.GetHeldBackCompletionPaymentsTotal(ukprn, jobId, cancellationToken);
                var yearToDateAmountsTask         = submissionRepository.GetYearToDatePaymentsTotal(ukprn, academicYear, collectionPeriod, cancellationToken);

                var dataTask = Task.WhenAll(dcEarningsTask, dasEarningsTask, dataLocksTask, dataLocksTotalTask, dataLocksAlreadyPaid, requiredPaymentsTask, heldBackCompletionAmountsTask, yearToDateAmountsTask);

                var waitTask = Task.Delay(TimeSpan.FromSeconds(270), cancellationToken);

                Task.WaitAny(dataTask, waitTask);

                cancellationToken.ThrowIfCancellationRequested();

                if (!dataTask.IsCompleted)
                {
                    throw new InvalidOperationException($"Took too long to get data for the submission metrics. Ukprn: {ukprn}, job: {jobId}, Collection period: {collectionPeriod}");
                }

                var dataDuration = stopwatch.ElapsedMilliseconds;

                logger.LogDebug($"finished getting data from databases for job: {jobId}, ukprn: {ukprn}. Took: {dataDuration}ms.");

                submissionSummary.AddEarnings(dcEarningsTask.Result, dasEarningsTask.Result);
                submissionSummary.AddDataLockTypeCounts(dataLocksTotalTask.Result, dataLocksTask.Result, dataLocksAlreadyPaid.Result);
                submissionSummary.AddRequiredPayments(requiredPaymentsTask.Result);
                submissionSummary.AddHeldBackCompletionPayments(heldBackCompletionAmountsTask.Result);
                submissionSummary.AddYearToDatePaymentTotals(yearToDateAmountsTask.Result);

                var metrics = submissionSummary.GetMetrics();

                await submissionRepository.SaveSubmissionMetrics(metrics, cancellationToken);

                stopwatch.Stop();

                SendMetricsTelemetry(metrics, stopwatch.ElapsedMilliseconds);

                logger.LogInfo($"Finished building metrics for submission job: {jobId}, provider: {ukprn}, Academic year: {academicYear}, Collection period: {collectionPeriod}. Took: {stopwatch.ElapsedMilliseconds}ms");
            }
            catch (Exception e)
            {
                logger.LogWarning($"Error building the submission metrics report for job: {jobId}, ukprn: {ukprn}. Error: {e}");
                throw;
            }
        }
示例#11
0
        public async Task Handle(T message, IMessageHandlerContext context)
        {
            var messageType = message.GetType().Name;

            paymentLogger.LogDebug($"Processing {messageType} for Message Id : {context.MessageId}");

            await HandleSubmission(message, submissionService);

            paymentLogger.LogDebug($"Finished processing {messageType} for Message Id : {context.MessageId}. ");
        }
        public async Task Validate()
        {
            var combinedLevyAccountBalance = await GetLevyAccountDetails();

            paymentLogger.LogDebug("Started Validating Employer Accounts");

            await validator.ValidateAsync(combinedLevyAccountBalance);

            paymentLogger.LogInfo("Finished Validating Employer Accounts");
        }
        public async Task Handle(IList <Act1FunctionalSkillEarningsEvent> messages, CancellationToken cancellationToken)
        {
            logger.LogDebug($"Handling ACT1 Functional Skill Earnings Event for Job(s): { string.Join(",", messages.Select(x => x.JobId).Distinct().ToArray()) }");
            var earningEvents = new List <EarningEvent>();

            earningEvents.AddRange(messages);
            await storageService.StoreEarnings(earningEvents, cancellationToken).ConfigureAwait(false);

            logger.LogDebug($"Finished Handling ACT1 Functional Skill Earnings Event for Job(s): { string.Join(",", messages.Select(x => x.JobId).Distinct().ToArray()) }");
        }
示例#14
0
        public async Task StartMonthEnd(long ukprn, short academicYear, byte collectionPeriod, long monthEndJobId)
        {
            logger.LogVerbose($"Recoding month end in the cache. Ukprn: {ukprn}, academic year: {academicYear}, collection period: {collectionPeriod}, Month End Job Id {monthEndJobId}");
            await monthEndCache.AddOrReplace(ukprn, academicYear, collectionPeriod, monthEndJobId).ConfigureAwait(false);

            logger.LogDebug($"Recoded month end in the cache. Ukprn: {ukprn}, academic year: {academicYear}, collection period: {collectionPeriod} , Month End Job Id {monthEndJobId}");

            logger.LogVerbose($"Flushing model cache. Ukprn: {ukprn}, academic year: {academicYear}, collection period: {collectionPeriod}, Month End Job Id {monthEndJobId}");
            await batchService.StorePayments(CancellationToken.None);

            logger.LogDebug($"Model cache flushed. Ukprn: {ukprn}, academic year: {academicYear}, collection period: {collectionPeriod} , Month End Job Id {monthEndJobId}");
        }
        public async Task SubmissionFinished(bool succeeded, long jobId, long ukprn, short academicYear, byte collectionPeriod, DateTime ilrSubmissionTime)
        {
            var submissionJobFinished = succeeded ? (SubmissionJobFinishedEvent) new SubmissionJobSucceeded() : new SubmissionJobFailed();

            submissionJobFinished.JobId                 = jobId;
            submissionJobFinished.CollectionPeriod      = collectionPeriod;
            submissionJobFinished.Ukprn                 = ukprn;
            submissionJobFinished.AcademicYear          = academicYear;
            submissionJobFinished.IlrSubmissionDateTime = ilrSubmissionTime;
            logger.LogDebug($"Publishing {submissionJobFinished.GetType().Name} event. Event: {submissionJobFinished.ToJson()}");
            var endpointInstance = await factory.GetEndpointInstance();

            await endpointInstance.Publish(submissionJobFinished).ConfigureAwait(false);
        }
示例#16
0
        public async Task Remove(long ukprn)
        {
            logger.LogDebug($"Removing UKPRN from ProviderRequiringReprocessing for ukprn: {ukprn}");
            var record = await dataContext.ProvidersRequiringReprocessing
                         .FirstOrDefaultAsync(x => x.Ukprn == ukprn);

            if (record != null)
            {
                dataContext.ProvidersRequiringReprocessing.Remove(record);
            }
            await dataContext.SaveChangesAsync();

            logger.LogInfo($"Removed UKPRN from ProviderRequiringReprocessing for ukprn: {ukprn}");
        }
示例#17
0
        public async Task RemovePreviousSubmissions(long commandJobId, byte collectionPeriod, short academicYear,
                                                    DateTime commandSubmissionDate, long ukprn)
        {
            logger.LogDebug($"Removing previous submissions for job id {commandJobId}, " +
                            $"collection period {collectionPeriod}, " +
                            $"academic year {academicYear}, " +
                            $"submission date {commandSubmissionDate}, " +
                            $"ukprn {ukprn}");

            await dataContext.DeletePreviousSubmissions(commandJobId, collectionPeriod, academicYear,
                                                        commandSubmissionDate, ukprn);

            logger.LogInfo("Finished removing previous submission payments.");
        }
        public async Task <bool> WaitForJobToFinish(long jobId, CancellationToken cancellationToken)
        {
            //TODO: Temp brittle solution to wait for jobs to finish
            logger.LogDebug($"Waiting for job {jobId} to finish.");
            var endTime = DateTime.Now.Add(config.TimeToWaitForJobToComplete);

            while (DateTime.Now < endTime)
            {
                cancellationToken.ThrowIfCancellationRequested();
                var job = await dataContext.GetJobByDcJobId(jobId).ConfigureAwait(false);

                if (job != null && (job.DataLocksCompletionTime != null ||
                                    job.Status != Monitoring.Jobs.Model.JobStatus.InProgress))
                {
                    logger.LogInfo($"DC Job {jobId} finished. Status: {job.Status:G}.  Finish time: {job.EndTime:G}");
                    return(true);
                }
                logger.LogVerbose($"DC Job {jobId} is still in progress");
                await Task.Delay(config.TimeToPauseBetweenChecks);

                continue;
            }
            logger.LogWarning($"Waiting {config.TimeToWaitForJobToComplete} but Job {jobId} still not finished.");
            return(false);
        }
        public async Task Handle(ReceivedProviderEarningsEvent message, CancellationToken cancellationToken)
        {
            logger.LogVerbose($"Handling ILR Submissions. Data: {message.ToJson()}");
            var currentIlr = await GetCurrentIlrSubmissionEvent(message.Ukprn, cancellationToken);

            var isNewIlrSubmission = validateIlrSubmission.IsNewIlrSubmission(new IlrSubmissionValidationRequest
            {
                IncomingPaymentUkprn          = message.Ukprn,
                IncomingPaymentSubmissionDate = message.IlrSubmissionDateTime,
                CurrentIlr = currentIlr
            });

            if (!isNewIlrSubmission)
            {
                logger.LogInfo($"Ignored same Ilr Submission Data for Ukprn {message.Ukprn} and Job Id {message.JobId} Submission already processed");
                return;
            }

            logger.LogInfo($"Updating current Ilr Submission Data for Ukprn {message.Ukprn} and Job Id {message.JobId}");

            await ilrSubmittedEventCache.Clear(message.Ukprn.ToString(), cancellationToken);

            await ilrSubmittedEventCache.Add(message.Ukprn.ToString(), message, cancellationToken);

            logger.LogDebug($"Successfully Updated current Ilr Submission Data for Ukprn {message.Ukprn} and Job Id {message.JobId}");

            await providerPaymentsRepository.DeleteOldMonthEndPayment(message.CollectionPeriod,
                                                                      message.Ukprn,
                                                                      message.IlrSubmissionDateTime,
                                                                      cancellationToken);

            logger.LogInfo($"Successfully Deleted Old Month End Payment for Ukprn {message.Ukprn} and Job Id {message.JobId}");
        }
        public async Task Handle(ApprenticeshipUpdated message, IMessageHandlerContext context)
        {
            logger.LogDebug($"Apprenticeship Updated. Ensuring Ukprn: {message.Ukprn} exists on the list for reprocessing");
            await repository.Add(message.Ukprn);

            logger.LogInfo($"Apprenticeship Updated. Finished ensuring that Ukprn: {message.Ukprn} exists on the list for reprocessing");
        }
示例#21
0
        protected async Task HandleBulkCopy(CancellationToken cancellationToken, List <TEntity> list, SqlBulkCopy bulkCopy)
        {
            using (var reader = ObjectReader.Create(list))
            {
                foreach (var columnMap in bulkCopyConfig.Columns)
                {
                    bulkCopy.ColumnMappings.Add(columnMap.Key, columnMap.Value);
                }

                bulkCopy.BulkCopyTimeout      = 0;
                bulkCopy.BatchSize            = batchSize;
                bulkCopy.DestinationTableName = bulkCopyConfig.TableName;

                try
                {
                    await bulkCopy.WriteToServerAsync(reader, cancellationToken).ConfigureAwait(false);
                }
                catch (SystemException)
                {
                    logger.LogWarning("Error bulk writing to server. Processing single records.");
                    await TrySingleRecord(bulkCopy, list, cancellationToken);
                }
            }

            logger.LogDebug($"Saved {list.Count} records of type {typeof(TEntity).Name}");
        }
 private void LogSql(string sql)
 {
     if (sql.StartsWith("Executing DbCommand"))
     {
         logger.LogDebug($"Sql: {sql}");
     }
 }
示例#23
0
        public async Task Handle(FoundLevyPayerEmployerAccount message, IMessageHandlerContext context)
        {
            paymentLogger.LogDebug($"Handling Found LevyPayer Employer Account Id: {message.AccountId}");
            await apprenticeshipProcessor.ProcessIsLevyPayerFlagForEmployer(message.AccountId, true).ConfigureAwait(false);

            paymentLogger.LogInfo($"Finished Handling Found LevyPayer Employer Account Id: {message.AccountId}");
        }
示例#24
0
        public async Task <bool> StoreNewJob(JobModel job, CancellationToken cancellationToken)
        {
            if (!job.DcJobId.HasValue)
            {
                throw new InvalidOperationException($"No dc job id specified for the job. Job type: {job.JobType:G}");
            }
            cancellationToken.ThrowIfCancellationRequested();
            var jobCache = await GetJobCollection();

            var cachedJob = await jobCache.TryGetValueAsync(reliableTransactionProvider.Current, job.DcJobId.Value, TransactionTimeout, cancellationToken).ConfigureAwait(false);

            if (cachedJob.HasValue)
            {
                logger.LogDebug($"Job has already been stored.");
                return(false);
            }

            await jobCache.AddOrUpdateAsync(reliableTransactionProvider.Current, job.DcJobId.Value,
                                            id => job, (id, existingJob) => job, TransactionTimeout, cancellationToken)
            .ConfigureAwait(false);

            if (job.Id == 0)
            {
                await dataContext.SaveNewJob(job, cancellationToken).ConfigureAwait(false);
            }
            return(true);
        }
        public async Task <IEndpointInstance> GetEndpointInstanceAsync()
        {
            try
            {
                if (endpointInstance != null)
                {
                    return(endpointInstance);
                }

                logger.LogDebug($"Opening endpoint: {config.EndpointName}");

                var endpointConfiguration = CreateEndpointConfiguration();

                endpointInstance = await Endpoint.Start(endpointConfiguration).ConfigureAwait(false);

                logger.LogInfo($"Finished opening endpoint listener: {config.EndpointName}");

                return(endpointInstance);
            }
            catch (Exception e)
            {
                logger.LogFatal($"Cannot start the endpoint: '{config.EndpointName}'.  Error: {e.Message}", e);
                throw;
            }
        }
示例#26
0
        public async Task ProcessedJobMessage(long jobId, Guid messageId, string messageName, List <GeneratedMessage> generatedMessages)
        {
            try
            {
                logger.LogVerbose($"Sending request to record successful processing of event. Job Id: {jobId}, Event: id: {messageId} ");
                var itemProcessedEvent = new RecordJobMessageProcessingStatus
                {
                    JobId             = jobId,
                    Id                = messageId,
                    MessageName       = messageName,
                    EndTime           = DateTimeOffset.UtcNow,
                    GeneratedMessages = generatedMessages ?? new List <GeneratedMessage>(),
                    Succeeded         = true,
                };

                var partitionedEndpointName = config.GetMonitoringEndpointName(jobId);
                await messageSession.Send(partitionedEndpointName, itemProcessedEvent).ConfigureAwait(false);

                logger.LogDebug($"Sent request to record successful processing of event. Job Id: {jobId}, Event: id: {messageId} ");
            }
            catch (Exception ex)
            {
                logger.LogWarning($"Failed to send the job status message. Job: {jobId}, Message: {messageId}, {messageName}, Error: {ex.Message}, {ex}");
            }
        }
示例#27
0
        public async Task StoreLevyTransactions(IList <CalculatedRequiredLevyAmount> calculatedRequiredLevyAmounts, CancellationToken cancellationToken, bool isReceiverTransferPayment = false)
        {
            logger.LogDebug($"Got {calculatedRequiredLevyAmounts.Count} levy transactions.");

            var models = calculatedRequiredLevyAmounts.Select(levyAmount => new LevyTransactionModel
            {
                CollectionPeriod        = levyAmount.CollectionPeriod.Period,
                AcademicYear            = levyAmount.CollectionPeriod.AcademicYear,
                JobId                   = levyAmount.JobId,
                Ukprn                   = levyAmount.Ukprn,
                Amount                  = levyAmount.AmountDue,
                EarningEventId          = levyAmount.EarningEventId,
                DeliveryPeriod          = levyAmount.DeliveryPeriod,
                AccountId               = levyAmount.AccountId ?? 0,
                RequiredPaymentEventId  = levyAmount.EventId,
                TransferSenderAccountId = levyAmount.TransferSenderAccountId,
                MessagePayload          = levyAmount.ToJson(),
                MessageType             = levyAmount.GetType().FullName,
                IlrSubmissionDateTime   = levyAmount.IlrSubmissionDateTime,
                FundingAccountId        = levyAmount.CalculateFundingAccountId(isReceiverTransferPayment),
            }).ToList();

            cancellationToken.ThrowIfCancellationRequested();

            await dataContext.SaveBatch(models, cancellationToken).ConfigureAwait(false);

            logger.LogInfo($"Saved {calculatedRequiredLevyAmounts.Count} levy transactions to db.");
        }
示例#28
0
        public async Task Handle(SubmissionJobSucceeded message, IMessageHandlerContext context)
        {
            logger.LogDebug($"Handling SubmissionJobSucceeded event for Ukprn: {message.Ukprn}");
            await repository.Remove(message.Ukprn);

            logger.LogInfo($"Finished handling SubmissionJobSucceeded event for Ukprn: {message.Ukprn}");
        }
        public async Task Handle(T message, IMessageHandlerContext context)
        {
            var messageType = message.GetType().Name;

            logger.LogInfo($"Processing {messageType} event. Ukprn: {message.Ukprn}");
            ((ESFA.DC.Logging.ExecutionContext)executionContext).JobId = message.JobId.ToString();

            if (message.Ukprn == 0)
            {
                throw new ArgumentException($"Ukprn cannot be 0. Job Id: {message.JobId}");
            }

            logger.LogDebug($"Getting AccountId for Ukprn: {message.Ukprn}.");
            var accountIds = await repository.GetEmployerAccountsByUkprn(message.Ukprn).ConfigureAwait(false);

            var tasks = new List <Task>();

            foreach (var account in accountIds)
            {
                var accountToUse = levyMessageRoutingService.GetDestinationAccountId(account.Item1, account.Item2);
                tasks.Add(InvokeSubmissionAction(accountToUse, message));
            }

            await Task.WhenAll(tasks).ConfigureAwait(false);

            logger.LogInfo($"Successfully processed {messageType} for Job: {message.JobId}, UKPRN: {message.Ukprn}. Skipped submission removing as no account ID found.");
        }
示例#30
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            var initialised = false;

            try
            {
                logger.LogDebug("Starting the Earning Events service.");
                jobContextManager = lifetimeScope.Resolve <IJobContextManager <JobContextMessage> >();
                jobContextManager.OpenAsync(cancellationToken);
                initialised = true;
                logger.LogInfo("Started the Earning Events service.");
                await Task.Delay(Timeout.Infinite, cancellationToken);
            }
            catch (Exception exception) when(!(exception is TaskCanceledException))
            {
                // Ignore, as an exception is only really thrown on cancellation of the token.
                logger.LogError($"Reference Data Stateless Service Exception. Error: {exception}.", exception);
            }
            finally
            {
                if (initialised)
                {
                    logger.LogInfo("Earning Events Stateless Service End");
                    await jobContextManager.CloseAsync();
                }
            }
        }