use of uk.nhs.adaptors.pss.translator.mhs.model.InboundMessage in project nia-patient-switching-standard-adaptor by NHSDigital.
the class EHRTimeoutHandlerIT method checkDatabaseUpdated.
private void checkDatabaseUpdated(MigrationStatus migrationStatus) throws IOException {
String losingOdsCode = "P83007";
String winningOdsCode = "A0378";
String nhsNumber = "9446363101";
String persistDuration = "PT4H";
String conversationId = UUID.randomUUID().toString();
InboundMessage inboundMessage = createInboundMessage();
when(sdsService.getPersistDurationFor(any(), any(), any())).thenReturn(Duration.parse(persistDuration));
patientMigrationRequestDao.addNewRequest(nhsNumber, conversationId, losingOdsCode, winningOdsCode);
migrationStatusLogService.updatePatientMigrationRequestAndAddMigrationStatusLog(conversationId, "{test bundle}", objectMapper.writeValueAsString(inboundMessage), migrationStatus);
ehrTimeoutHandler.checkForTimeouts();
MigrationStatusLog statusLog = migrationStatusLogService.getLatestMigrationStatusLog(conversationId);
assertEquals(ERROR_LRG_MSG_TIMEOUT, statusLog.getMigrationStatus());
}
use of uk.nhs.adaptors.pss.translator.mhs.model.InboundMessage in project nia-patient-switching-standard-adaptor by NHSDigital.
the class COPCMessageHandler method checkAndMergeFileParts.
public void checkAndMergeFileParts(InboundMessage inboundMessage, String conversationId) throws SAXException, AttachmentLogException, ValidationException, InlineAttachmentProcessingException {
Document ebXmlDocument = xPathService.parseDocumentFromXml(inboundMessage.getEbXML());
var inboundMessageId = xPathService.getNodeValue(ebXmlDocument, MESSAGE_ID_PATH);
var currentAttachmentLog = patientAttachmentLogService.findAttachmentLog(inboundMessageId, conversationId);
if (currentAttachmentLog == null) {
throw new AttachmentLogException("Given COPC message is missing an attachment log");
}
// if a message has arrived early, it will not have a parent ID so we can cancel early.
if (currentAttachmentLog.getParentMid() == null) {
return;
}
var conversationAttachmentLogs = patientAttachmentLogService.findAttachmentLogs(conversationId);
var attachmentLogFragments = conversationAttachmentLogs.stream().sorted(Comparator.comparingInt(PatientAttachmentLog::getOrderNum)).filter(log -> !(log.getParentMid() == null) && log.getParentMid().equals(currentAttachmentLog.getParentMid())).toList();
var parentLogMessageId = attachmentLogFragments.size() == 1 ? currentAttachmentLog.getMid() : currentAttachmentLog.getParentMid();
attachmentLogFragments = conversationAttachmentLogs.stream().sorted(Comparator.comparingInt(PatientAttachmentLog::getOrderNum)).filter(log -> !(log.getParentMid() == null) && log.getParentMid().equals(parentLogMessageId)).toList();
var allFragmentsHaveUploaded = attachmentLogFragments.stream().allMatch(PatientAttachmentLog::getUploaded);
if (allFragmentsHaveUploaded) {
String payload = attachmentHandlerService.buildSingleFileStringFromPatientAttachmentLogs(attachmentLogFragments, conversationId);
var parentLogFile = conversationAttachmentLogs.stream().filter(log -> log.getMid().equals(parentLogMessageId)).findAny().orElse(null);
var mergedLargeAttachment = createNewLargeAttachmentInList(parentLogFile, payload);
attachmentHandlerService.storeAttachments(mergedLargeAttachment, conversationId);
var updatedLog = PatientAttachmentLog.builder().mid(parentLogFile.getMid()).uploaded(true).build();
patientAttachmentLogService.updateAttachmentLog(updatedLog, conversationId);
attachmentLogFragments.forEach((PatientAttachmentLog log) -> {
attachmentHandlerService.removeAttachment(log.getFilename(), conversationId);
patientAttachmentLogService.deleteAttachmentLog(log.getMid(), conversationId);
});
}
}
use of uk.nhs.adaptors.pss.translator.mhs.model.InboundMessage in project nia-patient-switching-standard-adaptor by NHSDigital.
the class EhrExtractMessageHandler method handleMessage.
public void handleMessage(InboundMessage inboundMessage, String conversationId) throws JAXBException, JsonProcessingException, InlineAttachmentProcessingException, BundleMappingException, AttachmentNotFoundException, ParseException, SAXException {
RCMRIN030000UK06Message payload = unmarshallString(inboundMessage.getPayload(), RCMRIN030000UK06Message.class);
PatientMigrationRequest migrationRequest = migrationRequestDao.getMigrationRequest(conversationId);
MigrationStatusLog migrationStatusLog = migrationStatusLogService.getLatestMigrationStatusLog(conversationId);
migrationStatusLogService.addMigrationStatusLog(EHR_EXTRACT_RECEIVED, conversationId);
try {
Document ebXmlDocument = getEbXmlDocument(inboundMessage);
String messageId = xPathService.getNodeValue(ebXmlDocument, MESSAGE_ID_PATH);
boolean hasExternalAttachment = !(inboundMessage.getExternalAttachments() == null || inboundMessage.getExternalAttachments().isEmpty());
// Manage attachments against the EHR message
var attachments = inboundMessage.getAttachments();
if (attachments != null) {
attachmentHandlerService.storeAttachments(attachments, conversationId);
for (var i = 0; i < attachments.size(); i++) {
var attachment = attachments.get(i);
PatientAttachmentLog newAttachmentLog = buildPatientAttachmentLogFromAttachment(messageId, migrationRequest, attachment);
patientAttachmentLogService.addAttachmentLog(newAttachmentLog);
}
}
if (!hasExternalAttachment) {
var fileUpdatedPayload = attachmentReferenceUpdaterService.updateReferenceToAttachment(inboundMessage.getAttachments(), conversationId, inboundMessage.getPayload());
inboundMessage.setPayload(fileUpdatedPayload);
payload = unmarshallString(inboundMessage.getPayload(), RCMRIN030000UK06Message.class);
var bundle = bundleMapperService.mapToBundle(payload, migrationRequest.getLosingPracticeOdsCode());
migrationStatusLogService.updatePatientMigrationRequestAndAddMigrationStatusLog(conversationId, fhirParser.encodeToJson(bundle), objectMapper.writeValueAsString(inboundMessage), EHR_EXTRACT_TRANSLATED);
nackAckPreparationService.sendAckMessage(payload, conversationId);
}
// sending continue message
if (hasExternalAttachment) {
String patientNhsNumber = XmlParseUtilService.parseNhsNumber(payload);
for (InboundMessage.ExternalAttachment externalAttachment : inboundMessage.getExternalAttachments()) {
PatientAttachmentLog patientAttachmentLog;
// save COPC_UK01 messages
patientAttachmentLog = buildPatientAttachmentLogFromExternalAttachment(migrationRequest, externalAttachment);
patientAttachmentLogService.addAttachmentLog(patientAttachmentLog);
}
migrationStatusLogService.updatePatientMigrationRequestAndAddMigrationStatusLog(conversationId, null, objectMapper.writeValueAsString(inboundMessage), EHR_EXTRACT_TRANSLATED);
sendContinueRequest(payload, conversationId, patientNhsNumber, migrationRequest.getWinningPracticeOdsCode(), migrationStatusLog.getDate().toInstant());
}
} catch (BundleMappingException | DataFormatException | JsonProcessingException | InlineAttachmentProcessingException | AttachmentNotFoundException | SAXException | StorageException ex) {
nackAckPreparationService.sendNackMessage(EHR_EXTRACT_CANNOT_BE_PROCESSED, payload, conversationId);
throw ex;
} catch (ParseException ex) {
throw ex;
}
}
use of uk.nhs.adaptors.pss.translator.mhs.model.InboundMessage in project nia-patient-switching-standard-adaptor by NHSDigital.
the class MhsQueueMessageHandler method handleMessage.
public boolean handleMessage(Message message) {
try {
InboundMessage inboundMessage = readMessage(message);
Document ebXmlDocument = xPathService.parseDocumentFromXml(inboundMessage.getEbXML());
String conversationId = xPathService.getNodeValue(ebXmlDocument, CONVERSATION_ID_PATH);
applyConversationId(conversationId);
String interactionId = xPathService.getNodeValue(ebXmlDocument, INTERACTION_ID_PATH);
if (ACKNOWLEDGEMENT_INTERACTION_ID.equals(interactionId)) {
acknowledgmentMessageHandler.handleMessage(inboundMessage, conversationId);
} else if (EHR_EXTRACT_INTERACTION_ID.equals(interactionId)) {
ehrExtractMessageHandler.handleMessage(inboundMessage, conversationId);
} else if (CONTINUE_ATTACHMENT_INTERACTION_ID.equals(interactionId)) {
continueMessageHandler.handleMessage(inboundMessage, conversationId);
} else {
LOGGER.info("Handling message with [{}] interaction id not implemented", interactionId);
}
return true;
} catch (JMSException | JAXBException | SAXException e) {
LOGGER.error("Unable to read the content of the inbound MHS message", e);
return false;
} catch (JsonProcessingException | DataFormatException e) {
LOGGER.error("Unable to parse messages", e);
return false;
} catch (InlineAttachmentProcessingException | AttachmentLogException e) {
LOGGER.error("Unable to process inline attachments", e);
return false;
} catch (AttachmentNotFoundException e) {
LOGGER.error("Unable to find attachment reference inbound message", e);
return false;
} catch (BundleMappingException e) {
LOGGER.error("Unable to map EHR Extract to FHIR bundle", e);
return false;
} catch (ParseException e) {
LOGGER.error("Unable to parse Ebxml References", e);
return false;
}
// catch (SkeletonEhrProcessingException e) {
// LOGGER.error("Unable to process EhrExtract", e);
// return false;
// }
}
use of uk.nhs.adaptors.pss.translator.mhs.model.InboundMessage in project nia-patient-switching-standard-adaptor by NHSDigital.
the class EHRTimeoutHandler method handleMigrationTimeout.
private void handleMigrationTimeout(PatientMigrationRequest migrationRequest) {
String conversationId = migrationRequest.getConversationId();
mdcService.applyConversationId(conversationId);
try {
long timeout;
Duration ehrPersistDuration = persistDurationService.getPersistDurationFor(migrationRequest, EHR_EXTRACT_MESSAGE_NAME);
InboundMessage message = inboundMessageUtil.readMessage(migrationRequest.getInboundMessage());
ZonedDateTime messageTimestamp = inboundMessageUtil.parseMessageTimestamp(message.getEbXML());
ZonedDateTime currentTime = ZonedDateTime.now(messageTimestamp.getZone());
long numberCOPCMessages = patientAttachmentLogService.countAttachmentsForMigrationRequest(migrationRequest.getId());
if (numberCOPCMessages > 0) {
Duration copcPersistDuration = persistDurationService.getPersistDurationFor(migrationRequest, COPC_MESSAGE_NAME);
timeout = (timeoutProperties.getEhrExtractWeighting() * ehrPersistDuration.getSeconds()) + (timeoutProperties.getCopcWeighting() * numberCOPCMessages * copcPersistDuration.getSeconds());
LOGGER.debug("Large message timeout calculated as [{}] seconds", timeout);
} else {
timeout = timeoutProperties.getEhrExtractWeighting() * ehrPersistDuration.getSeconds();
LOGGER.debug("Non large message timeout calculated as [{}] seconds", timeout);
}
ZonedDateTime timeoutDateTime = messageTimestamp.plusSeconds(timeout);
LOGGER.debug("Timeout datetime calculated as [{}]", timeoutDateTime);
if (timeoutDateTime.isBefore(currentTime)) {
LOGGER.info("Migration timed out at [{}]", timeoutDateTime);
sendNackMessage(message, conversationId);
}
} catch (SdsRetrievalException e) {
LOGGER.error("Error retrieving persist duration: [{}]", e.getMessage());
} catch (JsonProcessingException | SAXException | DateTimeParseException | JAXBException e) {
LOGGER.error("Error parsing inbound message from database");
migrationStatusLogService.addMigrationStatusLog(EHR_GENERAL_PROCESSING_ERROR, conversationId);
}
mdcService.applyConversationId("");
}
Aggregations