From 0e77fb974eee2638b7e096d9017451cc40bdea5b Mon Sep 17 00:00:00 2001 From: jcrichlake <145698165+jcrichlake@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:27:08 -0500 Subject: [PATCH] Add time of delivery to metadata endpoint (#831) * Pushing initial branch * Adding time delivered to Operation Outcome API Response object * Adding test coverage * Update time_delivered SQL in PostgresDao.java --------- Co-authored-by: Tiffini Johnson <86614374+tjohnson7021@users.noreply.github.com> --- .../workflows/terraform-deploy_reusable.yml | 2 +- .../trustedintermediary/e2e/ResultTest.groovy | 2 + .../metadata/partner/PartnerMetadata.java | 35 ++++++++++-- .../partner/PartnerMetadataOrchestrator.java | 18 ++++++- .../DatabasePartnerMetadataStorage.java | 1 + .../external/database/DbDao.java | 1 + .../external/database/PostgresDao.java | 35 ++++++++---- .../external/hapi/HapiOrderConverter.java | 9 +++- .../localfile/MockRSEndpointClient.java | 1 + .../etor/EtorDomainRegistrationTest.groovy | 2 +- .../PartnerMetadataOrchestratorTest.groovy | 53 ++++++++++++------- .../partner/PartnerMetadataTest.groovy | 42 +++++++++++++-- ...geAccountPartnerMetadataStorageTest.groovy | 6 +-- .../DatabasePartnerMetadataStorageTest.groovy | 6 ++- .../external/database/PostgresDaoTest.groovy | 26 +++++---- .../hapi/HapiOrderConverterTest.groovy | 7 +-- .../FilePartnerMetadataStorageTest.groovy | 10 ++-- 17 files changed, 194 insertions(+), 62 deletions(-) diff --git a/.github/workflows/terraform-deploy_reusable.yml b/.github/workflows/terraform-deploy_reusable.yml index d5d0bd5fb..393294c3b 100644 --- a/.github/workflows/terraform-deploy_reusable.yml +++ b/.github/workflows/terraform-deploy_reusable.yml @@ -74,7 +74,7 @@ jobs: - name: Run Db migration run: | export PGPASSWORD=$(az account get-access-token --resource-type oss-rdbms --query "[accessToken]" -o tsv) - psql "host=$(terraform output -raw database_hostname) port=5432 dbname=postgres user=cdcti-github sslmode=require" -c "DO \$\$ BEGIN CREATE TYPE message_status AS ENUM ('PENDING', 'DELIVERED', 'FAILED'); EXCEPTION WHEN duplicate_object THEN null; END \$\$; CREATE TABLE IF NOT EXISTS metadata (received_message_id varchar(40) PRIMARY KEY, sent_message_id varchar(40), sender varchar(30), receiver varchar(30), hash_of_order varchar(1000), time_received timestamptz, delivery_status message_status, failure_reason varchar(1000)); GRANT ALL ON metadata TO azure_pg_admin; ALTER TABLE metadata OWNER TO azure_pg_admin; ALTER TYPE message_status OWNER TO azure_pg_admin" + psql "host=$(terraform output -raw database_hostname) port=5432 dbname=postgres user=cdcti-github sslmode=require" -c "DO \$\$ BEGIN CREATE TYPE message_status AS ENUM ('PENDING', 'DELIVERED', 'FAILED'); EXCEPTION WHEN duplicate_object THEN null; END \$\$; CREATE TABLE IF NOT EXISTS metadata (received_message_id varchar(40) PRIMARY KEY, sent_message_id varchar(40), sender varchar(30), receiver varchar(30), hash_of_order varchar(1000), time_received timestamptz, time_delivered timestamptz, delivery_status message_status, failure_reason varchar(1000)); GRANT ALL ON metadata TO azure_pg_admin; ALTER TABLE metadata OWNER TO azure_pg_admin; ALTER TYPE message_status OWNER TO azure_pg_admin" - id: export-terraform-output name: Export Terraform Output diff --git a/e2e/src/test/groovy/gov/hhs/cdc/trustedintermediary/e2e/ResultTest.groovy b/e2e/src/test/groovy/gov/hhs/cdc/trustedintermediary/e2e/ResultTest.groovy index 8f0b5d019..d42f0b473 100644 --- a/e2e/src/test/groovy/gov/hhs/cdc/trustedintermediary/e2e/ResultTest.groovy +++ b/e2e/src/test/groovy/gov/hhs/cdc/trustedintermediary/e2e/ResultTest.groovy @@ -7,7 +7,9 @@ import java.nio.file.Path class ResultTest extends Specification { def resultClient = new EndpointClient("/v1/etor/results") + def labResultJsonFileString = Files.readString(Path.of("../examples/MN/004_MN_ORU_R01_NBS_1_translation_from_initial_hl7_ingestion.fhir")) + def submissionId = "submissionId" def setup() { diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadata.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadata.java index 9daaa8172..93f7c4c15 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadata.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadata.java @@ -10,6 +10,7 @@ * @param sender The name of the sender of the message. * @param receiver The name of the receiver of the message. * @param timeReceived The time the message was received. + * @param timeDelivered The time the message was delivered. * @param hash The hash of the message. * @param deliveryStatus the status of the message based on an enum */ @@ -19,6 +20,7 @@ public record PartnerMetadata( String sender, String receiver, Instant timeReceived, + Instant timeDelivered, String hash, PartnerMetadataStatus deliveryStatus, String failureReason) { @@ -34,17 +36,27 @@ public PartnerMetadata( String receivedSubmissionId, String sender, Instant timeReceived, + Instant timeDelivered, String hash, PartnerMetadataStatus deliveryStatus) { - this(receivedSubmissionId, null, sender, null, timeReceived, hash, deliveryStatus, null); + this( + receivedSubmissionId, + null, + sender, + null, + timeReceived, + timeDelivered, + hash, + deliveryStatus, + null); } public PartnerMetadata(String receivedSubmissionId, String hash) { - this(receivedSubmissionId, null, null, null, null, hash, null, null); + this(receivedSubmissionId, null, null, null, null, null, hash, null, null); } public PartnerMetadata(String receivedSubmissionId, PartnerMetadataStatus deliveryStatus) { - this(receivedSubmissionId, null, null, null, null, null, deliveryStatus, null); + this(receivedSubmissionId, null, null, null, null, null, null, deliveryStatus, null); } public PartnerMetadata withSentSubmissionId(String sentSubmissionId) { @@ -54,6 +66,7 @@ public PartnerMetadata withSentSubmissionId(String sentSubmissionId) { this.sender, this.receiver, this.timeReceived, + this.timeDelivered, this.hash, this.deliveryStatus, this.failureReason); @@ -66,6 +79,20 @@ public PartnerMetadata withReceiver(String receiver) { this.sender, receiver, this.timeReceived, + this.timeDelivered, + this.hash, + this.deliveryStatus, + this.failureReason); + } + + public PartnerMetadata withTimeDelivered(Instant timeDelivered) { + return new PartnerMetadata( + this.receivedSubmissionId, + this.sentSubmissionId, + this.sender, + this.receiver, + this.timeReceived, + timeDelivered, this.hash, this.deliveryStatus, this.failureReason); @@ -78,6 +105,7 @@ public PartnerMetadata withDeliveryStatus(PartnerMetadataStatus deliveryStatus) this.sender, this.receiver, this.timeReceived, + this.timeDelivered, this.hash, deliveryStatus, this.failureReason); @@ -90,6 +118,7 @@ public PartnerMetadata withFailureMessage(String failureMessage) { this.sender, this.receiver, this.timeReceived, + this.timeDelivered, this.hash, this.deliveryStatus, failureMessage); diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataOrchestrator.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataOrchestrator.java index c386aaf35..ec64e68bc 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataOrchestrator.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataOrchestrator.java @@ -44,7 +44,6 @@ public void updateMetadataForReceivedOrder(String receivedSubmissionId, String o String sender; Instant timeReceived; - try { String bearerToken = rsclient.getRsToken(); String responseBody = @@ -78,6 +77,7 @@ public void updateMetadataForReceivedOrder(String receivedSubmissionId, String o receivedSubmissionId, sender, timeReceived, + null, orderHash, PartnerMetadataStatus.PENDING); partnerMetadataStorage.saveMetadata(partnerMetadata); @@ -128,6 +128,7 @@ public Optional getMetadata(String receivedSubmissionId) String receiver; String rsStatus; String rsMessage = ""; + String timeDelivered; try { String bearerToken = rsclient.getRsToken(); String responseBody = @@ -136,6 +137,7 @@ public Optional getMetadata(String receivedSubmissionId) receiver = parsedResponseBody[0]; rsStatus = parsedResponseBody[1]; rsMessage = parsedResponseBody[2]; + timeDelivered = parsedResponseBody[3]; } catch (ReportStreamEndpointClientException | FormatterProcessingException e) { throw new PartnerMetadataException( "Unable to retrieve metadata from RS history API", e); @@ -148,6 +150,8 @@ public Optional getMetadata(String receivedSubmissionId) if (ourStatus == PartnerMetadataStatus.FAILED) { partnerMetadata = partnerMetadata.withFailureMessage(rsMessage); + } else if (ourStatus == PartnerMetadataStatus.DELIVERED && timeDelivered != null) { + partnerMetadata = partnerMetadata.withTimeDelivered(Instant.parse(timeDelivered)); } partnerMetadataStorage.saveMetadata(partnerMetadata); @@ -214,6 +218,7 @@ String[] getDataFromReportStream(String responseBody) throws FormatterProcessing // { // ... // "overallStatus": "Waiting to Deliver", + // "actualCompletionAt": "2023-10-24T19:48:26.921Z" // ... // "destinations" : [ { // ... @@ -265,7 +270,16 @@ String[] getDataFromReportStream(String responseBody) throws FormatterProcessing "Unable to extract failure reason due to unexpected format", e); } - return new String[] {receiver, overallStatus, errorMessages.toString()}; + String timeDelivered = null; + try { + + timeDelivered = (String) responseObject.get("actualCompletionAt"); + } catch (Exception e) { + throw new FormatterProcessingException( + "Unable to extract timeDelivered due to unexpected format", e); + } + + return new String[] {receiver, overallStatus, errorMessages.toString(), timeDelivered}; } PartnerMetadataStatus ourStatusFromReportStreamStatus(String rsStatus) { diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/DatabasePartnerMetadataStorage.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/DatabasePartnerMetadataStorage.java index 63d1c8475..15659c27a 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/DatabasePartnerMetadataStorage.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/DatabasePartnerMetadataStorage.java @@ -46,6 +46,7 @@ public void saveMetadata(final PartnerMetadata metadata) throws PartnerMetadataE metadata.receiver(), metadata.hash(), metadata.timeReceived(), + metadata.timeDelivered(), metadata.deliveryStatus(), metadata.failureReason()); } catch (SQLException e) { diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/DbDao.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/DbDao.java index 5483af15f..5e3f2afca 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/DbDao.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/DbDao.java @@ -15,6 +15,7 @@ void upsertMetadata( String receiver, String hash, Instant timeReceived, + Instant timeDelivered, PartnerMetadataStatus deliveryStatus, String failureReason) throws SQLException; diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/PostgresDao.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/PostgresDao.java index d2ae2ccf2..4a603ee0f 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/PostgresDao.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/database/PostgresDao.java @@ -78,6 +78,7 @@ public synchronized void upsertMetadata( String receiver, String hash, Instant timeReceived, + Instant timeDelivered, PartnerMetadataStatus deliveryStatus, String failureReason) throws SQLException { @@ -86,8 +87,8 @@ public synchronized void upsertMetadata( PreparedStatement statement = conn.prepareStatement( """ - INSERT INTO metadata VALUES (?, ?, ?, ?, ?, ?, ?, ?) - ON CONFLICT (received_message_id) DO UPDATE SET receiver = EXCLUDED.receiver, sent_message_id = EXCLUDED.sent_message_id, delivery_status = EXCLUDED.delivery_status, failure_reason = EXCLUDED.failure_reason + INSERT INTO metadata VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT (received_message_id) DO UPDATE SET receiver = EXCLUDED.receiver, sent_message_id = EXCLUDED.sent_message_id, time_delivered = EXCLUDED.time_delivered, delivery_status = EXCLUDED.delivery_status, failure_reason = EXCLUDED.failure_reason """)) { statement.setString(1, receivedSubmissionId); @@ -96,20 +97,27 @@ ON CONFLICT (received_message_id) DO UPDATE SET receiver = EXCLUDED.receiver, se statement.setString(4, receiver); statement.setString(5, hash); - Timestamp timestamp = null; + Timestamp timestampReceived = null; if (timeReceived != null) { - timestamp = Timestamp.from(timeReceived); + timestampReceived = Timestamp.from(timeReceived); } - statement.setTimestamp(6, timestamp); + statement.setTimestamp(6, timestampReceived); + + Timestamp timestampDelivered = null; + + if (timeDelivered != null) { + timestampDelivered = Timestamp.from(timeDelivered); + } + statement.setTimestamp(7, timestampDelivered); String deliveryStatusString = null; if (deliveryStatus != null) { deliveryStatusString = deliveryStatus.toString(); } - statement.setObject(7, deliveryStatusString, Types.OTHER); + statement.setObject(8, deliveryStatusString, Types.OTHER); - statement.setString(8, failureReason); + statement.setString(9, failureReason); statement.executeUpdate(); } @@ -157,9 +165,15 @@ public synchronized PartnerMetadata fetchMetadata(String submissionId) throws SQ private PartnerMetadata partnerMetadataFromResultSet(ResultSet resultSet) throws SQLException { Instant timeReceived = null; - Timestamp timestamp = resultSet.getTimestamp("time_received"); - if (timestamp != null) { - timeReceived = timestamp.toInstant(); + Instant timeDelivered = null; + Timestamp timestampReceived = resultSet.getTimestamp("time_received"); + Timestamp timestampDelivered = resultSet.getTimestamp("time_delivered"); + if (timestampReceived != null) { + timeReceived = timestampReceived.toInstant(); + } + + if (timestampDelivered != null) { + timeDelivered = timestampDelivered.toInstant(); } return new PartnerMetadata( @@ -168,6 +182,7 @@ private PartnerMetadata partnerMetadataFromResultSet(ResultSet resultSet) throws resultSet.getString("sender"), resultSet.getString("receiver"), timeReceived, + timeDelivered, resultSet.getString("hash_of_order"), PartnerMetadataStatus.valueOf(resultSet.getString("delivery_status")), resultSet.getString("failure_reason")); diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverter.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverter.java index ef43d1406..ec247b993 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverter.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverter.java @@ -217,15 +217,22 @@ public FhirMetadata extractPublicMetadataToOperationOutcome( .add(createInformationIssueComponent("receiver name", metadata.receiver())); String orderIngestion = null; + String orderDelivered = null; if (metadata.timeReceived() != null) { orderIngestion = metadata.timeReceived().toString(); } + if (metadata.timeDelivered() != null) { + orderDelivered = metadata.timeDelivered().toString(); + } operation .getIssue() .add(createInformationIssueComponent("order ingestion", orderIngestion)); - operation.getIssue().add(createInformationIssueComponent("payload hash", metadata.hash())); + operation.getIssue().add(createInformationIssueComponent("payload hash", metadata.hash())); + operation + .getIssue() + .add(createInformationIssueComponent("order delivered", orderDelivered)); operation .getIssue() .add( diff --git a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/localfile/MockRSEndpointClient.java b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/localfile/MockRSEndpointClient.java index 0cc24c8ef..92205613d 100644 --- a/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/localfile/MockRSEndpointClient.java +++ b/etor/src/main/java/gov/hhs/cdc/trustedintermediary/external/localfile/MockRSEndpointClient.java @@ -46,6 +46,7 @@ public String requestHistoryEndpoint(String submissionId, String bearerToken) { { "timestamp" : "2020-01-01T00:00:00.000Z", "sender" : "flexion.simulated-hospital", + "actualCompletionAt" : "2023-10-24T19:48:26.921Z", "overallStatus": "Not Delivering", "destinations": [{ "organization_id": "flexion", diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy index a62678b52..1e0ac9e1d 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/EtorDomainRegistrationTest.groovy @@ -381,7 +381,7 @@ class EtorDomainRegistrationTest extends Specification { request.setPathParams(["id": "metadataId"]) def mockPartnerMetadataOrchestrator = Mock(PartnerMetadataOrchestrator) - mockPartnerMetadataOrchestrator.getMetadata(_ as String) >> Optional.ofNullable(new PartnerMetadata("receivedSubmissionId", "sender", Instant.now(), "hash", PartnerMetadataStatus.DELIVERED)) + mockPartnerMetadataOrchestrator.getMetadata(_ as String) >> Optional.ofNullable(new PartnerMetadata("receivedSubmissionId", "sender", Instant.now(), null, "hash", PartnerMetadataStatus.DELIVERED)) TestApplicationContext.register(PartnerMetadataOrchestrator, mockPartnerMetadataOrchestrator) def mockResponseHelper = Mock(DomainResponseHelper) diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataOrchestratorTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataOrchestratorTest.groovy index 56d556948..4db161142 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataOrchestratorTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataOrchestratorTest.groovy @@ -40,13 +40,14 @@ class PartnerMetadataOrchestratorTest extends Specification { def receivedSubmissionId = "receivedSubmissionId" def sender = "senderName" def timestamp = "2020-01-01T00:00:00.000Z" + def timeDelivered = "2020-01-02T00:00:00.000Z" def hashCode = "123" def bearerToken = "token" - def rsHistoryApiResponse = "{\"sender\": \"${sender}\", \"timestamp\": \"${timestamp}\"}" + def rsHistoryApiResponse = "{\"actualCompletionAt\": \"2023-10-24T19:48:26.921Z\",\"sender\": \"${sender}\", \"timestamp\": \"${timestamp}\"}" def deliveryStatus = PartnerMetadataStatus.PENDING - mockFormatter.convertJsonToObject(rsHistoryApiResponse, _ as TypeReference) >> [sender: sender, timestamp: timestamp] + mockFormatter.convertJsonToObject(rsHistoryApiResponse, _ as TypeReference) >> [sender: sender, timestamp: timestamp, actualCompletionAt: timeDelivered] when: PartnerMetadataOrchestrator.getInstance().updateMetadataForReceivedOrder(receivedSubmissionId, hashCode) @@ -54,7 +55,7 @@ class PartnerMetadataOrchestratorTest extends Specification { then: 1 * mockClient.getRsToken() >> bearerToken 1 * mockClient.requestHistoryEndpoint(receivedSubmissionId, bearerToken) >> rsHistoryApiResponse - 1 * mockPartnerMetadataStorage.saveMetadata(new PartnerMetadata(receivedSubmissionId, sender, Instant.parse(timestamp), hashCode, deliveryStatus)) + 1 * mockPartnerMetadataStorage.saveMetadata(new PartnerMetadata(receivedSubmissionId, sender, Instant.parse(timestamp), null, hashCode, deliveryStatus)) } def "updateMetadataForSentOrder test case when sentSubmissionId is null"() { @@ -149,7 +150,7 @@ class PartnerMetadataOrchestratorTest extends Specification { given: def receivedSubmissionId = "receivedSubmissionId" def sentSubmissionId = "sentSubmissionId" - def partnerMetadata = new PartnerMetadata(receivedSubmissionId, "sender", Instant.now(), "hash", PartnerMetadataStatus.PENDING) + def partnerMetadata = new PartnerMetadata(receivedSubmissionId, "sender", Instant.now(), null, "hash", PartnerMetadataStatus.PENDING) def updatedPartnerMetadata = partnerMetadata.withSentSubmissionId(sentSubmissionId) when: @@ -176,7 +177,7 @@ class PartnerMetadataOrchestratorTest extends Specification { given: def receivedSubmissionId = "receivedSubmissionId" def sentSubmissionId = "sentSubmissionId" - def partnerMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, "sender", null, Instant.now(), "hash", PartnerMetadataStatus.PENDING, "failureReason") + def partnerMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, "sender", null, Instant.now(), null, "hash", PartnerMetadataStatus.PENDING, "failureReason") mockPartnerMetadataStorage.readMetadata(receivedSubmissionId) >> Optional.of(partnerMetadata) mockClient.getRsToken() >> "token" @@ -194,7 +195,7 @@ class PartnerMetadataOrchestratorTest extends Specification { def receivedSubmissionId = "receivedSubmissionId" def sentSubmissionId = "sentSubmissionId" def rsHistoryApiResponse = "{\"destinations\": [{\"organization_id\": \"org\", \"service\": \"service\"}]}" - def partnerMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, "sender", null, Instant.now(), "hash", PartnerMetadataStatus.PENDING, "failureReason") + def partnerMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, "sender", null, Instant.now(), null, "hash", PartnerMetadataStatus.PENDING, "failureReason") mockPartnerMetadataStorage.readMetadata(receivedSubmissionId) >> Optional.of(partnerMetadata) mockClient.getRsToken() >> "token" @@ -211,7 +212,7 @@ class PartnerMetadataOrchestratorTest extends Specification { def "getMetadata retrieves metadata successfully with the sender already filled"() { given: def receivedSubmissionId = "receivedSubmissionId" - def metadata = new PartnerMetadata(receivedSubmissionId, "sentSubmissionId", "sender", "receiver", Instant.now(), "hash", PartnerMetadataStatus.DELIVERED, null) + def metadata = new PartnerMetadata(receivedSubmissionId, "sentSubmissionId", "sender", "receiver", Instant.now(), null, "hash", PartnerMetadataStatus.DELIVERED, null) when: def result = PartnerMetadataOrchestrator.getInstance().getMetadata(receivedSubmissionId) @@ -226,7 +227,7 @@ class PartnerMetadataOrchestratorTest extends Specification { def "getMetadata retrieves metadata successfully when receiver is present and sentSubmissionId is missing"() { given: def receivedSubmissionId = "receivedSubmissionId" - def metadata = new PartnerMetadata(receivedSubmissionId, null, "sender", "receiver", Instant.now(), "hash", PartnerMetadataStatus.DELIVERED, null) + def metadata = new PartnerMetadata(receivedSubmissionId, null, "sender", "receiver", Instant.now(), null, "hash", PartnerMetadataStatus.DELIVERED, null) when: def result = PartnerMetadataOrchestrator.getInstance().getMetadata(receivedSubmissionId) @@ -243,16 +244,18 @@ class PartnerMetadataOrchestratorTest extends Specification { def sentSubmissionId = "sentSubmissionId" def sender = "senderName" def timestamp = Instant.now() + def timeDelivered = Instant.now() def hashCode = "123" def bearerToken = "token" - def rsHistoryApiResponse = "{\"destinations\": [{\"organization_id\": \"org\", \"service\": \"service\"}]}" - def missingReceiverMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, null, timestamp, hashCode, PartnerMetadataStatus.DELIVERED, "") - def expectedMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, "org.service", timestamp, hashCode, PartnerMetadataStatus.DELIVERED, "") + def rsHistoryApiResponse = "{\"actualCompletionAt\": \"2023-10-24T19:48:26.921Z\",\"destinations\": [{\"organization_id\": \"org\", \"service\": \"service\"}]}" + def missingReceiverMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, null, timestamp, timeDelivered, hashCode, PartnerMetadataStatus.DELIVERED, "") + def expectedMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, "org.service", timestamp, timeDelivered, hashCode, PartnerMetadataStatus.DELIVERED, "") mockClient.getRsToken() >> bearerToken mockClient.requestHistoryEndpoint(sentSubmissionId, bearerToken) >> rsHistoryApiResponse mockFormatter.convertJsonToObject(rsHistoryApiResponse, _ as TypeReference) >> [ overallStatus: "Delivered", + actualCompletionAt: timeDelivered.toString(), destinations: [ [organization_id: "org", service: "service"] ], @@ -279,8 +282,8 @@ class PartnerMetadataOrchestratorTest extends Specification { def hashCode = "123" def bearerToken = "token" def rsHistoryApiResponse = "{\"destinations\": [{\"organization_id\": \"org\", \"service\": \"service\"}]}" - def missingReceiverMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timestamp, hashCode, PartnerMetadataStatus.PENDING, null) - def expectedMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timestamp, hashCode, PartnerMetadataStatus.FAILED, "") + def missingReceiverMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timestamp, null, hashCode, PartnerMetadataStatus.PENDING, null) + def expectedMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timestamp, null, hashCode, PartnerMetadataStatus.FAILED, "") mockClient.getRsToken() >> bearerToken mockClient.requestHistoryEndpoint(sentSubmissionId, bearerToken) >> rsHistoryApiResponse @@ -309,16 +312,18 @@ class PartnerMetadataOrchestratorTest extends Specification { def sender = "senderName" def receiver = "org.service" def timestamp = Instant.now() + def timeDelivered = Instant.now() def hashCode = "123" def bearerToken = "token" def rsHistoryApiResponse = "whatever" - def missingReceiverMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timestamp, hashCode, PartnerMetadataStatus.PENDING, null) - def expectedMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timestamp, hashCode, PartnerMetadataStatus.DELIVERED, null) + def missingReceiverMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timestamp, timeDelivered, hashCode, PartnerMetadataStatus.PENDING, null) + def expectedMetadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timestamp, timeDelivered, hashCode, PartnerMetadataStatus.DELIVERED, null) mockClient.getRsToken() >> bearerToken mockClient.requestHistoryEndpoint(sentSubmissionId, bearerToken) >> rsHistoryApiResponse mockFormatter.convertJsonToObject(rsHistoryApiResponse, _ as TypeReference) >> [ overallStatus: "Delivered", + actualCompletionAt: timeDelivered.toString(), destinations: [ [organization_id: "org", service: "service"], ], @@ -343,7 +348,7 @@ class PartnerMetadataOrchestratorTest extends Specification { given: def submissionId = "13425" def metadataStatus = PartnerMetadataStatus.FAILED - def optional = Optional.of(new PartnerMetadata("","","","",Instant.now(),"",PartnerMetadataStatus.PENDING, "Bad Message")) + def optional = Optional.of(new PartnerMetadata("","","","",Instant.now(),null, "",PartnerMetadataStatus.PENDING, "Bad Message")) mockPartnerMetadataStorage.readMetadata(submissionId) >> optional when: @@ -359,7 +364,7 @@ class PartnerMetadataOrchestratorTest extends Specification { given: def submissionId = "13425" def metadataStatus = PartnerMetadataStatus.FAILED - def optional = Optional.of(new PartnerMetadata("","","","",Instant.now(),"",metadataStatus, null)) + def optional = Optional.of(new PartnerMetadata("","","","",Instant.now(), null, "",metadataStatus, null)) mockPartnerMetadataStorage.readMetadata(submissionId) >> optional when: @@ -475,6 +480,17 @@ class PartnerMetadataOrchestratorTest extends Specification { then: thrown(FormatterProcessingException) + + when: + def jsonWithBadCompletionDate = "{\"actualCompletionAt\": 123, \"destinations\":[{\"organization_id\":\"org_id\", \"service\":\"service\"}], \"overallStatus\": \"Error\"}" + PartnerMetadataOrchestrator.getInstance().getDataFromReportStream(jsonWithBadCompletionDate) + then: + thrown(FormatterProcessingException) + when: + def jsonWithBadStatus = "{\"overallStatus\": 123, \"destinations\":[{\"organization_id\":\"org_id\", \"service\":\"service\"}]}" + PartnerMetadataOrchestrator.getInstance().getDataFromReportStream(jsonWithBadStatus) + then: + thrown(FormatterProcessingException) } def "ourStatusFromReportStreamStatus returns FAILED"() { @@ -526,11 +542,10 @@ class PartnerMetadataOrchestratorTest extends Specification { def failure = "This thing is bonked" def status = PartnerMetadataStatus.PENDING def mockMetadata = [ - new PartnerMetadata("123456789", null, senderName, "receiver_name", Instant.now(), null, status, failure) + new PartnerMetadata("123456789", null, senderName, "receiver_name", Instant.now(), null, null, status, failure) ] mockPartnerMetadataStorage.readMetadataForSender(senderName) >> mockMetadata - when: def result = PartnerMetadataOrchestrator.getInstance().getConsolidatedMetadata(senderName) diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataTest.groovy index b70823c7e..aea2f1870 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/etor/metadata/partner/PartnerMetadataTest.groovy @@ -24,19 +24,21 @@ class PartnerMetadataTest extends Specification { def sender = "sender" def receiver = "receiver" def timeReceived = Instant.now() + def timeDelivered = Instant.now() def hash = "abcd" def status = PartnerMetadataStatus.DELIVERED def failureReason = "failure reason" when: - def metadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timeReceived, hash, PartnerMetadataStatus.DELIVERED, failureReason) + def metadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timeReceived, timeDelivered, hash, PartnerMetadataStatus.DELIVERED, failureReason) then: metadata.receivedSubmissionId() == receivedSubmissionId metadata.sentSubmissionId() == sentSubmissionId metadata.sender() == sender metadata.receiver() == receiver + metadata.timeDelivered() == timeDelivered metadata.timeReceived() == timeReceived metadata.hash() == hash metadata.deliveryStatus() == status @@ -48,11 +50,12 @@ class PartnerMetadataTest extends Specification { def receivedSubmissionId = "receivedSubmissionId" def sender = "sender" def timeReceived = Instant.now() + def timeDelivered = Instant.now() def hash = "abcd" def status = PartnerMetadataStatus.DELIVERED when: - def metadata = new PartnerMetadata(receivedSubmissionId, sender, timeReceived, hash, PartnerMetadataStatus.DELIVERED) + def metadata = new PartnerMetadata(receivedSubmissionId, sender, timeReceived, timeDelivered, hash, PartnerMetadataStatus.DELIVERED) then: metadata.receivedSubmissionId() == receivedSubmissionId @@ -60,6 +63,7 @@ class PartnerMetadataTest extends Specification { metadata.sender() == sender metadata.receiver() == null metadata.timeReceived() == timeReceived + metadata.timeDelivered() == timeDelivered metadata.hash() == hash metadata.deliveryStatus() == status } @@ -78,6 +82,7 @@ class PartnerMetadataTest extends Specification { metadata.sender() == null metadata.receiver() == null metadata.timeReceived() == null + metadata.timeDelivered() == null metadata.hash() == hash //Status should default to PENDING metadata.deliveryStatus() == PartnerMetadataStatus.PENDING @@ -97,6 +102,7 @@ class PartnerMetadataTest extends Specification { metadata.sender() == null metadata.receiver() == null metadata.timeReceived() == null + metadata.timeDelivered() == null metadata.hash() == null metadata.deliveryStatus() == deliverStatus } @@ -111,7 +117,7 @@ class PartnerMetadataTest extends Specification { def hash = "abcd" def status = PartnerMetadataStatus.DELIVERED def failureReason = "DogCow goes boom" - def metadata = new PartnerMetadata(receivedSubmissionId, null, sender, null, timeReceived, hash, status, failureReason) + def metadata = new PartnerMetadata(receivedSubmissionId, null, sender, null, timeReceived, null, hash, status, failureReason) when: def updatedMetadata = metadata.withSentSubmissionId(sentSubmissionId).withReceiver(receiver) @@ -133,9 +139,10 @@ class PartnerMetadataTest extends Specification { def sender = "sender" def receiver = "receiver" def timeReceived = Instant.now() + def timeDelivered = null def hash = "abcd" def failureReason = "DogCow goes boom" - def metadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timeReceived, hash, PartnerMetadataStatus.PENDING, failureReason) + def metadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timeReceived, timeDelivered, hash, PartnerMetadataStatus.PENDING, failureReason) when: def newStatus = PartnerMetadataStatus.DELIVERED @@ -147,8 +154,35 @@ class PartnerMetadataTest extends Specification { updatedMetadata.sender() == sender updatedMetadata.receiver() == receiver updatedMetadata.timeReceived() == timeReceived + updatedMetadata.timeDelivered() == null updatedMetadata.hash() == hash updatedMetadata.deliveryStatus() == newStatus updatedMetadata.failureReason() == failureReason } + + def "test withTimeDelivered to update PartnerMetadata"() { + given: + def receivedSubmissionId = "receivedSubmissionId" + def sentSubmissionId = "sentSubmissionId" + def sender = "sender" + def receiver = "receiver" + def timeReceived = Instant.now() + def timeDelivered = Instant.now() + def hash = "abcd" + def failureReason = "DogCow goes boom" + def metadata = new PartnerMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, timeReceived, null, hash, PartnerMetadataStatus.PENDING, failureReason) + + when: + def updatedMetadata = metadata.withTimeDelivered(timeDelivered) + + then: + updatedMetadata.receivedSubmissionId() == receivedSubmissionId + updatedMetadata.sentSubmissionId() == sentSubmissionId + updatedMetadata.sender() == sender + updatedMetadata.receiver() == receiver + updatedMetadata.timeReceived() == timeReceived + updatedMetadata.timeDelivered() == timeDelivered + updatedMetadata.hash() == hash + updatedMetadata.failureReason() == failureReason + } } diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/azure/AzureStorageAccountPartnerMetadataStorageTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/azure/AzureStorageAccountPartnerMetadataStorageTest.groovy index c6d0786ca..864ef607b 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/azure/AzureStorageAccountPartnerMetadataStorageTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/azure/AzureStorageAccountPartnerMetadataStorageTest.groovy @@ -30,7 +30,7 @@ class AzureStorageAccountPartnerMetadataStorageTest extends Specification { def expectedHash = "abcd" PartnerMetadataStatus status = PartnerMetadataStatus.PENDING - PartnerMetadata expectedMetadata = new PartnerMetadata(expectedReceivedSubmissionId, expectedSentSubmissionId, expectedSender, expectedReceiver, expectedTimestamp, expectedHash, status, null) + PartnerMetadata expectedMetadata = new PartnerMetadata(expectedReceivedSubmissionId, expectedSentSubmissionId, expectedSender, expectedReceiver, expectedTimestamp, null, expectedHash, status, null) String simulatedMetadataJson = """{ "receivedSubmissionId": "${expectedReceivedSubmissionId}", @@ -100,7 +100,7 @@ class AzureStorageAccountPartnerMetadataStorageTest extends Specification { def "successfully save metadata"() { given: - PartnerMetadata partnerMetadata = new PartnerMetadata("receivedSubmissionId", "sentSubmissionId", "sender", "receiver", Instant.now(), "abcd", PartnerMetadataStatus.DELIVERED, null) + PartnerMetadata partnerMetadata = new PartnerMetadata("receivedSubmissionId", "sentSubmissionId", "sender", "receiver", Instant.now(), null, "abcd", PartnerMetadataStatus.DELIVERED, null) def mockBlobClient = Mock(BlobClient) def azureClient = Mock(AzureClient) @@ -122,7 +122,7 @@ class AzureStorageAccountPartnerMetadataStorageTest extends Specification { def "failed to save metadata"() { given: - PartnerMetadata partnerMetadata = new PartnerMetadata("receivedSubmissionId", "sentSubmissionId", "sender", "receiver", Instant.now(), "abcd", PartnerMetadataStatus.DELIVERED, null) + PartnerMetadata partnerMetadata = new PartnerMetadata("receivedSubmissionId", "sentSubmissionId", "sender", "receiver", Instant.now(), null, "abcd", PartnerMetadataStatus.DELIVERED, null) def mockBlobClient = Mock(BlobClient) mockBlobClient.upload(_ as BinaryData, true) >> { throw new AzureException("upload failed") } diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/database/DatabasePartnerMetadataStorageTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/database/DatabasePartnerMetadataStorageTest.groovy index 08c25cd28..b2b425652 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/database/DatabasePartnerMetadataStorageTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/database/DatabasePartnerMetadataStorageTest.groovy @@ -28,7 +28,7 @@ class DatabasePartnerMetadataStorageTest extends Specification { def "readMetadata happy path works"() { given: def receivedSubmissionId = "receivedSubmissionId" - def mockMetadata = new PartnerMetadata(receivedSubmissionId, "sentSubmissionId", "sender", "receiver", Instant.now(), "hash", PartnerMetadataStatus.PENDING, null) + def mockMetadata = new PartnerMetadata(receivedSubmissionId, "sentSubmissionId", "sender", "receiver", Instant.now(), Instant.now(), "hash", PartnerMetadataStatus.PENDING, null) def expectedResult = Optional.of(mockMetadata) mockDao.fetchMetadata(_ as String) >> mockMetadata @@ -61,6 +61,7 @@ class DatabasePartnerMetadataStorageTest extends Specification { "sender", "receiver", Instant.now(), + Instant.now(), "hash", PartnerMetadataStatus.PENDING, "DogCow failure" @@ -77,6 +78,7 @@ class DatabasePartnerMetadataStorageTest extends Specification { mockMetadata.receiver(), mockMetadata.hash(), mockMetadata.timeReceived(), + mockMetadata.timeDelivered(), mockMetadata.deliveryStatus(), mockMetadata.failureReason() ) @@ -91,6 +93,7 @@ class DatabasePartnerMetadataStorageTest extends Specification { "sender", "receiver", Instant.now(), + Instant.now(), "hash", PartnerMetadataStatus.FAILED, "DogCow failure" @@ -103,6 +106,7 @@ class DatabasePartnerMetadataStorageTest extends Specification { mockMetadata.receiver(), mockMetadata.hash(), mockMetadata.timeReceived(), + mockMetadata.timeDelivered(), mockMetadata.deliveryStatus(), mockMetadata.failureReason() ) >> { throw new SQLException("Something went wrong!") } diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/database/PostgresDaoTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/database/PostgresDaoTest.groovy index 48946200a..10ebfa331 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/database/PostgresDaoTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/database/PostgresDaoTest.groovy @@ -80,7 +80,7 @@ class PostgresDaoTest extends Specification { TestApplicationContext.injectRegisteredImplementations() when: - PostgresDao.getInstance().upsertMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, hash, timestamp, status, failureReason) + PostgresDao.getInstance().upsertMetadata(receivedSubmissionId, sentSubmissionId, sender, receiver, hash, timestamp, timestamp, status, failureReason) then: 1 * mockPreparedStatement.setString(1, receivedSubmissionId) @@ -89,8 +89,9 @@ class PostgresDaoTest extends Specification { 1 * mockPreparedStatement.setString(4, receiver) 1 * mockPreparedStatement.setString(5, hash) 1 * mockPreparedStatement.setTimestamp(6, Timestamp.from(timestamp)) - 1 * mockPreparedStatement.setObject(7, status.toString(), Types.OTHER) - 1 * mockPreparedStatement.setString(8, failureReason) + 1 * mockPreparedStatement.setTimestamp(7, Timestamp.from(timestamp)) + 1 * mockPreparedStatement.setObject(8, status.toString(), Types.OTHER) + 1 * mockPreparedStatement.setString(9, failureReason) 1 * mockPreparedStatement.executeUpdate() } @@ -103,7 +104,7 @@ class PostgresDaoTest extends Specification { TestApplicationContext.injectRegisteredImplementations() when: - PostgresDao.getInstance().upsertMetadata("mock_id_receiver", "mock_id_sender", "mock_sender", "mock_receiver", "mock_hash", Instant.now(), PartnerMetadataStatus.DELIVERED, "mock_failure_reason") + PostgresDao.getInstance().upsertMetadata("mock_id_receiver", "mock_id_sender", "mock_sender", "mock_receiver", "mock_hash", Instant.now(), Instant.now(), PartnerMetadataStatus.DELIVERED, "mock_failure_reason") then: thrown(SQLException) @@ -118,10 +119,10 @@ class PostgresDaoTest extends Specification { TestApplicationContext.injectRegisteredImplementations() when: - PostgresDao.getInstance().upsertMetadata("mock_id_receiver", "mock_id_sender", "mock_sender", "mock_receiver", "mock_hash", null, PartnerMetadataStatus.DELIVERED, "mock_failure_reason") + PostgresDao.getInstance().upsertMetadata("mock_id_receiver", "mock_id_sender", "mock_sender", "mock_receiver", "mock_hash", null, null, PartnerMetadataStatus.DELIVERED, "mock_failure_reason") then: - mockPreparedStatement.setTimestamp(_ as Integer, _) >> { Integer parameterIndex, Timestamp timestamp -> + mockPreparedStatement.setTimestamp(_ as Integer, _ as Timestamp) >> { Integer parameterIndex, Timestamp timestamp -> assert timestamp == null } } @@ -184,10 +185,12 @@ class PostgresDaoTest extends Specification { def receiver = "You'll get your just reward" Timestamp timestampForMock = Timestamp.from(Instant.parse("2024-01-03T15:45:33.30Z")) Instant timeReceived = timestampForMock.toInstant() + Timestamp mockDeliveredTimestamp = Timestamp.from(Instant.parse("2024-01-31T11:07:53.00Z")) + Instant timeDelivered = mockDeliveredTimestamp.toInstant() def hash = sender.hashCode().toString() def status = PartnerMetadataStatus.PENDING def reason = "It done Goofed" - def expected = new PartnerMetadata(receivedMessageId, sentMessageId, sender, receiver, timeReceived, hash, status, reason) + def expected = new PartnerMetadata(receivedMessageId, sentMessageId, sender, receiver, timeReceived, timeDelivered, hash, status, reason) mockDriver.getConnection(_ as String, _ as Properties) >> mockConn mockConn.prepareStatement(_ as String) >> mockPreparedStatement @@ -197,6 +200,7 @@ class PostgresDaoTest extends Specification { mockResultSet.getString("sender") >> sender mockResultSet.getString("receiver") >> receiver mockResultSet.getTimestamp("time_received") >> timestampForMock + mockResultSet.getTimestamp("time_delivered") >> mockDeliveredTimestamp mockResultSet.getString("hash_of_order") >> hash mockResultSet.getString("delivery_status") >> status.toString() mockResultSet.getString("failure_reason") >> reason @@ -234,8 +238,8 @@ class PostgresDaoTest extends Specification { def "fetchMetadataForSender retrieves a set of PartnerMetadata"() { given: def sender = "DogCow" - def expected1 = new PartnerMetadata("12345", "7890", sender, "You'll get your just reward", Instant.parse("2024-01-03T15:45:33.30Z"), sender.hashCode().toString(), PartnerMetadataStatus.PENDING, "It done Goofed") - def expected2 = new PartnerMetadata("doreyme", "fasole", sender, "receiver", Instant.now(), "gobeltygoook", PartnerMetadataStatus.DELIVERED, "cause I said so") + def expected1 = new PartnerMetadata("12345", "7890", sender, "You'll get your just reward", Instant.parse("2024-01-03T15:45:33.30Z"),Instant.parse("2024-01-03T15:45:33.30Z"), sender.hashCode().toString(), PartnerMetadataStatus.PENDING, "It done Goofed") + def expected2 = new PartnerMetadata("doreyme", "fasole", sender, "receiver", Instant.now(), Instant.now(), "gobeltygoook", PartnerMetadataStatus.DELIVERED, "cause I said so") mockDriver.getConnection(_ as String, _ as Properties) >> mockConn mockConn.prepareStatement(_ as String) >> mockPreparedStatement @@ -260,6 +264,10 @@ class PostgresDaoTest extends Specification { Timestamp.from(expected1.timeReceived()), Timestamp.from(expected2.timeReceived()) ] + mockResultSet.getTimestamp("time_delivered") >>> [ + Timestamp.from(expected1.timeDelivered()), + Timestamp.from(expected2.timeDelivered()) + ] mockResultSet.getString("hash_of_order") >>> [ expected1.hash(), expected2.hash() diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverterTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverterTest.groovy index d5003fcf9..8050d709e 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverterTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiOrderConverterTest.groovy @@ -308,7 +308,7 @@ class HapiOrderConverterTest extends Specification { def hash = "hash" def failureReason = "timed_out" PartnerMetadata metadata = new PartnerMetadata( - "receivedSubmissionId", "sentSubmissionId", sender, receiver, time, hash, PartnerMetadataStatus.DELIVERED, failureReason) + "receivedSubmissionId", "sentSubmissionId", sender, receiver, time, time, hash, PartnerMetadataStatus.DELIVERED, failureReason) when: def result = HapiOrderConverter.getInstance().extractPublicMetadataToOperationOutcome(metadata, "receivedSubmissionId").getUnderlyingOutcome() as OperationOutcome @@ -319,7 +319,8 @@ class HapiOrderConverterTest extends Specification { result.getIssue().get(1).diagnostics == receiver result.getIssue().get(2).diagnostics == time.toString() result.getIssue().get(3).diagnostics == hash - result.getIssue().get(4).diagnostics == PartnerMetadataStatus.DELIVERED.toString() - result.getIssue().get(5).diagnostics == failureReason + result.getIssue().get(4).diagnostics == time.toString() + result.getIssue().get(5).diagnostics == PartnerMetadataStatus.DELIVERED.toString() + result.getIssue().get(6).diagnostics == failureReason } } diff --git a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/localfile/FilePartnerMetadataStorageTest.groovy b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/localfile/FilePartnerMetadataStorageTest.groovy index 94cf00a6f..9874ce3c0 100644 --- a/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/localfile/FilePartnerMetadataStorageTest.groovy +++ b/etor/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/localfile/FilePartnerMetadataStorageTest.groovy @@ -26,7 +26,7 @@ class FilePartnerMetadataStorageTest extends Specification { given: def expectedReceivedSubmissionId = "receivedSubmissionId" def expectedSentSubmissionId = "receivedSubmissionId" - PartnerMetadata metadata = new PartnerMetadata(expectedReceivedSubmissionId, expectedSentSubmissionId, "sender", "receiver", Instant.parse("2023-12-04T18:51:48.941875Z"), "abcd", PartnerMetadataStatus.DELIVERED, null) + PartnerMetadata metadata = new PartnerMetadata(expectedReceivedSubmissionId, expectedSentSubmissionId, "sender", "receiver", Instant.parse("2023-12-04T18:51:48.941875Z"),Instant.parse("2023-12-04T18:51:48.941875Z"), "abcd", PartnerMetadataStatus.DELIVERED, null) TestApplicationContext.register(Formatter, Jackson.getInstance()) TestApplicationContext.injectRegisteredImplementations() @@ -41,7 +41,7 @@ class FilePartnerMetadataStorageTest extends Specification { def "saveMetadata throws PartnerMetadataException when unable to save file"() { given: - PartnerMetadata metadata = new PartnerMetadata("receivedSubmissionId", "sentSubmissionId","sender", "receiver", Instant.now(), "abcd", PartnerMetadataStatus.DELIVERED, null) + PartnerMetadata metadata = new PartnerMetadata("receivedSubmissionId", "sentSubmissionId","sender", "receiver", Instant.now(), Instant.now(), "abcd", PartnerMetadataStatus.DELIVERED, null) def mockFormatter = Mock(Formatter) mockFormatter.convertToJsonString(_ as PartnerMetadata) >> {throw new FormatterProcessingException("error", new Exception())} @@ -65,7 +65,7 @@ class FilePartnerMetadataStorageTest extends Specification { //write something to the hard drive so that the `readMetadata` in the when gets pass the file existence check def submissionId = "asljfaskljgalsjgjlas" - PartnerMetadata metadata = new PartnerMetadata(submissionId, null, null, null, null, null, null, null) + PartnerMetadata metadata = new PartnerMetadata(submissionId, null, null, null, null, null, null, null, null) FilePartnerMetadataStorage.getInstance().saveMetadata(metadata) when: @@ -86,8 +86,8 @@ class FilePartnerMetadataStorageTest extends Specification { def "readMetadataForSender returns a set of PartnerMetadata"() { given: def sender = "same_sender" - PartnerMetadata metadata2 = new PartnerMetadata("abcdefghi", null, sender, null, null, null, null, null) - PartnerMetadata metadata1 = new PartnerMetadata("123456789", null, sender, null, null, null, null, null) + PartnerMetadata metadata2 = new PartnerMetadata("abcdefghi", null, sender, null, null, null, null, null, null) + PartnerMetadata metadata1 = new PartnerMetadata("123456789", null, sender, null, null, null, null, null, null) TestApplicationContext.register(Formatter, Jackson.getInstance()) TestApplicationContext.injectRegisteredImplementations()