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

PRMT-3413 E2E testing - Unexpected Interaction ID and NHS number #21

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0ff49b1
[PRMT-3413] Add method to queue helper to check that a message does n…
joefong-nhs Jun 13, 2023
b746f75
[PRMT-3413] Add url of ehr out service to test config
joefong-nhs Jun 13, 2023
c72be7f
[PRMT-3413] Add asid code to the Gp2gp system class
joefong-nhs Jun 13, 2023
0264513
[PRMT-3413] Add an EhrRequestMessage class and its builder for making…
joefong-nhs Jun 13, 2023
83d6646
[PRMT-3413] Fixed the incoherent conversation ids in RCMR_IN010000UK0…
joefong-nhs Jun 13, 2023
73221e1
[PRMT-3413] Added two E2E tests, one for unrecognised interaction ID …
joefong-nhs Jun 13, 2023
e548cd8
[PRMT-3413] Allow health check to wait for 2xx response for at most 5…
joefong-nhs Jun 13, 2023
7266c1c
[PRMT-3413] Change the invalid interactionId used in test to make it …
joefong-nhs Jun 13, 2023
a2972cd
[PRMT-3413] Add test for Erroneous message: COPC continue request wit…
joefong-nhs Jun 13, 2023
ebaa402
[PRMT-3413] Bundled test cases into one ParameterizedTest
joefong-nhs Jun 14, 2023
c349de9
[PRMT-3413] Change healthcheck class to use LOGGER.info rather than s…
joefong-nhs Jun 14, 2023
e8c1fae
[PRMT-3413] Remove duplicated tests, minor fix on log wordings and te…
joefong-nhs Jun 14, 2023
a2f073b
[PRMT-3413] Minor fix on wordings
joefong-nhs Jun 14, 2023
6e37ee4
[PRMT-3413] Move the list of known asid codes to a static final field
joefong-nhs Jun 14, 2023
956dfa7
[PRMT-3413] Amended a misleading log message
joefong-nhs Jun 14, 2023
3f7a68d
[PRMT-3413] Amend incorrect LOGGER setting in new class
joefong-nhs Jun 14, 2023
f3cc475
[PRMT-3413] Address comments (change some final class to just public …
joefong-nhs Jun 15, 2023
8f6eaf9
[PRMT-3413] Address comments and add a static method getUuidAsUpperCa…
joefong-nhs Jun 15, 2023
a34a5c9
[PRMT-3413] Addressed PR comment (getUUIDAsUpperCaseString)
joefong-nhs Jun 28, 2023
161bc2d
[PRMT-3413] Address PR comment
joefong-nhs Jul 4, 2023
ea8bd7c
[PRMT-3413] Address PR comment https://github.com/nhsconnect/prm-repo…
joefong-nhs Jul 4, 2023
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
4 changes: 4 additions & 0 deletions src/test/java/uk/nhs/prm/deduction/e2e/TestConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ public String getEhrRepoUrl() {
return String.format("https://ehr-repo.%s.patient-deductions.nhs.uk/", getEnvSuffix());
}

public String getEhrOutUrl() {
return String.format("https://ehr-out-service.%s.patient-deductions.nhs.uk/", getEnvSuffix());
}

private String getAwsAccountNo() {
if (cachedAwsAccountNo == null) {
cachedAwsAccountNo = fetchAwsAccountNo();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package uk.nhs.prm.deduction.e2e.models;

import uk.nhs.prm.deduction.e2e.utility.Resources;

import java.util.UUID;

import static uk.nhs.prm.deduction.e2e.utility.TestUtils.getUUIDAsUpperCaseString;

public class ContinueRequestMessage {
private UUID conversationId;
private UUID messageId;
private String sourceGpOds;
private String destinationGpOds;
private String sourceGpAsid;
private String destinationGpAsid;

public ContinueRequestMessage(UUID conversationId, UUID messageId, String sourceGpOds, String destinationGpOds, String sourceGpAsid, String destinationGpAsid) {
this.conversationId = conversationId;
this.messageId = messageId;
this.sourceGpOds = sourceGpOds;
this.destinationGpOds = destinationGpOds;
this.sourceGpAsid = sourceGpAsid;
this.destinationGpAsid = destinationGpAsid;
}

public String toJsonString() {
return Resources.readTestResourceFile("COPC_IN000001UK01")
.replaceAll("DBC31D30-F984-11ED-A4C4-956AA80C6B4E", conversationId())
.replaceAll("DE304CA0-F984-11ED-808B-AC162D1F16F0", messageId())
.replaceAll("B85002", sourceGpOds)
.replaceAll("200000001613", sourceGpAsid)
.replaceAll("M85019", destinationGpOds)
.replaceAll("200000000149", destinationGpAsid);
}

public String conversationId() {
Copy link
Contributor

@AndyFlintNHS AndyFlintNHS Jun 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if it's worth us breaking the conversationId and messageId methods out into a static method on a utility class. This UUID as upper case string format is useful across more than just the continueRequestMessage class and rather than us duplicating a lot of code, having something like this might help:

    public static String getUuidAsUpperCaseString(UUID uuid) {
        return uuid.toString().toUpperCase();
    }

Which could be called in the code like this (using line 34 as an example):

.replaceAll("DBC31D30-F984-11ED-A4C4-956AA80C6B4E", getUuidAsUpperCaseString(conversationId))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I have added the static method getUuidAsUpperCaseString to TestUtils class and call it for conversation ids and message ids.
Later could you have a look and see if I did it right?
Because conversation id is a private field so I keep the getter methods, but now all those getter would call to our getUuidAsUpperCaseString :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest you don't even need the 'conversationId()' method at all. conversationId IS a private field as you say, but you don't need to use getters to reference private variables in the scope of the class where they're defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I overlooked this comment...
For conversationId(), in the e2e test that is a part that we need the conversation id from the message (the test use the conversation id to find an expected message in outbound queue), so I have kept the getter method for this purpose.

return getUUIDAsUpperCaseString(conversationId);
}

public String messageId() {
return getUUIDAsUpperCaseString(messageId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package uk.nhs.prm.deduction.e2e.models;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import uk.nhs.prm.deduction.e2e.TestConfiguration;
import uk.nhs.prm.deduction.e2e.utility.TestUtils;

import java.util.UUID;

public class ContinueRequestMessageBuilder {
private UUID conversationId;
private UUID messageId;
private String sourceGpOds;
private String destinationGpOds;
private String sourceGpAsid;
private String destinationGpAsid;

private static final Logger LOGGER = LogManager.getLogger(ContinueRequestMessageBuilder.class);

AndyFlintNHS marked this conversation as resolved.
Show resolved Hide resolved
public ContinueRequestMessageBuilder() {
withRandomlyGeneratedConversationId();
withRandomlyGeneratedMessageId();
withEhrSourceGp(Gp2GpSystem.REPO_DEV);
withEhrDestinationGp(Gp2GpSystem.TPP_PTL_INT);
}

public ContinueRequestMessageBuilder withConversationId(UUID conversationId) {
this.conversationId = conversationId;
return this;
}

public ContinueRequestMessageBuilder withRandomlyGeneratedConversationId() {
this.conversationId = UUID.randomUUID();
LOGGER.info("generated conversation id {}", conversationId);
return this;
}

public ContinueRequestMessageBuilder withEhrSourceAsRepo(TestConfiguration config) {
Gp2GpSystem repoInEnv = Gp2GpSystem.repoInEnv(config);
this.sourceGpOds = repoInEnv.odsCode();
this.sourceGpAsid = repoInEnv.asidCode();
return this;
}

public ContinueRequestMessageBuilder withEhrSourceGp(Gp2GpSystem ehrSourceGp) {
this.sourceGpOds = ehrSourceGp.odsCode();
this.sourceGpAsid = ehrSourceGp.asidCode();
return this;
}

public ContinueRequestMessageBuilder withEhrDestinationGp(Gp2GpSystem ehrDestinationGp) {
this.destinationGpOds = ehrDestinationGp.odsCode();
this.destinationGpAsid = ehrDestinationGp.asidCode();
return this;
}

public ContinueRequestMessageBuilder withMessageId(UUID messageId) {
this.messageId = messageId;
return this;
}

public ContinueRequestMessageBuilder withRandomlyGeneratedMessageId() {
this.messageId = UUID.randomUUID();
LOGGER.info("generated message id {}", messageId);
return this;
}

public ContinueRequestMessageBuilder withSourceGpOds(String sourceGpOds) {
this.sourceGpOds = sourceGpOds;
return this;
}

public ContinueRequestMessageBuilder withDestinationGpOds(String destinationGpOds) {
this.destinationGpOds = destinationGpOds;
return this;
}

public ContinueRequestMessageBuilder withSourceGpAsid(String sourceGpAsid) {
this.sourceGpAsid = sourceGpAsid;
return this;
}

public ContinueRequestMessageBuilder withDestinationGpAsid(String destinationGpAsid) {
this.destinationGpAsid = destinationGpAsid;
return this;
}

public ContinueRequestMessage build() {
return new ContinueRequestMessage(conversationId, messageId, sourceGpOds, destinationGpOds, sourceGpAsid, destinationGpAsid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package uk.nhs.prm.deduction.e2e.models;

import uk.nhs.prm.deduction.e2e.utility.Resources;

import java.util.UUID;

import static uk.nhs.prm.deduction.e2e.utility.TestUtils.getUUIDAsUpperCaseString;

public class EhrRequestMessage {
private final String nhsNumber;
private final String sourceGpOds;
private final String destinationGpOds;
private final String sourceGpAsid;
private final String destinationGpAsid;
private final UUID conversationId;
private final UUID messageId;

public EhrRequestMessage(String nhsNumber, String sourceGpOds, String destinationGpOds, String sourceGpAsid, String destinationGpAsid, UUID conversationId, UUID messageId) {
this.nhsNumber = nhsNumber;
this.sourceGpOds = sourceGpOds;
this.destinationGpOds = destinationGpOds;
this.sourceGpAsid = sourceGpAsid;
this.destinationGpAsid = destinationGpAsid;
this.conversationId = conversationId;
this.messageId = messageId;
}

public String toJsonString() {
return Resources.readTestResourceFile("RCMR_IN010000UK05")
.replaceAll("9692842304", nhsNumber)
.replaceAll("17a757f2-f4d2-444e-a246-9cb77bef7f22", conversationId())
.replaceAll("C445C720-B0EB-4E36-AF8A-48CD1CA5DE4F", messageId())
.replaceAll("B86041", sourceGpOds)
.replaceAll("200000001161", sourceGpAsid)
.replaceAll("A91720", destinationGpOds)
.replaceAll("200000000631", destinationGpAsid);
}

public String conversationId() {
return getUUIDAsUpperCaseString(conversationId);
}

public String messageId() {
return getUUIDAsUpperCaseString(messageId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package uk.nhs.prm.deduction.e2e.models;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import uk.nhs.prm.deduction.e2e.TestConfiguration;
import uk.nhs.prm.deduction.e2e.tests.Patient;
import uk.nhs.prm.deduction.e2e.utility.TestUtils;

import java.util.UUID;

public class EhrRequestMessageBuilder {
private String nhsNumber;
private String sourceGpOds;
private String destinationGpOds;
private String sourceGpAsid;
private String destinationGpAsid;
private UUID conversationId;
private UUID messageId;

private static final Logger LOGGER = LogManager.getLogger(EhrRequestMessageBuilder.class);

public EhrRequestMessageBuilder() {
withRandomlyGeneratedConversationId();
withRandomlyGeneratedMessageId();
withNhsNumber("9692842304"); // nhs number in test template file
withEhrSourceGp(Gp2GpSystem.REPO_DEV);
withEhrDestinationGp(Gp2GpSystem.TPP_PTL_INT);
}

public EhrRequestMessageBuilder withNhsNumber(String nhsNumber) {
this.nhsNumber = nhsNumber;
return this;
}

public EhrRequestMessageBuilder withPatient(Patient patient) {
return withNhsNumber(patient.nhsNumber());
}

public EhrRequestMessageBuilder withEhrSourceAsRepo(TestConfiguration config) {
Gp2GpSystem repoInEnv = Gp2GpSystem.repoInEnv(config);
this.sourceGpOds = repoInEnv.odsCode();
this.sourceGpAsid = repoInEnv.asidCode();
return this;
}

public EhrRequestMessageBuilder withEhrSourceGp(Gp2GpSystem ehrSourceGp) {
this.sourceGpOds = ehrSourceGp.odsCode();
this.sourceGpAsid = ehrSourceGp.asidCode();
return this;
}

public EhrRequestMessageBuilder withEhrDestinationGp(Gp2GpSystem ehrDestinationGp) {
this.destinationGpOds = ehrDestinationGp.odsCode();
this.destinationGpAsid = ehrDestinationGp.asidCode();
return this;
}

public EhrRequestMessageBuilder withConversationId(UUID conversationId) {
this.conversationId = conversationId;
return this;
}

public EhrRequestMessageBuilder withRandomlyGeneratedConversationId() {
conversationId = UUID.randomUUID();
LOGGER.info("generated conversation id {}", conversationId);
return this;
}

public EhrRequestMessageBuilder withMessageId(UUID messageId) {
this.messageId = messageId;
return this;
}

public EhrRequestMessageBuilder withRandomlyGeneratedMessageId() {
messageId = UUID.randomUUID();
LOGGER.info("generated message id {}", messageId);
return this;
}

public EhrRequestMessage build() {
return new EhrRequestMessage(nhsNumber, sourceGpOds, destinationGpOds, sourceGpAsid, destinationGpAsid, conversationId, messageId);
}
}
12 changes: 12 additions & 0 deletions src/test/java/uk/nhs/prm/deduction/e2e/models/Gp2GpSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.junit.jupiter.params.provider.Arguments;
import uk.nhs.prm.deduction.e2e.TestConfiguration;

import java.util.Map;
import java.util.stream.Stream;

public enum Gp2GpSystem {
Expand All @@ -13,6 +14,13 @@ public enum Gp2GpSystem {

private String odsCode;

private static final Map<String, String> KNOWN_ASID_CODES = Map.of(
"M85019", "200000000149", // TPP_PTL_INT
"N82668", "200000000631", // EMIS_PTL_INT
"B85002", "200000001613", // REPO dev
"B86041", "200000001694" // REPO test
);

Gp2GpSystem(String odsCode) {
this.odsCode = odsCode;
}
Expand All @@ -21,6 +29,10 @@ public String odsCode() {
return odsCode;
}

public String asidCode() {
return KNOWN_ASID_CODES.get(this.odsCode);
}

public static Gp2GpSystem repoInEnv(TestConfiguration config) {
var environmentName = config.getEnvironmentName();
if ("dev".equals(environmentName)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package uk.nhs.prm.deduction.e2e.queue;

import lombok.extern.slf4j.Slf4j;
import org.awaitility.core.ConditionTimeoutException;
import org.json.JSONException;
import uk.nhs.prm.deduction.e2e.models.ResolutionMessage;
import uk.nhs.prm.deduction.e2e.utility.QueueHelper;
Expand Down Expand Up @@ -52,6 +53,20 @@ public SqsMessage getMessageContaining(String substring) {
return found;
}

public boolean verifyNoMessageContaining(String substring) {
try {
await().atMost(60, TimeUnit.SECONDS)
.with()
.pollInterval(100, TimeUnit.MILLISECONDS)
.until(() -> findMessageContaining(substring), notNullValue());
log(String.format("A message on %s match the given substring %s. Returning false", this.queueUri, substring));
return false;
} catch (ConditionTimeoutException error) {
log(String.format("Confirmed no message on %s match the given substring %s.", this.queueUri, substring));
return true;
}
}

public List<SqsMessage> getAllMessageContaining(String substring) {
log(String.format("Checking if message is present on : %s", this.queueUri));
List<SqsMessage> allMessages = new ArrayList<>();
Expand Down Expand Up @@ -108,7 +123,7 @@ private List<SqsMessage> findMessagesOnQueue(int visibilityTimeout) {
private SqsMessage findMessageContaining(String substring) {
List<SqsMessage> allMessages = thinlyWrappedSqsClient.readThroughMessages(this.queueUri, 180);
for (SqsMessage message : allMessages) {
log(String.format("just finding message, checking conversationId: %s", this.queueUri));
log(String.format("Finding message with substring %s on queue: %s", substring, this.queueUri));
if (message.contains(substring)) {
return message;
}
Expand Down
Loading