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

BAH-4158 | Migrate HIP Data transfer flow to use ABDM v3 APIs #180

Merged
merged 4 commits into from
Jan 15, 2025
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
3 changes: 2 additions & 1 deletion src/In.ProjectEKA.HipLibrary/Patient/Model/HiType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public enum HiType
DischargeSummary,
OPConsultation,
WellnessRecord,
HealthDocumentRecord
HealthDocumentRecord,
Invoice
}
}
8 changes: 3 additions & 5 deletions src/In.ProjectEKA.HipService/Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,10 @@ public static class Constants
public static readonly string PATH_ON_LINK_CONFIRM = "/api/hiecm/user-initiated-linking/"+VERSION_V3+"/link/care-context/on-confirm";
public static readonly string PATH_CONSENT_ON_NOTIFY = "/" + CURRENT_VERSION + "/consents/hip/on-notify";

public static readonly string PATH_HEALTH_INFORMATION_ON_REQUEST = "/" + CURRENT_VERSION +
"/health-information/hip/on-request";

public static readonly string PATH_HEALTH_INFORMATION_NOTIFY_GATEWAY = "/" + CURRENT_VERSION +
"/health-information/notify";
public static readonly string PATH_HEALTH_INFORMATION_ON_REQUEST =
"/api/hiecm/data-flow/" + VERSION_V3 + "/health-information/hip/on-request";

public static readonly string PATH_HEALTH_INFORMATION_NOTIFY_GATEWAY = "/api/hiecm/data-flow/"+ VERSION_V3 +"/health-information/notify";
public static readonly string PATH_AUTH_CONFIRM = "/" + CURRENT_VERSION + "/users/auth/confirm";

public static readonly string PATH_OPENMRS_FHIR = "ws/fhir2/R4/metadata";
Expand Down
7 changes: 7 additions & 0 deletions src/In.ProjectEKA.HipService/Common/HttpRequestHelper.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System.Collections.Generic;
using Newtonsoft.Json.Converters;

namespace In.ProjectEKA.HipService.Common
{
using System;
Expand Down Expand Up @@ -32,6 +35,10 @@ public static HttpRequestMessage CreateHttpRequest<T>(
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
},
Converters = new List<JsonConverter>
{
new StringEnumConverter()
}
});
httpRequestMessage.Content = new StringContent(json, Encoding.UTF8, MediaTypeNames.Application.Json);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@ namespace In.ProjectEKA.HipService.Consent

public class ConsentArtefactRepresentation
{
public ConsentArtefactRepresentation(Notification notification, DateTime timestamp, string requestId)
public ConsentArtefactRepresentation(Notification notification)
{
Notification = notification;
Timestamp = timestamp;
RequestId = requestId;
}

public Notification Notification { get; }

public DateTime Timestamp { get; }

public string RequestId { get; }
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// ReSharper disable MemberCanBePrivate.Global

using System.ComponentModel.DataAnnotations;
using In.ProjectEKA.HipService.Common;

namespace In.ProjectEKA.HipService.Consent
Expand Down Expand Up @@ -34,15 +35,17 @@ public ConsentNotificationController(

[HttpPost(PATH_CONSENTS_HIP)]
public AcceptedResult ConsentNotification(
[FromHeader(Name = CORRELATION_ID)] string correlationId,
[FromHeader(Name = CORRELATION_ID)] string correlationId,
[FromHeader(Name = REQUEST_ID), Required] string requestId,
[FromHeader(Name = TIMESTAMP)] string timestamp,
[FromBody] ConsentArtefactRepresentation consentArtefact)
{
backgroundJob.Enqueue(() => StoreConsent(consentArtefact, correlationId));
backgroundJob.Enqueue(() => StoreConsent(consentArtefact, correlationId, requestId));
return Accepted();
}

[NonAction]
public async Task StoreConsent(ConsentArtefactRepresentation consentArtefact, String correlationId)
public async Task StoreConsent(ConsentArtefactRepresentation consentArtefact, String correlationId, String requestId)
{
var notification = consentArtefact.Notification;

Expand All @@ -56,11 +59,9 @@ public async Task StoreConsent(ConsentArtefactRepresentation consentArtefact, St
await consentRepository.AddAsync(consent);
var cmSuffix = consent.ConsentArtefact.ConsentManager.Id;
var gatewayResponse = new GatewayConsentRepresentation(
Guid.NewGuid(),
DateTime.Now.ToUniversalTime().ToString(DateTimeFormat),
new ConsentUpdateResponse(ConsentUpdateStatus.OK.ToString(), notification.ConsentId),
null,
new Resp(consentArtefact.RequestId));
new Resp(requestId));
await gatewayClient.SendDataToGateway(PATH_CONSENT_ON_NOTIFY, gatewayResponse, cmSuffix, correlationId);
}
else
Expand All @@ -71,11 +72,9 @@ public async Task StoreConsent(ConsentArtefactRepresentation consentArtefact, St
var consent = await consentRepository.GetFor(notification.ConsentId);
var cmSuffix = consent.ConsentArtefact.ConsentManager.Id;
var gatewayResponse = new GatewayConsentRepresentation(
Guid.NewGuid(),
DateTime.Now.ToUniversalTime().ToString(DateTimeFormat),
new ConsentUpdateResponse(ConsentUpdateStatus.OK.ToString(), notification.ConsentId),
null,
new Resp(consentArtefact.RequestId));
new Resp(requestId));
await gatewayClient.SendDataToGateway(PATH_CONSENT_ON_NOTIFY, gatewayResponse, cmSuffix, correlationId);
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/In.ProjectEKA.HipService/Consent/Model/Notification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ namespace In.ProjectEKA.HipService.Consent.Model

public class Notification
{
public Notification(ConsentArtefact consentDetail, string consentId, string signature, ConsentStatus status)
public Notification(ConsentArtefact consentDetail, string consentId, string signature, ConsentStatus status, bool grantAcknowledgement)
{
ConsentDetail = consentDetail;
ConsentId = consentId;
Signature = signature;
Status = status;
GrantAcknowledgement = grantAcknowledgement;
}

public ConsentArtefact ConsentDetail { get; }
Expand All @@ -19,5 +20,7 @@ public Notification(ConsentArtefact consentDetail, string consentId, string sign
public string Signature { get; }

public ConsentStatus Status { get; }

public bool GrantAcknowledgement { get; }
}
}
19 changes: 10 additions & 9 deletions src/In.ProjectEKA.HipService/DataFlow/DataFlowController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.ComponentModel.DataAnnotations;

namespace In.ProjectEKA.HipService.DataFlow
{
using System;
Expand Down Expand Up @@ -87,16 +89,19 @@ GatewayConfiguration gatewayConfiguration
[HttpPost(PATH_HEALTH_INFORMATION_HIP_REQUEST)]
public AcceptedResult HealthInformationRequestFor(PatientHealthInformationRequest healthInformationRequest,
[FromHeader(Name = CORRELATION_ID)] string correlationId,
[FromHeader(Name = "X-GatewayID")] string gatewayId)
[FromHeader(Name = "X-GatewayID")] string gatewayId,
[FromHeader(Name = REQUEST_ID), Required] string requestId,
[FromHeader(Name = TIMESTAMP)] string timestamp)

{
logger.Log(LogLevel.Information, LogEvents.DataFlow, "Data request received");
backgroundJob.Enqueue(() => HealthInformationOf(healthInformationRequest, gatewayId, correlationId));
backgroundJob.Enqueue(() => HealthInformationOf(healthInformationRequest, gatewayId, correlationId, requestId));
return Accepted();
}

[NonAction]
public async Task HealthInformationOf(PatientHealthInformationRequest healthInformationRequest,
string gatewayId, string correlationId)
string gatewayId, string correlationId, string requestId)
{
try
{
Expand All @@ -112,12 +117,10 @@ public async Task HealthInformationOf(PatientHealthInformationRequest healthInfo
if (error != null)
{
gatewayResponse = new GatewayDataFlowRequestResponse(
Guid.NewGuid(),
DateTime.Now.ToUniversalTime().ToString(DateTimeFormat),
new DataFlowRequestResponse(healthInformationRequest.TransactionId,
DataFlowRequestStatus.ERRORED.ToString()),
error.Error,
new Resp(healthInformationRequest.RequestId));
new Resp(requestId));
logger.Log(LogLevel.Error,
LogEvents.DataFlow,
"Response for data request {@GatewayResponse}",
Expand All @@ -126,12 +129,10 @@ public async Task HealthInformationOf(PatientHealthInformationRequest healthInfo
else
{
gatewayResponse = new GatewayDataFlowRequestResponse(
Guid.NewGuid(),
DateTime.Now.ToUniversalTime().ToString(DateTimeFormat),
new DataFlowRequestResponse(healthInformationRequest.TransactionId,
DataFlowRequestStatus.ACKNOWLEDGED.ToString()),
null,
new Resp(healthInformationRequest.RequestId));
new Resp(requestId));
logger.Log(LogLevel.Information,
LogEvents.DataFlow,
"Response for data request {@GatewayResponse}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ public DataFlowNotificationClient(GatewayClient gatewayClient)
public virtual async Task NotifyGateway(string cmSuffix, DataNotificationRequest dataNotificationRequest,
string correlationId)
{
var notificationRequest = new GatewayDataNotificationRequest(Guid.NewGuid(),
DateTime.Now.ToUniversalTime().ToString(DateTimeFormat),
var notificationRequest = new GatewayDataNotificationRequest(
new DataFlowNotificationRequest(
dataNotificationRequest.TransactionId,
dataNotificationRequest.ConsentId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,13 @@ namespace In.ProjectEKA.HipService.DataFlow
public class PatientHealthInformationRequest
{
public PatientHealthInformationRequest(string transactionId,
string requestId,
DateTime timestamp,
HIRequest hiRequest)
{
TransactionId = transactionId;
RequestId = requestId;
Timestamp = timestamp;
HiRequest = hiRequest;
}

public string TransactionId { get; }
public string RequestId { get; }
public DateTime Timestamp { get; }
public HIRequest HiRequest { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,15 @@ namespace In.ProjectEKA.HipService.Gateway.Model

public class GatewayConsentRepresentation
{
public GatewayConsentRepresentation(Guid requestId, string timestamp,
ConsentUpdateResponse acknowledgement, Error error, Resp resp)
public GatewayConsentRepresentation(ConsentUpdateResponse acknowledgement, Error error, Resp response)
{
RequestId = requestId;
Timestamp = timestamp;
Acknowledgement = acknowledgement;
Resp = resp;
Response = response;
Error = error;
}

public Guid RequestId { get; }
public string Timestamp { get; }
public ConsentUpdateResponse Acknowledgement { get; }
public Resp Resp { get; }
public Resp Response { get; }
public Error Error { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,17 @@ namespace In.ProjectEKA.HipService.Gateway.Model
public class GatewayDataFlowRequestResponse
{
public GatewayDataFlowRequestResponse(
Guid requestId,
string timestamp,
DataFlowRequestResponse hiRequest,
Error error,
Resp resp)
Resp response)
{
RequestId = requestId;
Timestamp = timestamp;
HiRequest = hiRequest;
Error = error;
Resp = resp;
Response = response;
}

public Guid RequestId { get; }
public string Timestamp { get; }

public DataFlowRequestResponse HiRequest { get; }
public Error Error { get; }
public Resp Resp { get; }
public Resp Response { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@ namespace In.ProjectEKA.HipService.Gateway.Model

public class GatewayDataNotificationRequest
{
public GatewayDataNotificationRequest(Guid requestId, string timestamp,
DataFlowNotificationRequest notification)
public GatewayDataNotificationRequest(DataFlowNotificationRequest notification)
{
RequestId = requestId;
Timestamp = timestamp;
Notification = notification;
}

public Guid RequestId { get; }
public string Timestamp { get; }

public DataFlowNotificationRequest Notification { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ internal static Notification Notification(
return new Notification(ConsentArtefact().Generate().Build(),
faker.Random.Hash(),
faker.Random.Hash(),
consentStatus);
consentStatus, false);
}

internal static Notification RevokedNotification(string patientId)
Expand All @@ -26,7 +26,7 @@ internal static Notification RevokedNotification(string patientId)
return new Notification(consentArtefactBuilder.Build(),
faker.Random.Hash(),
faker.Random.Hash(),
ConsentStatus.REVOKED);
ConsentStatus.REVOKED, false);
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Hl7.Fhir.Model;
using In.ProjectEKA.HipService.Common;
using In.ProjectEKA.HipService.Gateway;

namespace In.ProjectEKA.HipServiceTest.Consent
Expand Down Expand Up @@ -68,9 +69,7 @@ private void SetupConsentNotification(ConsentStatus consentStatus)
const string consentMangerId = "consentMangerId";
var notification = TestBuilder.Notification(consentStatus);
var faker = new Faker();
consentNotification = new ConsentArtefactRepresentation(notification,
DateTime.Now,
faker.Random.Hash());
consentNotification = new ConsentArtefactRepresentation(notification);
var consent =
new Consent(notification.ConsentDetail.ConsentId,
notification.ConsentDetail,
Expand All @@ -87,7 +86,9 @@ private void SetupConsentNotification(ConsentStatus consentStatus)
private void ShouldEnqueueConsentNotificationAndReturnAccepted()
{
var correlationId = Uuid.Generate().ToString();
var result = consentNotificationController.ConsentNotification(correlationId, consentNotification);
var requestId = Uuid.Generate().ToString();
var timestamp = DateTime.Now.ToString();
var result = consentNotificationController.ConsentNotification(correlationId, requestId, timestamp, consentNotification);

backgroundJobClient.Verify(client => client.Create(
It.Is<Job>(job => job.Method.Name == "StoreConsent" && job.Args[0] == consentNotification),
Expand All @@ -100,7 +101,8 @@ private void ShouldEnqueueConsentNotificationAndReturnAccepted()
async void ShouldStoreConsentArtefact()
{
var correlationId = Uuid.Generate().ToString();
await consentNotificationController.StoreConsent(consentNotification,correlationId);
var requestId = Uuid.Generate().ToString();
await consentNotificationController.StoreConsent(consentNotification,correlationId,requestId);

consentRepository.Verify(cr => cr.AddAsync(
It.Is<Consent>(c => verifyActualConsentEqualsExpected(c))),
Expand All @@ -117,9 +119,10 @@ async void ShouldStoreConsentArtefact()
async void ShouldUpdateConsentArtefact(ConsentStatus consentStatus)
{
var correlationId = Uuid.Generate().ToString();
var requestId = Uuid.Generate().ToString();
SetupConsentNotification(consentStatus);

await consentNotificationController.StoreConsent(consentNotification,correlationId);
await consentNotificationController.StoreConsent(consentNotification,correlationId,requestId);

consentRepository.Verify(cr => cr.UpdateAsync(
consentNotification.Notification.ConsentId,
Expand All @@ -132,16 +135,17 @@ async void ShouldUpdateConsentArtefact(ConsentStatus consentStatus)
async void ShouldInvokeGatewayWhenRevokingConsent()
{
var correlationId = Uuid.Generate().ToString();
var requestId = Uuid.Generate().ToString();
SetupConsentNotification(ConsentStatus.REVOKED);

await consentNotificationController.StoreConsent(consentNotification,correlationId);
await consentNotificationController.StoreConsent(consentNotification,correlationId,requestId);

gatewayClient.Verify(g => g.SendDataToGateway(
"/v0.5/consents/hip/on-notify",
Constants.PATH_CONSENT_ON_NOTIFY,
It.Is<GatewayConsentRepresentation>(
c =>
c.Acknowledgement.ConsentId == consentNotification.Notification.ConsentId
&& c.Resp.RequestId == consentNotification.RequestId),
&& c.Response.RequestId == requestId),
consentNotification.Notification.ConsentDetail.ConsentManager.Id,
correlationId),
Times.Once);
Expand Down
Loading
Loading