Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Reporting Service #2218

Merged
merged 1 commit into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions api/net/Areas/Admin/Controllers/ReportController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public async Task<IActionResult> SendToAsync(int id, string to)
var username = User.GetUsername() ?? throw new NotAuthorizedException("Username is missing");
var user = _userService.FindByUsername(username) ?? throw new NotAuthorizedException($"User [{username}] does not exist");

var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, report.Id, new { })
var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, report.Id, JsonDocument.Parse("{}"))
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Needed to change to JsonDocument because it was being used inconsistently with a dynamic object.

{
RequestorId = user.Id,
To = to,
Expand Down Expand Up @@ -245,7 +245,7 @@ public async Task<IActionResult> Publish(int id)
var username = User.GetUsername() ?? throw new NotAuthorizedException("Username is missing");
var user = _userService.FindByUsername(username) ?? throw new NotAuthorizedException($"User [{username}] does not exist");

var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, report.Id, new { })
var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, report.Id, JsonDocument.Parse("{}"))
{
RequestorId = user.Id
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public async Task<IActionResult> Publish(int id, bool resend = false)
instance.Status = new[] { Entities.ReportStatus.Pending, Entities.ReportStatus.Reopen }.Contains(instance.Status) ? Entities.ReportStatus.Submitted : instance.Status;
instance = _reportInstanceService.UpdateAndSave(instance);

var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, instance.ReportId, instance.Id, new { })
var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, instance.ReportId, instance.Id, JsonDocument.Parse("{}"))
{
RequestorId = user.Id,
Resend = resend || instance.Status == ReportStatus.Reopen,
Expand Down
3 changes: 2 additions & 1 deletion api/net/Areas/Editor/Controllers/AVOverviewController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Net;
using System.Net.Mime;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.Annotations;
Expand Down Expand Up @@ -203,7 +204,7 @@ public async Task<IActionResult> Publish(long instanceId)
var username = User.GetUsername() ?? throw new NotAuthorizedException("Username is missing");
var user = _userService.FindByUsername(username) ?? throw new NotAuthorizedException($"User [{username}] does not exist");

var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.AVOverview, 0, instance.Id, new { })
var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.AVOverview, 0, instance.Id, JsonDocument.Parse("{}"))
{
RequestorId = user.Id
};
Expand Down
2 changes: 1 addition & 1 deletion api/net/Areas/Editor/Controllers/ReportController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public async Task<IActionResult> Publish(int id)
var username = User.GetUsername() ?? throw new NotAuthorizedException("Username is missing");
var user = _userService.FindByUsername(username) ?? throw new NotAuthorizedException($"User [{username}] does not exist");

var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, report.Id, new { })
var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, report.Id, JsonDocument.Parse("{}"))
{
RequestorId = user.Id,
SendToSubscribers = true,
Expand Down
4 changes: 2 additions & 2 deletions api/net/Areas/Helpers/ReportHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public async Task<ReportResultModel> GenerateReportAsync(
});

var result = await GenerateReportAsync(model, null, sections, viewOnWebOnly, isPreview);
result.Data = elasticResults;
result.Data = JsonDocument.Parse(JsonSerializer.Serialize(elasticResults));
return result;

throw new NotImplementedException($"Report template type '{model.Template.ReportType.GetName()}' has not been implemented");
Expand Down Expand Up @@ -254,7 +254,7 @@ public async Task<ReportResultModel> GenerateReportAsync(
var template = _overviewTemplateService.FindById(instance.TemplateType) ?? throw new InvalidOperationException($"AV overview template '{instance.TemplateType.GetName()}' not found.");
if (template.Template == null) throw new InvalidOperationException($"Report template '{instance.TemplateType.GetName()}' not found.");
var result = await GenerateReportAsync(new Areas.Services.Models.AVOverview.ReportTemplateModel(template.Template, _serializerOptions), instance, isPreview);
result.Data = instance;
result.Data = JsonDocument.Parse(JsonSerializer.Serialize(instance));
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public async Task<IActionResult> SendToAsync(int id, string to)
var instance = _reportInstanceService.FindById(id) ?? throw new NoContentException("Report does not exist");
if (instance.OwnerId != user.Id) throw new NotAuthorizedException("Not authorized to send this report"); // User does not own the report

var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, instance.ReportId, instance.Id, new { })
var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, instance.ReportId, instance.Id, JsonDocument.Parse("{}"))
{
RequestorId = user.Id,
To = to,
Expand Down Expand Up @@ -247,7 +247,7 @@ public async Task<IActionResult> PublishAsync(int id, bool resend)
instance.Status = new[] { Entities.ReportStatus.Pending, Entities.ReportStatus.Reopen }.Contains(instance.Status) ? Entities.ReportStatus.Submitted : instance.Status;
instance = _reportInstanceService.UpdateAndSave(instance);

var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, instance.ReportId, instance.Id, new { })
var request = new ReportRequestModel(ReportDestination.ReportingService, Entities.ReportType.Content, instance.ReportId, instance.Id, JsonDocument.Parse("{}"))
{
RequestorId = user.Id,
Resend = resend || instance.Status == Entities.ReportStatus.Reopen,
Expand Down
20 changes: 16 additions & 4 deletions libs/net/core/Extensions/JsonElementExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,29 @@ public static string ToJson(this JsonElement element, JsonWriterOptions? options

if (property == null) return defaultValue;
var node = (JsonElement)property;
var type = typeof(T);
return node.ValueKind switch
{
JsonValueKind.String => !typeof(T).IsEnum ?
(T)Convert.ChangeType($"{node.GetString()}".Trim(), typeof(T)) :
(T)Enum.Parse(typeof(T), node.GetString() ?? ""),
JsonValueKind.String => ((Func<T?>)(() =>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed parsing issue with nullable enum values

{
var isNullableEnum = type.IsNullable() && Nullable.GetUnderlyingType(type)?.IsEnum == true;
if (isNullableEnum)
{
var eType = Nullable.GetUnderlyingType(type);
if (eType != null && Enum.TryParse(eType, node.GetString(), true, out var value))
{
return (T)value;
}
return defaultValue;
}
return type.IsEnum ? (T)Enum.Parse(type, node.GetString() ?? "") : (T)Convert.ChangeType($"{node.GetString()}".Trim(), type);
}))(),
JsonValueKind.Null or JsonValueKind.Undefined => defaultValue,
JsonValueKind.Number => node.ConvertNumberTo<T>(),
JsonValueKind.True or JsonValueKind.False => (T)(object)node.GetBoolean(),
JsonValueKind.Object => node.Deserialize<T>(options),
JsonValueKind.Array => node.Deserialize<T>(options),
_ => (T)Convert.ChangeType($"{node}", typeof(T)),
_ => (T)Convert.ChangeType($"{node}", type),
};
}

Expand Down
1 change: 1 addition & 0 deletions libs/net/core/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ public static string Escape(this string value)

/// <summary>
/// Determines if the email address is valid.
/// Regrettably the following email "name@name" is valid, but will fail in most cases.
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
Expand Down
16 changes: 9 additions & 7 deletions libs/net/kafka/Models/ReportRequestModel.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Text.Json;

namespace TNO.Kafka.Models;

/// <summary>
Expand Down Expand Up @@ -37,7 +39,7 @@ public class ReportRequestModel
/// <summary>
/// get/set - JSON object with data to be passed to the report template.
/// </summary>
public dynamic Data { get; set; } = new { };
public JsonDocument Data { get; set; } = JsonDocument.Parse("{}");

/// <summary>
/// get/set - Foreign key to user who requested the report.
Expand Down Expand Up @@ -89,7 +91,7 @@ public ReportRequestModel() { }
/// <param name="type"></param>
/// <param name="reportId"></param>
/// <param name="data"></param>
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, object data)
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, JsonDocument data)
{
this.ReportType = type;
this.Destination = destination;
Expand All @@ -106,7 +108,7 @@ public ReportRequestModel(ReportDestination destination, Entities.ReportType typ
/// <param name="data"></param>
/// <param name="assignedId"></param>
/// <param name="to"></param>
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, object data, int assignedId, string to = "")
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, JsonDocument data, int assignedId, string to = "")
: this(destination, type, reportId, data)
{
this.AssignedId = assignedId;
Expand All @@ -123,7 +125,7 @@ public ReportRequestModel(ReportDestination destination, Entities.ReportType typ
/// <param name="requestorId"></param>
/// <param name="assignedId"></param>
/// <param name="to"></param>
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, object data, int requestorId, int assignedId, string to = "")
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, JsonDocument data, int requestorId, int assignedId, string to = "")
: this(destination, type, reportId, data, assignedId, to)
{
this.RequestorId = requestorId;
Expand All @@ -137,7 +139,7 @@ public ReportRequestModel(ReportDestination destination, Entities.ReportType typ
/// <param name="reportId"></param>
/// <param name="reportInstanceId"></param>
/// <param name="data"></param>
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, long reportInstanceId, object data)
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, long reportInstanceId, JsonDocument data)
: this(destination, type, reportId, data)
{
this.ReportInstanceId = reportInstanceId;
Expand All @@ -153,7 +155,7 @@ public ReportRequestModel(ReportDestination destination, Entities.ReportType typ
/// <param name="data"></param>
/// <param name="assignedId"></param>
/// <param name="to"></param>
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, long reportInstanceId, object data, int assignedId, string to = "")
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, long reportInstanceId, JsonDocument data, int assignedId, string to = "")
: this(destination, type, reportId, reportInstanceId, data)
{
this.AssignedId = assignedId;
Expand All @@ -171,7 +173,7 @@ public ReportRequestModel(ReportDestination destination, Entities.ReportType typ
/// <param name="requestorId"></param>
/// <param name="assignedId"></param>
/// <param name="to"></param>
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, long reportInstanceId, object data, int requestorId, int assignedId, string to = "")
public ReportRequestModel(ReportDestination destination, Entities.ReportType type, int reportId, long reportInstanceId, JsonDocument data, int requestorId, int assignedId, string to = "")
: this(destination, type, reportId, reportInstanceId, data, assignedId, to)
{
this.RequestorId = requestorId;
Expand Down
19 changes: 0 additions & 19 deletions libs/net/models/Areas/Services/Models/Report/UserModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,24 +118,5 @@ public string GetEmail()
{
return String.IsNullOrWhiteSpace(this.PreferredEmail) ? this.Email : this.PreferredEmail;
}

/// <summary>
/// Get the preferred email if it has been set.
/// </summary>
/// <returns></returns>
public string[] GetEmails()
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not needed

{
if (this.AccountType == Entities.UserAccountType.Distribution)
{
var addresses = this.Preferences.GetElementValue<API.Models.UserEmailModel[]?>(".addresses");
if (addresses != null) return addresses.Select(a => a.Email).ToArray();
return Array.Empty<string>();
}
else
{
var email = String.IsNullOrWhiteSpace(this.PreferredEmail) ? this.Email : this.PreferredEmail;
return new string[] { email };
}
}
#endregion
}
8 changes: 4 additions & 4 deletions libs/net/services/Managers/IngestManager`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public override async Task RunAsync()
}
else
{
// Auto-reset time delay hasnt passed yet.
// Auto-reset time delay hasn't passed yet.
this.Logger.LogWarning("Ingest [{name}] has reached maximum failure limit. Auto-reset will occur at [{timestamp}]", ingest.Name, ingest.LastRanOn!.Value.AddMilliseconds(ingest.ResetRetryAfterDelayMs).ToLocalTime());
continue;
}
Expand Down Expand Up @@ -182,7 +182,7 @@ public override async Task RunAsync()
// Reached limit return to ingest manager, send email.
if (manager.Ingest.FailedAttempts >= manager.Ingest.RetryLimit)
{
await this.SendEmailAsync($"Ingest [{ingest.Name}] failed. Reached [{manager.Ingest.RetryLimit}] maximum retries.", ex);
await this.SendErrorEmailAsync($"Ingest [{ingest.Name}] failed. Reached [{manager.Ingest.RetryLimit}] maximum retries.", ex);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Renamed method to make it clear

}
}
catch (Exception ex)
Expand All @@ -195,7 +195,7 @@ public override async Task RunAsync()
// Reached limit return to ingest manager, send email.
if (manager.Ingest.FailedAttempts >= manager.Ingest.RetryLimit)
{
await this.SendEmailAsync($"Ingest ['{ingest.Name}'] failed. Reached [{manager.Ingest.RetryLimit}] maximum retries.", ex);
await this.SendErrorEmailAsync($"Ingest ['{ingest.Name}'] failed. Reached [{manager.Ingest.RetryLimit}] maximum retries.", ex);
}
}
}
Expand Down Expand Up @@ -281,7 +281,7 @@ public virtual async Task<IEnumerable<IngestModel>> GetIngestsAsync()
{
this.Logger.LogError(ex, "Failed to fetch ingests for ingest type '{type}'", ingestType);
this.State.RecordFailure();
await this.SendEmailAsync($"Failed to fetch ingests for ingest type '{ingestType}", ex);
await this.SendErrorEmailAsync($"Failed to fetch ingests for ingest type '{ingestType}", ex);
}
}

Expand Down
2 changes: 1 addition & 1 deletion libs/net/services/Managers/ServiceManager`.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public async Task SendEmailAsync(string subject, string message)
/// <param name="subject"></param>
/// <param name="ex"></param>
/// <returns></returns>
public async Task SendEmailAsync(string subject, Exception ex)
public async Task SendErrorEmailAsync(string subject, Exception ex)
{
string env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production";
string? serviceName = GetType().FullName ?? "Service";
Expand Down
6 changes: 4 additions & 2 deletions libs/net/template/Models/Reports/ReportResultModel.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Text.Json;

namespace TNO.TemplateEngine.Models.Reports;

/// <summary>
Expand Down Expand Up @@ -29,7 +31,7 @@ public class ReportResultModel
/// <summary>
/// get/set - JSON data that was used to generate the report.
/// </summary>
public object? Data { get; set; }
public JsonDocument? Data { get; set; }
#endregion

#region Constructors
Expand All @@ -44,7 +46,7 @@ public ReportResultModel() { }
/// <param name="subject"></param>
/// <param name="body"></param>
/// <param name="data"></param>
public ReportResultModel(Entities.ReportInstance instance, object? data = null)
public ReportResultModel(Entities.ReportInstance instance, JsonDocument? data = null)
{
this.ReportId = instance.ReportId;
this.InstanceId = instance.Id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ data:
CHES_EMAIL_ENABLED: "true"
CHES_EMAIL_AUTHORIZED: "true"
CHARTS_URL: http://charts-api:8080
RESEND_ON_FAILURE: "true"
5 changes: 5 additions & 0 deletions openshift/kustomize/services/reporting/base/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ spec:
configMapKeyRef:
name: reporting-service
key: MAX_FAIL_LIMIT
- name: Service__ResendOnFailure
valueFrom:
configMapKeyRef:
name: reporting-service
key: RESEND_ON_FAILURE
- name: Service__Topics
valueFrom:
configMapKeyRef:
Expand Down
6 changes: 3 additions & 3 deletions services/net/content/ContentManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public override async Task RunAsync()
{
this.Logger.LogError(ex, "Service had an unexpected failure.");
this.State.RecordFailure();
await this.SendEmailAsync("Service had an Unexpected Failure", ex);
await this.SendErrorEmailAsync("Service had an Unexpected Failure", ex);
}
}

Expand Down Expand Up @@ -268,12 +268,12 @@ private async Task HandleMessageAsync(ConsumeResult<string, SourceContent> resul
if (ex is HttpClientRequestException httpEx)
{
this.Logger.LogError(ex, "HTTP exception while consuming. {response}", httpEx.Data["body"] ?? "");
await this.SendEmailAsync("HTTP exception while consuming. {response}", ex);
await this.SendErrorEmailAsync("HTTP exception while consuming. {response}", ex);
}
else
{
this.Logger.LogError(ex, "Failed to handle message");
await this.SendEmailAsync("Failed to handle message", ex);
await this.SendErrorEmailAsync("Failed to handle message", ex);
}
ListenerErrorHandler(this, new ErrorEventArgs(ex));
}
Expand Down
6 changes: 3 additions & 3 deletions services/net/extract-quotes/ExtractQuotesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public override async Task RunAsync()
{
Logger.LogError(ex, "Service had an unexpected failure.");
State.RecordFailure();
await SendEmailAsync("Service had an Unexpected Failure", ex);
await SendErrorEmailAsync("Service had an Unexpected Failure", ex);
}
}

Expand Down Expand Up @@ -235,12 +235,12 @@ private async Task HandleMessageAsync(ConsumeResult<string, IndexRequestModel> r
if (ex is HttpClientRequestException httpEx)
{
Logger.LogError(ex, "HTTP exception while consuming. {response}", httpEx.Data["body"] ?? "");
await SendEmailAsync("HTTP exception while consuming. {response}", ex);
await SendErrorEmailAsync("HTTP exception while consuming. {response}", ex);
}
else
{
Logger.LogError(ex, "Failed to handle message");
await SendEmailAsync("Failed to handle message", ex);
await SendErrorEmailAsync("Failed to handle message", ex);
}
ListenerErrorHandler(this, new ErrorEventArgs(ex));
}
Expand Down
Loading
Loading