-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGetValidationExceptions.cs
More file actions
164 lines (143 loc) · 7.81 KB
/
GetValidationExceptions.cs
File metadata and controls
164 lines (143 loc) · 7.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
namespace NHS.CohortManager.ScreeningDataServices;
using System.Net;
using System.Text.Json;
using System.Threading.Tasks;
using Common;
using Common.Interfaces;
using Data.Database;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using Model;
using Model.Enums;
/// <summary>
/// Azure Function for retrieving and managing validation exceptions.
/// Provides endpoints for exception queries, reports, and ServiceNowId updates.
/// </summary>
public class GetValidationExceptions
{
private readonly ILogger<GetValidationExceptions> _logger;
private readonly ICreateResponse _createResponse;
private readonly IValidationExceptionData _validationData;
private readonly IHttpParserHelper _httpParserHelper;
private readonly IPaginationService<ValidationException> _paginationService;
public GetValidationExceptions(ILogger<GetValidationExceptions> logger, ICreateResponse createResponse, IValidationExceptionData validationData, IHttpParserHelper httpParserHelper, IPaginationService<ValidationException> paginationService)
{
_logger = logger;
_createResponse = createResponse;
_validationData = validationData;
_httpParserHelper = httpParserHelper;
_paginationService = paginationService;
}
/// <summary>
/// Retrieves validation exceptions based on query parameters.
/// Supports single exception lookup, filtered lists, and report-based queries.
/// </summary>
/// <param name="req">The HTTP request data containing query parameters.</param>
/// <returns>
/// HTTP response containing validation exceptions in JSON format.
/// Returns 200 OK with data, 204 No Content if empty, 400 Bad Request for validation errors, or 500 Internal Server Error.
/// </returns>
[Function(nameof(GetValidationExceptions))]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req)
{
var exceptionId = _httpParserHelper.GetQueryParameterAsInt(req, "exceptionId");
var lastId = _httpParserHelper.GetQueryParameterAsInt(req, "lastId");
var exceptionStatus = HttpParserHelper.GetEnumQueryParameter(req, "exceptionStatus", ExceptionStatus.All);
var sortOrder = HttpParserHelper.GetEnumQueryParameter(req, "sortOrder", SortOrder.Descending);
var exceptionCategory = HttpParserHelper.GetEnumQueryParameter(req, "exceptionCategory", ExceptionCategory.NBO);
var reportDate = _httpParserHelper.GetQueryParameterAsDateTime(req, "reportDate");
var isReport = _httpParserHelper.GetQueryParameterAsBool(req, "isReport");
try
{
if (exceptionId > 0)
{
var exceptionById = await _validationData.GetExceptionById(exceptionId);
return exceptionById == null
? _createResponse.CreateHttpResponse(HttpStatusCode.NoContent, req)
: _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, JsonSerializer.Serialize(exceptionById));
}
var isReportCategory = exceptionCategory == ExceptionCategory.Confusion || exceptionCategory == ExceptionCategory.Superseded;
return isReport
? await HandleReportRequest(req, reportDate, exceptionCategory, isReportCategory, lastId)
: await HandleStandardRequestWithHeaders(req, exceptionStatus, sortOrder, exceptionCategory, lastId);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing: {Function} validation exceptions request", nameof(GetValidationExceptions));
return _createResponse.CreateHttpResponse(HttpStatusCode.InternalServerError, req);
}
}
private async Task<HttpResponseData> HandleReportRequest(HttpRequestData req, DateTime? reportDate, ExceptionCategory exceptionCategory, bool hasSpecificCategory, int lastId)
{
if (reportDate.HasValue && reportDate.Value > DateTime.Now.Date)
{
return _createResponse.CreateHttpResponse(HttpStatusCode.BadRequest, req, "Report date cannot be in the future.");
}
var reportExceptions = await _validationData.GetReportExceptions(reportDate, exceptionCategory);
return CreatePaginatedResponse(req, reportExceptions, lastId);
}
private HttpResponseData CreatePaginatedResponse(HttpRequestData req, List<ValidationException>? exceptions, int lastId)
{
if (exceptions?.Count == 0 || exceptions == null)
{
return _createResponse.CreateHttpResponse(HttpStatusCode.NoContent, req);
}
var result = _paginationService.GetPaginatedResult(exceptions.AsQueryable(), lastId, e => e.ExceptionId);
return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, JsonSerializer.Serialize(result));
}
private async Task<HttpResponseData> HandleStandardRequestWithHeaders(HttpRequestData req, ExceptionStatus exceptionStatus, SortOrder sortOrder, ExceptionCategory exceptionCategory, int lastId)
{
var allExceptions = await _validationData.GetAllFilteredExceptions(exceptionStatus, sortOrder, exceptionCategory);
if (allExceptions == null)
{
return _createResponse.CreateHttpResponse(HttpStatusCode.NoContent, req);
}
var paginatedResult = _paginationService.GetPaginatedResult(allExceptions.AsQueryable(), lastId == 0 ? null : lastId, e => e.ExceptionId);
if (!paginatedResult.Items.Any())
{
return _createResponse.CreateHttpResponse(HttpStatusCode.NoContent, req);
}
var headers = _paginationService.BuildPaginationHeaders(req, paginatedResult);
return _createResponse.CreateHttpResponseWithHeaders(HttpStatusCode.OK, req, JsonSerializer.Serialize(paginatedResult.Items), headers);
}
/// <summary>
/// Updates the ServiceNowId for a specific validation exception.
/// </summary>
/// <param name="req">The HTTP request data containing the exceptionId and ServiceNowId.</param>
/// <returns>
/// HTTP response with:
/// - 200 OK if the update is successful
/// - 400 Bad Request if required parameters are missing
/// - 500 Internal Server Error if an exception occurs
/// </returns>
[Function(nameof(UpdateExceptionServiceNowId))]
public async Task<HttpResponseData> UpdateExceptionServiceNowId([HttpTrigger(AuthorizationLevel.Anonymous, "put")] HttpRequestData req)
{
try
{
using var bodyReader = new StreamReader(req.Body);
var requestBody = await bodyReader.ReadToEndAsync();
if (string.IsNullOrWhiteSpace(requestBody))
{
return _createResponse.CreateHttpResponse(HttpStatusCode.BadRequest, req, "Request body cannot be empty.");
}
var updateRequest = JsonSerializer.Deserialize<UpdateExceptionServiceNowIdRequest>(requestBody);
if (updateRequest == null || updateRequest.ExceptionId == 0)
{
return _createResponse.CreateHttpResponse(HttpStatusCode.BadRequest, req, "Invalid request. ExceptionId and ServiceNowId is required.");
}
var response = await _validationData.UpdateExceptionServiceNowId(updateRequest.ExceptionId, updateRequest.ServiceNowId);
if (!response.Success)
{
return _createResponse.CreateHttpResponse(response.StatusCode, req, response.Message ?? "Failed to update ServiceNowId");
}
return _createResponse.CreateHttpResponse(HttpStatusCode.OK, req, response.Message);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing: {Function} update ServiceNowId request", nameof(UpdateExceptionServiceNowId));
return _createResponse.CreateHttpResponse(HttpStatusCode.InternalServerError, req);
}
}
}