Skip to content

Commit

Permalink
Merge pull request #768 from CDCgov/610-task_set-delivery-status-for-…
Browse files Browse the repository at this point in the history
…failed-order

Set Delivery Status for Internal Failed Order
  • Loading branch information
tjohnson7021 authored Jan 15, 2024
2 parents 9def037 + 318eb49 commit 8043388
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import gov.hhs.cdc.trustedintermediary.etor.metadata.PartnerMetadataException;
import gov.hhs.cdc.trustedintermediary.etor.metadata.PartnerMetadataOrchestrator;
import gov.hhs.cdc.trustedintermediary.etor.metadata.PartnerMetadataStorage;
import gov.hhs.cdc.trustedintermediary.etor.metadata.partner.PartnerMetadataStatus;
import gov.hhs.cdc.trustedintermediary.etor.operationoutcomes.FhirMetadata;
import gov.hhs.cdc.trustedintermediary.etor.orders.Order;
import gov.hhs.cdc.trustedintermediary.etor.orders.OrderController;
Expand Down Expand Up @@ -155,15 +156,27 @@ DomainResponse handleOrders(DomainRequest request) {
logger.logError("Missing required header or empty: RecordId");
}

var markMetadataAsFailed = false;
try {
orders = orderController.parseOrders(request);
sendOrderUseCase.convertAndSend(orders, receivedSubmissionId);
} catch (FhirParseException e) {
logger.logError("Unable to parse order request", e);
markMetadataAsFailed = true;
return domainResponseHelper.constructErrorResponse(400, e);
} catch (UnableToSendOrderException e) {
logger.logError("Unable to send order", e);
markMetadataAsFailed = true;
return domainResponseHelper.constructErrorResponse(400, e);
} finally {
if (markMetadataAsFailed) {
try {
partnerMetadataOrchestrator.setMetadataStatus(
receivedSubmissionId, PartnerMetadataStatus.FAILED);
} catch (PartnerMetadataException innerE) {
logger.logError("Unable to update metadata status", innerE);
}
}
}

OrderResponse orderResponse = new OrderResponse(orders);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public PartnerMetadata(String receivedSubmissionId, String hash) {
this(receivedSubmissionId, null, null, null, null, hash, null);
}

public PartnerMetadata(String receivedSubmissionId, PartnerMetadataStatus deliveryStatus) {
this(receivedSubmissionId, null, null, null, null, null, deliveryStatus);
}

public PartnerMetadata withSentSubmissionId(String sentSubmissionId) {
return new PartnerMetadata(
this.receivedSubmissionId,
Expand All @@ -64,4 +68,15 @@ public PartnerMetadata withReceiver(String receiver) {
this.hash,
this.deliveryStatus);
}

public PartnerMetadata withDeliveryStatus(PartnerMetadataStatus deliveryStatus) {
return new PartnerMetadata(
this.receivedSubmissionId,
this.sentSubmissionId,
this.sender,
this.receiver,
this.timeReceived,
this.hash,
deliveryStatus);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,33 @@ public Optional<PartnerMetadata> getMetadata(String receivedSubmissionId)
return Optional.of(partnerMetadata);
}

public void setMetadataStatus(String submissionId, PartnerMetadataStatus metadataStatus)
throws PartnerMetadataException {
if (submissionId == null) {
return;
}

Optional<PartnerMetadata> optionalPartnerMetadata =
partnerMetadataStorage.readMetadata(submissionId);
PartnerMetadata partnerMetadata;
if (optionalPartnerMetadata.isEmpty()) {
// there wasn't any metadata given the submission ID, so make one with the status
partnerMetadata = new PartnerMetadata(submissionId, metadataStatus);
} else {
partnerMetadata = optionalPartnerMetadata.get();
if (partnerMetadata.deliveryStatus().equals(metadataStatus)) {
return;
}
}

logger.logInfo(
"Updating metadata delivery status {} with submissionId: {}",
metadataStatus,
submissionId);
partnerMetadata = partnerMetadata.withDeliveryStatus(metadataStatus);
partnerMetadataStorage.saveMetadata(partnerMetadata);
}

String getReceiverName(String responseBody) throws FormatterProcessingException {
// the expected json structure for the response is:
// {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ class EtorDomainRegistrationTest extends Specification {
mockResponseHelper.constructErrorResponse(expectedStatusCode, _ as Exception) >> new DomainResponse(expectedStatusCode)
TestApplicationContext.register(DomainResponseHelper, mockResponseHelper)

def mockPartnerMetadataOrchestrator = Mock(PartnerMetadataOrchestrator)
TestApplicationContext.register(PartnerMetadataOrchestrator,mockPartnerMetadataOrchestrator)

TestApplicationContext.injectRegisteredImplementations()

when:
Expand Down Expand Up @@ -241,6 +244,49 @@ class EtorDomainRegistrationTest extends Specification {
mockResponseHelper.constructErrorResponse(expectedStatusCode, _ as Exception) >> new DomainResponse(expectedStatusCode)
TestApplicationContext.register(DomainResponseHelper, mockResponseHelper)

def mockPartnerMetadataOrchestrator = Mock(PartnerMetadataOrchestrator)
TestApplicationContext.register(PartnerMetadataOrchestrator,mockPartnerMetadataOrchestrator)

TestApplicationContext.injectRegisteredImplementations()

when:
def res = domainRegistration.handleOrders(request)
def actualStatusCode = res.statusCode

then:
actualStatusCode == expectedStatusCode
}

def "handleOrders generates an error response when not being able to send the order even when setMetadataStatus throws an exception"() {
given:
def expectedStatusCode = 400

def request = new DomainRequest()
request.headers["recordid"] = "recordId"

def domainRegistration = new EtorDomainRegistration()
TestApplicationContext.register(EtorDomainRegistration, domainRegistration)

def mockController = Mock(OrderController)
mockController.parseOrders(_ as DomainRequest) >> new OrderMock<?>(null, null, null)
TestApplicationContext.register(OrderController, mockController)

def mockUseCase = Mock(SendOrderUseCase)
mockUseCase.convertAndSend(_ as Order<?>, _ as String) >> {
throw new UnableToSendOrderException("error", new NullPointerException())
}
TestApplicationContext.register(SendOrderUseCase, mockUseCase)

def mockResponseHelper = Mock(DomainResponseHelper)
mockResponseHelper.constructErrorResponse(expectedStatusCode, _ as UnableToSendOrderException) >> new DomainResponse(expectedStatusCode)
TestApplicationContext.register(DomainResponseHelper, mockResponseHelper)

def mockPartnerMetadataOrchestrator = Mock(PartnerMetadataOrchestrator)
mockPartnerMetadataOrchestrator.setMetadataStatus(_, PartnerMetadataStatus.FAILED) >> {
throw new PartnerMetadataException("error")
}
TestApplicationContext.register(PartnerMetadataOrchestrator,mockPartnerMetadataOrchestrator)

TestApplicationContext.injectRegisteredImplementations()

when:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,61 @@ class PartnerMetadataOrchestratorTest extends Specification {
1 * mockPartnerMetadataStorage.saveMetadata(expectedMetadata)
}

def "setMetadataStatus sets status to Pending"(){
given:
def submissionId = "13425"
def metadataStatus = PartnerMetadataStatus.PENDING
def optional = Optional.of(new PartnerMetadata("","","","",Instant.now(),"",PartnerMetadataStatus.FAILED))
mockPartnerMetadataStorage.readMetadata(submissionId) >> optional

when:
PartnerMetadataOrchestrator.getInstance().setMetadataStatus(submissionId,metadataStatus)

then:
1 * mockPartnerMetadataStorage.saveMetadata(_ as PartnerMetadata) >> { PartnerMetadata partnerMetadata ->
assert partnerMetadata.deliveryStatus() == metadataStatus
}
}

def "setMetadataStatus doesn't update status if status is the same"(){
given:
def submissionId = "13425"
def metadataStatus = PartnerMetadataStatus.PENDING
def optional = Optional.of(new PartnerMetadata("","","","",Instant.now(),"",metadataStatus))
mockPartnerMetadataStorage.readMetadata(submissionId) >> optional

when:
PartnerMetadataOrchestrator.getInstance().setMetadataStatus(submissionId,metadataStatus)

then:
0 * mockPartnerMetadataStorage.saveMetadata(_ as PartnerMetadata)
}

def "setMetadataStatus doesn't update when submissionId is null"(){
when:
PartnerMetadataOrchestrator.getInstance().setMetadataStatus(null,PartnerMetadataStatus.DELIVERED)

then:
0 * mockPartnerMetadataStorage.saveMetadata(_ as PartnerMetadata)
}

def "setMetadataStatus sets status to Pending when there is no metadata"(){
given:
def submissionId = "13425"
def metadataStatus = PartnerMetadataStatus.DELIVERED
def optional = Optional.empty()
mockPartnerMetadataStorage.readMetadata(submissionId) >> optional

when:
PartnerMetadataOrchestrator.getInstance().setMetadataStatus(submissionId,metadataStatus)

then:
1 * mockPartnerMetadataStorage.saveMetadata(_ as PartnerMetadata) >> { PartnerMetadata partnerMetadata ->
assert partnerMetadata.deliveryStatus() == metadataStatus
assert partnerMetadata.receivedSubmissionId() == submissionId
}
}

def "getReceiverName returns correct receiver name from valid JSON response"() {
given:
def validJson = "{\"destinations\": [{\"organization_id\": \"org_id\", \"service\": \"service_name\"}]}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ class PartnerMetadataTest extends Specification {
metadata.deliveryStatus() == PartnerMetadataStatus.PENDING
}

def "test constructor with only received submission ID and status"() {
given:
def receivedSubmissionId = "receivedSubmissionId"
def deliverStatus = PartnerMetadataStatus.DELIVERED

when:
def metadata = new PartnerMetadata(receivedSubmissionId, deliverStatus)

then:
metadata.receivedSubmissionId() == receivedSubmissionId
metadata.sentSubmissionId() == null
metadata.sender() == null
metadata.receiver() == null
metadata.timeReceived() == null
metadata.hash() == null
metadata.deliveryStatus() == deliverStatus
}

def "test withSentSubmissionId and withReceiver to update PartnerMetadata"() {
given:
def receivedSubmissionId = "receivedSubmissionId"
Expand All @@ -101,4 +119,28 @@ class PartnerMetadataTest extends Specification {
updatedMetadata.hash() == hash
updatedMetadata.deliveryStatus() == status
}

def "test withDeliveryStatus to update PartnerMetadata"() {
given:
def receivedSubmissionId = "receivedSubmissionId"
def sentSubmissionId = "sentSubmissionId"
def sender = "sender"
def receiver = "receiver"
def timeReceived = Instant.now()
def hash = "abcd"
def metadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timeReceived, hash, PartnerMetadataStatus.PENDING)

when:
def newStatus = PartnerMetadataStatus.DELIVERED
def updatedMetadata = metadata.withSentSubmissionId(sentSubmissionId).withDeliveryStatus(newStatus)

then:
updatedMetadata.receivedSubmissionId() == receivedSubmissionId
updatedMetadata.sentSubmissionId() == sentSubmissionId
updatedMetadata.sender() == sender
updatedMetadata.receiver() == receiver
updatedMetadata.timeReceived() == timeReceived
updatedMetadata.hash() == hash
updatedMetadata.deliveryStatus() == newStatus
}
}

0 comments on commit 8043388

Please sign in to comment.