Skip to content

LNK-4955: Report Service Bug FIxes#1526

Merged
nvmLantana merged 5 commits intodevfrom
nvm/Report_Data_BugFixes
Mar 31, 2026
Merged

LNK-4955: Report Service Bug FIxes#1526
nvmLantana merged 5 commits intodevfrom
nvm/Report_Data_BugFixes

Conversation

@nvmLantana
Copy link
Copy Markdown
Contributor

@nvmLantana nvmLantana commented Mar 29, 2026

🛠️ Description of Changes

https://lantana.atlassian.net/browse/LNK-4955

This PR applies the Report scheduled-workflow bug fixes and supporting reliability tests.

Quartz Registration

  • Start Quartz scheduler in Report service
  • Added hosted scheduler startup so scheduled Quartz jobs actually run.

UTC-safe scheduling for End of Report Period

  • Normalized ReportEndDate to UTC-kind before creating Quartz trigger.
  • Prevents trigger-time interpretation drift from DateTimeKind.Unspecified.

UTC-safe serialization for Data Acquisition payload dates

  • Normalized ScheduledReports.StartDate / EndDate to UTC-kind before producing DataAcquisitionRequested.
  • Prevents downstream deserialization issues caused by timezone-less serialized dates.

Quartz JobDataMap reliability improvements

  • Reworked PutObject / GetObject behavior for robust JSON + scalar handling (Guid, DateTime, DateTimeOffset, enums, strings).
  • Updated Quartz helper to write job data through extension methods instead of raw JobDataMap constructor.

🧪 Testing Performed

Adhoc End to End
Report Sceduled End to End
In depth data validation.

JobDataMapExtensionsTests

  • Covers null/string/scalar/JSON/enum/date conversion behavior and failure-safe fallbacks.

QuartzJobHelperTests

  • Covers schedule/delete/reschedule behavior, job+trigger identity, job-data roundtrip, and cancellation token propagation.

🧑‍🔬 Unit Testing

  • I have written or updated unit tests to cover my changes
  • Coverage: 0.0%

📓 Documentation Updated

Please update any relevant sections in the project documentation that were impacted by the changes in the PR.

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Report scheduled dates now normalized to UTC to ensure consistent time handling across all services.
  • New Features

    • Introduced retry scheduling service for scheduled reports.
  • Tests

    • Added comprehensive unit test coverage for job scheduling utilities and job data handling.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 29, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8205cba3-10a1-4a72-8f44-220084a41b51

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR normalizes DateTime values to UTC across the Report service's Kafka producers and Quartz schedulers, enhances JobDataMap serialization with improved type handling for Guid, DateTimeOffset, DateTime, and enums, updates Quartz scheduling to use DateTimeOffset, registers a new RetryScheduleService in dependency injection, and excludes the JobStoreFactories directory from the project file.

Changes

Cohort / File(s) Summary
DateTime Normalization to UTC
DotNet/Report/KafkaProducers/DataAcquisitionRequestedProducer.cs, DotNet/Report/Listeners/ReportScheduledListener.cs
Normalizes ReportStartDate and ReportEndDate to UTC before populating Kafka messages and Quartz scheduling triggers, converting DateTime to DateTimeOffset where applicable.
JobDataMap Serialization Enhancements
DotNet/Shared/Application/Extensions/JobDataMapExtensions.cs, DotNet/Shared/Application/Utilities/QuartzJobHelper.cs
Refactors PutObject to support object-based serialization; enhances GetObject to handle Guid, DateTimeOffset, DateTime, and enums; updates QuartzJobHelper to use the improved extension methods for job data population.
Service Registration & Project Configuration
DotNet/Report/Program.cs, DotNet/Report/Report.csproj
Adds RetryScheduleService to hosted services; excludes Jobs\JobStoreFactories\** directory from project compilation and resource groups.
Test Coverage
DotNet/ServiceTests/UnitTests/Shared/JobDataMapExtensionsTests.cs, DotNet/ServiceTests/UnitTests/Shared/QuartzJobHelperTests.cs
Introduces comprehensive unit tests for JobDataMap extension methods (type round-tripping, JSON deserialization, enum parsing) and QuartzJobHelper (job scheduling, deletion, rescheduling logic).

Sequence Diagram

sequenceDiagram
    participant Producer as DataAcquisition<br/>Producer
    participant Kafka as Kafka Topic
    participant Listener as ReportScheduled<br/>Listener
    participant Helper as QuartzJobHelper
    participant JobDataMap as JobDataMap<br/>Extensions
    participant Scheduler as Quartz Scheduler

    Producer->>Producer: Normalize ReportStartDate,<br/>ReportEndDate to UTC
    Producer->>Kafka: Publish ScheduledReport<br/>(UTC dates)
    Listener->>Listener: Receive Message &<br/>Normalize ReportEndDate to UTC
    Listener->>Helper: ScheduleJob with jobData<br/>dictionary
    Helper->>JobDataMap: PutObject for each<br/>key/value pair
    JobDataMap->>JobDataMap: Serialize objects<br/>(Guid, DateTime,<br/>DateTimeOffset, etc.)
    Helper->>Scheduler: Schedule job with<br/>DateTimeOffset trigger
    Scheduler->>Scheduler: Execute at<br/>scheduled UTC time
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

config-change

Suggested reviewers

  • dvargaslantana
  • arianamihailescu
  • edward-miller-lcg

Poem

🐰 A rabbit hops through UTC time zones,
Quartz jobs now dance with robust stones,
JobDataMaps serialize with grace,
Enums and Guids find their place,
Schedules sync at the right embrace! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'LNK-4955: Report Service Bug FIxes' references a ticket and mentions 'Bug Fixes' but lacks specificity about the actual changes—it does not clearly summarize the primary modifications in the changeset. Revise the title to be more specific about the primary changes, such as 'Normalize DateTime handling in Kafka producers and job scheduling' or 'Fix UTC DateTime normalization in report scheduling.'
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The PR description is comprehensive, covering code changes, testing performed, and unit testing details with specific test coverage information.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nvm/Report_Data_BugFixes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
DotNet/Report/KafkaProducers/DataAcquisitionRequestedProducer.cs (1)

76-95: ⚠️ Potential issue | 🟠 Major

Add unit tests and fix the DateTime normalization logic.

Lines 76-82 use DateTime.SpecifyKind() to mark non-UTC dates as UTC instead of properly converting them to UTC. This preserves the wrong instant: if schedule.ReportStartDate is Local, relabeling it as UTC without conversion causes ScheduledReport.StartDate to be serialized with an incorrect instant on the Kafka payload.

Additionally, per coding guidelines, the if/else branches introduced at lines 76-82 must have corresponding XUnit tests to validate both the UTC and non-UTC code paths.

🕒 Suggested fix
-                var reportStartDateUtc = schedule.ReportStartDate.Kind == DateTimeKind.Utc
-                    ? schedule.ReportStartDate
-                    : DateTime.SpecifyKind(schedule.ReportStartDate, DateTimeKind.Utc);
-
-                var reportEndDateUtc = schedule.ReportEndDate.Kind == DateTimeKind.Utc
-                    ? schedule.ReportEndDate
-                    : DateTime.SpecifyKind(schedule.ReportEndDate, DateTimeKind.Utc);
+                static DateTime NormalizeUtc(DateTime value) => value.Kind switch
+                {
+                    DateTimeKind.Utc => value,
+                    DateTimeKind.Local => value.ToUniversalTime(),
+                    _ => DateTime.SpecifyKind(value, DateTimeKind.Utc)
+                };
+
+                var reportStartDateUtc = NormalizeUtc(schedule.ReportStartDate);
+                var reportEndDateUtc = NormalizeUtc(schedule.ReportEndDate);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@DotNet/Report/KafkaProducers/DataAcquisitionRequestedProducer.cs` around
lines 76 - 95, The DateTime normalization in DataAcquisitionRequestedProducer is
wrong: instead of using DateTime.SpecifyKind to relabel non-UTC instants,
convert schedule.ReportStartDate and schedule.ReportEndDate to UTC (e.g., call
ToUniversalTime() or use DateTimeOffset conversion) before assigning
ScheduledReport.StartDate and EndDate so the instant is preserved; update the
logic in the DataAcquisitionRequestedProducer class replacing SpecifyKind
branches with proper UTC conversion and ensure ScheduledReport.StartDate/EndDate
are the converted values. Also add XUnit tests for both code paths: one test
where schedule.ReportStartDate/ReportEndDate already have Kind==Utc and one
where they are Local/Unspecified to verify the produced Kafka payload contains
the correct UTC instants (assert on the serialized
ScheduledReport.StartDate/EndDate or resulting message value). Ensure tests
target the method that builds the darValue (or the producer method that
serializes it) and include clear assertions for expected UTC values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@DotNet/Report/Listeners/ReportScheduledListener.cs`:
- Around line 186-194: The code incorrectly uses DateTime.SpecifyKind for all
cases; change the conversion so that when reportSchedule.ReportEndDate.Kind ==
DateTimeKind.Utc you use the value as-is, when Kind == DateTimeKind.Local
convert with reportSchedule.ReportEndDate.ToUniversalTime(), and when Kind ==
DateTimeKind.Unspecified use DateTime.SpecifyKind(..., DateTimeKind.Utc) to
treat it as UTC; ensure the variable reportEndDateUtc holds the correct UTC
instant and then pass new DateTimeOffset(reportEndDateUtc) into
ScheduleJob<EndOfReportPeriodJob>. Add XUnit tests that exercise ScheduleJob
invocation (or inspect the computed DateTimeOffset) for all three branches (Utc,
Local, Unspecified) to verify the scheduled time is correct.

In `@DotNet/Shared/Application/Extensions/JobDataMapExtensions.cs`:
- Around line 52-57: The current branch in JobDataMapExtensions (checking
targetType == typeof(string)) treats empty/whitespace strings as missing by
using string.IsNullOrWhiteSpace, which drops valid payloads; update the branch
in the PutObject/round-trip logic to preserve raw string values: if storedValue
is string storedString then return storedString (do not treat empty or
whitespace as default/missing). Adjust/remove the string.IsNullOrWhiteSpace
check and ensure other branches (the non-string path that handles
whitespace-as-missing) remain unchanged. Add an xUnit test verifying that empty
("") and whitespace ("   ") strings round-trip correctly through
PutObject/GetObject.

---

Outside diff comments:
In `@DotNet/Report/KafkaProducers/DataAcquisitionRequestedProducer.cs`:
- Around line 76-95: The DateTime normalization in
DataAcquisitionRequestedProducer is wrong: instead of using DateTime.SpecifyKind
to relabel non-UTC instants, convert schedule.ReportStartDate and
schedule.ReportEndDate to UTC (e.g., call ToUniversalTime() or use
DateTimeOffset conversion) before assigning ScheduledReport.StartDate and
EndDate so the instant is preserved; update the logic in the
DataAcquisitionRequestedProducer class replacing SpecifyKind branches with
proper UTC conversion and ensure ScheduledReport.StartDate/EndDate are the
converted values. Also add XUnit tests for both code paths: one test where
schedule.ReportStartDate/ReportEndDate already have Kind==Utc and one where they
are Local/Unspecified to verify the produced Kafka payload contains the correct
UTC instants (assert on the serialized ScheduledReport.StartDate/EndDate or
resulting message value). Ensure tests target the method that builds the
darValue (or the producer method that serializes it) and include clear
assertions for expected UTC values.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 001e79e3-77bb-4baa-9182-49f6d8a7f50c

📥 Commits

Reviewing files that changed from the base of the PR and between 43523aa and d3bcad6.

📒 Files selected for processing (8)
  • DotNet/Report/KafkaProducers/DataAcquisitionRequestedProducer.cs
  • DotNet/Report/Listeners/ReportScheduledListener.cs
  • DotNet/Report/Program.cs
  • DotNet/Report/Report.csproj
  • DotNet/ServiceTests/UnitTests/Shared/JobDataMapExtensionsTests.cs
  • DotNet/ServiceTests/UnitTests/Shared/QuartzJobHelperTests.cs
  • DotNet/Shared/Application/Extensions/JobDataMapExtensions.cs
  • DotNet/Shared/Application/Utilities/QuartzJobHelper.cs

Comment thread DotNet/Report/Listeners/ReportScheduledListener.cs
Comment thread DotNet/Shared/Application/Extensions/JobDataMapExtensions.cs Outdated
@nvmLantana nvmLantana merged commit 0f420f7 into dev Mar 31, 2026
18 checks passed
@nvmLantana nvmLantana deleted the nvm/Report_Data_BugFixes branch March 31, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants