Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public interface IQueryPlanQueries
Task<List<QueryPlanModel>> FindAsync(Expression<Func<QueryPlan, bool>> predicate, CancellationToken cancellationToken = default);
Task<List<string>> GetPlanNamesAsync(string facilityId, CancellationToken cancellationToken = default);
Task<PagedConfigModel<QueryPlanModel>> SearchAsync(SearchQueryPlanModel model, CancellationToken cancellationToken = default);
Task<bool> ExistsAsync(string facilityId, Frequency value, CancellationToken cancellationToken);
}

public class QueryPlanQueries : IQueryPlanQueries
Expand Down Expand Up @@ -131,4 +132,9 @@ private Expression<Func<T, object>> SetSortBy<T>(string? sortBy)
var converted = Expression.Convert(property, typeof(object));
return Expression.Lambda<Func<T, object>>(converted, parameter);
}

public Task<bool> ExistsAsync(string facilityId, Frequency value, CancellationToken cancellationToken)
{
return _dbContext.QueryPlans.AnyAsync(q => q.FacilityId == facilityId && q.Type == value, cancellationToken);
}
Comment thread
nvmLantana marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using LantanaGroup.Link.DataAcquisition.Domain.Infrastructure.Interfaces;
using LantanaGroup.Link.DataAcquisition.Domain.Infrastructure.Models.QueryConfig.Parameter;
using System.Text.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using LantanaGroup.Link.DataAcquisition.Domain.Infrastructure.Interfaces;
using LantanaGroup.Link.DataAcquisition.Domain.Infrastructure.Models.QueryConfig.Parameter;

namespace LantanaGroup.Link.DataAcquisition.Domain.Application.Serializers;

Expand All @@ -11,14 +11,52 @@ public override IParameter Read(ref Utf8JsonReader reader, Type typeToConvert, J
{
using (JsonDocument doc = JsonDocument.ParseValue(ref reader))
{
if (!doc.RootElement.TryGetProperty("ParameterType", out JsonElement typeElement))
JsonElement typeElement;
string configType = null;

if (doc.RootElement.TryGetProperty("ParameterType", out typeElement) ||
doc.RootElement.TryGetProperty("parameterType", out typeElement))
{
configType = typeElement.GetString();
}
else if (doc.RootElement.TryGetProperty("$type", out typeElement))
{
var typeName = typeElement.GetString();
if (typeName?.Contains("LiteralParameter") == true)
{
configType = "Literal";
}
else if (typeName?.Contains("ResourceIdsParameter") == true)
{
configType = "ResourceIds";
}
else if (typeName?.Contains("VariableParameter") == true)
{
configType = "Variable";
}
}

if (configType == null)
{
if (!doc.RootElement.TryGetProperty("parameterType", out typeElement))
// Fallback to property inspection
if (doc.RootElement.TryGetProperty("Literal", out _))
{
throw new JsonException("Missing ParameterType property.");
configType = "Literal";
}
else if (doc.RootElement.TryGetProperty("Resource", out _) && doc.RootElement.TryGetProperty("Paged", out _))
{
configType = "ResourceIds";
}
else if (doc.RootElement.TryGetProperty("Variable", out _))
{
configType = "Variable";
}
else
{
throw new JsonException("Unable to determine ParameterType. Missing type discriminator or distinguishing properties.");
}
}
var configType = typeElement.GetString();

return configType switch
{
"Literal" => JsonSerializer.Deserialize<LiteralParameter>(doc.RootElement.GetRawText(), options),
Expand All @@ -28,6 +66,7 @@ public override IParameter Read(ref Utf8JsonReader reader, Type typeToConvert, J
};
}
}

public override void Write(Utf8JsonWriter writer, IParameter value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, value.GetType(), options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,44 @@ public override IQueryConfig Read(ref Utf8JsonReader reader, Type typeToConvert,
{
using (JsonDocument doc = JsonDocument.ParseValue(ref reader))
{
if (!doc.RootElement.TryGetProperty("QueryConfigType", out JsonElement typeElement))
JsonElement typeElement;
string configType = null;

if (doc.RootElement.TryGetProperty("QueryConfigType", out typeElement) ||
doc.RootElement.TryGetProperty("queryConfigType", out typeElement))
{
configType = typeElement.GetString();
}
else if (doc.RootElement.TryGetProperty("$type", out typeElement))
{
var typeName = typeElement.GetString();
if (typeName?.Contains("ParameterQueryConfig") == true)
{
configType = "Parameter";
}
else if (typeName?.Contains("ReferenceQueryConfig") == true)
{
configType = "Reference";
}
}

if (configType == null)
{
if (!doc.RootElement.TryGetProperty("queryConfigType", out typeElement))
// Fallback to property inspection if no type discriminator is found
if (doc.RootElement.TryGetProperty("Parameters", out _))
{
configType = "Parameter";
}
else if (doc.RootElement.TryGetProperty("Paged", out _))
Comment thread
nvmLantana marked this conversation as resolved.
{
throw new JsonException("Missing QueryConfigType property.");
configType = "Reference";
}
else
{
throw new JsonException("Unable to determine QueryConfigType. Missing type discriminator or distinguishing properties.");
}
}
var configType = typeElement.GetString();

return configType switch
{
"Parameter" => JsonSerializer.Deserialize<ParameterQueryConfig>(doc.RootElement.GetRawText(), options),
Expand All @@ -27,6 +57,7 @@ public override IQueryConfig Read(ref Utf8JsonReader reader, Type typeToConvert,
};
}
}

public override void Write(Utf8JsonWriter writer, IQueryConfig value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, value.GetType(), options);
Expand Down
16 changes: 9 additions & 7 deletions DotNet/DataAcquisition/Controllers/QueryPlanConfigController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using DataAcquisition.Domain.Application.Models;
using DataAcquisition.Domain.Application.Models.Exceptions;
using Hl7.Fhir.Model;
using LantanaGroup.Link.DataAcquisition.Domain.Application.Managers;
using LantanaGroup.Link.DataAcquisition.Domain.Application.Models;
using LantanaGroup.Link.DataAcquisition.Domain.Application.Models.Exceptions;
Expand Down Expand Up @@ -139,9 +140,9 @@ public async Task<IActionResult> CreateQueryPlan(

if (ModelState.IsValid)
{
var existing = await _queryPlanQueries.GetAsync(facilityId, queryPlan.Type.Value, cancellationToken);
var exists = await _queryPlanQueries.ExistsAsync(facilityId, queryPlan.Type.Value, cancellationToken);

if (existing != null)
if (exists)
{
throw new EntityAlreadyExistsException($"A Query Plan already exists for facilityId: {facilityId}.");
}
Expand Down Expand Up @@ -254,9 +255,9 @@ public async Task<ActionResult> UpdateQueryPlan(

if (ModelState.IsValid)
{
var existing = await _queryPlanQueries.GetAsync(facilityId, queryPlan.Type.Value, cancellationToken);
var exists = await _queryPlanQueries.ExistsAsync(facilityId, queryPlan.Type.Value, cancellationToken);

if (existing == null)
if (!exists)
{
throw new NotFoundException($"A Query Plan was not found for facilityId: {facilityId}.");
}
Expand Down Expand Up @@ -340,6 +341,7 @@ public async Task<ActionResult> DeleteQueryPlan(

try
{
facilityId = facilityId.SanitizeAndRemove();
if (string.IsNullOrWhiteSpace(facilityId))
{
throw new BadRequestException("parameter facilityId is required.");
Expand All @@ -350,14 +352,14 @@ public async Task<ActionResult> DeleteQueryPlan(
throw new BadRequestException("type query parameter must be defined.");
}

var existing = await _queryPlanQueries.GetAsync(facilityId.Sanitize(), parameters.Type.Value, cancellationToken);
var exists = await _queryPlanQueries.ExistsAsync(facilityId, parameters.Type.Value, cancellationToken);

if (existing == null)
if (!exists)
{
throw new NotFoundException($"A QueryPlan or Query component was not found for facilityId: {facilityId}.");
}

await _queryPlanManager.DeleteAsync(facilityId.Sanitize(), parameters.Type.Value, cancellationToken);
await _queryPlanManager.DeleteAsync(facilityId, parameters.Type.Value, cancellationToken);

return Accepted();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public async Task UpdateQueryPlanTest()
{
var facilityId = "test-facility-id";
var _mocker = new AutoMocker();
_mocker.GetMock<IQueryPlanQueries>().Setup(x => x.ExistsAsync(It.IsAny<string>(), Frequency.Monthly, CancellationToken.None))
.ReturnsAsync(true);
_mocker.GetMock<IQueryPlanQueries>().Setup(x => x.GetAsync(It.IsAny<string>(), Frequency.Monthly, CancellationToken.None))
.ReturnsAsync(new QueryPlanModel());
_mocker.GetMock<IQueryPlanManager>().Setup(x => x.UpdateAsync(It.IsAny<UpdateQueryPlanModel>(), CancellationToken.None))
Expand Down Expand Up @@ -135,8 +137,8 @@ public async Task DeleteQueryPlanTest()
_mocker.GetMock<IQueryPlanManager>().Setup(x => x.AddAsync(It.IsAny<CreateQueryPlanModel>(), CancellationToken.None))
.ReturnsAsync(queryPlan);

_mocker.GetMock<IQueryPlanQueries>().Setup(x => x.GetAsync(It.IsAny<string>(), Frequency.Monthly, CancellationToken.None))
.ReturnsAsync(queryPlan);
_mocker.GetMock<IQueryPlanQueries>().Setup(x => x.ExistsAsync(It.IsAny<string>(), Frequency.Monthly, CancellationToken.None))
.ReturnsAsync(true);

var _createController = _mocker.CreateInstance<QueryPlanConfigController>();

Expand Down
Loading
Loading