public async Task <bool> HandleAsync(JobContextMessage message, CancellationToken cancellationToken) { try { logger.LogDebug("Getting task type from period end message."); var taskType = GetTask(message); logger.LogDebug("Got period end type now create the period end event."); var periodEndEvent = CreatePeriodEndEvent(taskType); logger.LogDebug($"Created period end event. Type: {periodEndEvent.GetType().Name}"); periodEndEvent.JobId = message.JobId; periodEndEvent.CollectionPeriod = new CollectionPeriod { AcademicYear = Convert.ToInt16(GetMessageValue(message, JobContextMessageConstants.KeyValuePairs.CollectionYear)), Period = Convert.ToByte(GetMessageValue(message, JobContextMessageConstants.KeyValuePairs.ReturnPeriod)) }; logger.LogDebug($"Got period end event: {periodEndEvent.ToJson()}"); await RecordPeriodEndJob(taskType, periodEndEvent).ConfigureAwait(false); var endpointInstance = await endpointInstanceFactory.GetEndpointInstance(); await endpointInstance.Publish(periodEndEvent); logger.LogInfo($"Finished publishing the period end event. Name: {periodEndEvent.GetType().Name}, JobId: {periodEndEvent.JobId}, Collection Period: {periodEndEvent.CollectionPeriod.Period}-{periodEndEvent.CollectionPeriod.AcademicYear}."); // TODO: This is a temporary workaround to enable the PeriodEndStart and PeriodEndStop messages to return true as otherwise the service will // TODO: just hang as there is nothing implemented to handle the Start and Stop events and so the job status service will never get a completion and so this will never return true. // PV2-1345 will handle PeriodEndStart // PeriodEndStoppedEvent will be handled by the PeriodEndStoppedEventHandler which in turn is handled by the ProcessProviderMonthEndCommandHandler but we don't want to wait for it if (periodEndEvent is PeriodEndStartedEvent || periodEndEvent is PeriodEndStoppedEvent) { logger.LogDebug("Returning as this is either a PeriodEndStart or PeriodEndStop event"); return(true); } await jobStatusService.WaitForJobToFinish(message.JobId, cancellationToken); return(true); } catch (Exception ex) { logger.LogError($"Failed to process job context message. Message: {message.ToJson()}", ex); throw; } }
public async Task <bool> HandleAsync(JobContextMessage message, CancellationToken cancellationToken) { logger.LogDebug($"Processing Earning Event Service event for Job Id : {message.JobId}"); try { if (await HandleSubmissionEvents(message)) { return(true); } using (var operation = telemetry.StartOperation($"FM36Processing:{message.JobId}")) { var stopwatch = Stopwatch.StartNew(); if (await jobStatusService.JobCurrentlyRunning(message.JobId)) { logger.LogWarning($"Job {message.JobId} is already running."); return(false); } var collectionPeriod = int.Parse(message.KeyValuePairs[JobContextMessageKey.ReturnPeriod].ToString()); var fileName = message.KeyValuePairs[JobContextMessageKey.Filename]?.ToString(); var fm36Output = await GetFm36Global(message, collectionPeriod, cancellationToken) .ConfigureAwait(false); if (fm36Output == null) { return(true); } cancellationToken.ThrowIfCancellationRequested(); await ClearSubmittedLearnerAims(collectionPeriod, fm36Output.Year, message.SubmissionDateTimeUtc, fm36Output.UKPRN, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await ProcessFm36Global(message, collectionPeriod, fm36Output, fileName, cancellationToken) .ConfigureAwait(false); await SendReceivedEarningsEvent(message.JobId, message.SubmissionDateTimeUtc, fm36Output.Year, collectionPeriod, fm36Output.UKPRN).ConfigureAwait(false); stopwatch.Stop(); var duration = stopwatch.ElapsedMilliseconds; telemetry.TrackEvent("Processed ILR Submission", new Dictionary <string, string> { { TelemetryKeys.Count, fm36Output.Learners.Count.ToString() }, { TelemetryKeys.CollectionPeriod, collectionPeriod.ToString() }, { TelemetryKeys.AcademicYear, fm36Output.Year }, { TelemetryKeys.JobId, message.JobId.ToString() }, { TelemetryKeys.Ukprn, fm36Output.UKPRN.ToString() }, }, new Dictionary <string, double> { { TelemetryKeys.Duration, duration }, { TelemetryKeys.Count, fm36Output.Learners.Count }, }); if (cancellationToken.IsCancellationRequested) { logger.LogError($"Job {message.JobId} has been cancelled after job has started processing. Ukprn: {fm36Output.UKPRN}"); return(false); } telemetry.StopOperation(operation); if (fm36Output.Learners.Count == 0) { logger.LogWarning($"Received ILR with 0 FM36 learners. Ukprn: {fm36Output.UKPRN}, job id: {message.JobId}."); return(true); } if (await jobStatusService.WaitForJobToFinish(message.JobId, cancellationToken)) { logger.LogInfo($"Successfully processed ILR Submission. Job Id: {message.JobId}, Ukprn: {fm36Output.UKPRN}, Submission Time: {message.SubmissionDateTimeUtc}"); return(true); } logger.LogError($"Job failed to finished within the allocated time. Job Id: {message.JobId}"); return(false); } } catch (OperationCanceledException) { logger.LogError($"Cancellation token cancelled for job: {message.JobId}"); return(false); } catch (Exception ex) { logger.LogFatal($"Error while handling EarningService event. Error: {ex.Message}", ex); return(false); //TODO: change back to throw when DC code is a little more defensive } }