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()}"); var jobIdToWaitFor = message.JobId; if (taskType == PeriodEndTaskType.PeriodEndReports) { 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}."); } else if (taskType == PeriodEndTaskType.PeriodEndSubmissionWindowValidation) { 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}."); } else { var existingNonFailedJobId = await jobsDataContext.GetNonFailedDcJobId(GetJobType(taskType), periodEndEvent.CollectionPeriod.AcademicYear, periodEndEvent.CollectionPeriod.Period); if (existingNonFailedJobId.GetValueOrDefault() == 0) { 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}."); } else { jobIdToWaitFor = existingNonFailedJobId.GetValueOrDefault(); logger.LogWarning($"Job already exists, will not be published. 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 PeriodEndStoppedEvent || periodEndEvent is PeriodEndRequestReportsEvent) { logger.LogDebug("Returning as this is either a PeriodEndStop or PeriodEndRequestReports event"); return(true); } if (periodEndEvent is PeriodEndStartedEvent periodEndStartedEvent) { return(await jobStatusService.WaitForPeriodEndStartedToFinish(jobIdToWaitFor, cancellationToken)); } if (periodEndEvent is PeriodEndRequestValidateSubmissionWindowEvent) { return(await jobStatusService.WaitForPeriodEndSubmissionWindowValidationToFinish(jobIdToWaitFor, cancellationToken)); } await jobStatusService.WaitForJobToFinish(jobIdToWaitFor, cancellationToken); return(true); } catch (Exception ex) { logger.LogError($"Failed to process job context message. Message: {message.ToJson()}", ex); throw; } }