From 207df5b7d473d88dd150de3da9d645eb014593d6 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Wed, 14 May 2025 10:37:28 +0100 Subject: [PATCH 1/8] Add Schema validation to transform tool * Add ErrorHandler for XML/XSD schema validation errors. * Add Schema validator which retrieves the configured redactions context and validates against the corresponding schema. * Add functionality to output the validation errors in a log file. * Inject and use schema validation when running the transformation process. * Update developer information. --- nhs-england-developer-information.md | 6 +- .../TransformJsonToXml.java | 3 +- .../XmlSchemaValidator.java | 101 ++++++++++++++++++ .../XsdErrorHandler.java | 36 +++++++ 4 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java create mode 100644 service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java diff --git a/nhs-england-developer-information.md b/nhs-england-developer-information.md index 130e52ff27..7a95aeee6d 100644 --- a/nhs-england-developer-information.md +++ b/nhs-england-developer-information.md @@ -191,7 +191,7 @@ We provide a mock MHS adaptor for local development and testing. ### How to transform arbitrary json ASR payload files -This is an interoperability testing tool to transform arbitrary/ad-hoc json ASR payloads and access the outputs. +This is an interoperability testing tool to transform arbitrary/ad-hoc json ASR payloads, access the outputs and validate the produced XML against the relevant schema. 1. Navigate to the input folder and place all Json files to convert here. `integration-adaptor-gp2gp/transformJsonToXml/input/` @@ -203,9 +203,11 @@ This is an interoperability testing tool to transform arbitrary/ad-hoc json ASR ./TransformJsonToXml.sh ``` -3. The Converted .Xml files will be located in the output folder. +3. The converted XML files will be located in the output folder. `integration-adaptor-gp2gp/transformJsonToXml/output/` +4. Any schema validation errors will be located with the extension `.validation-errors.log` and will be located in the same output folder as the converted XML files. + ## Troubleshooting ### "Invalid source release 17" error diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java index ca3155fd0d..cdf3e7994c 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java @@ -48,7 +48,6 @@ matchIfMissing = false) @Component public class TransformJsonToXml implements CommandLineRunner { - private static final String JSON_FILE_INPUT_PATH = Paths.get("src/").toFile().getAbsoluteFile().getAbsolutePath() + "/../../transformJsonToXml/input/"; private static final String XML_OUTPUT_PATH = @@ -57,6 +56,7 @@ public class TransformJsonToXml implements CommandLineRunner { private final MessageContext messageContext; private final OutputMessageWrapperMapper outputMessageWrapperMapper; private final EhrExtractMapper ehrExtractMapper; + private final uk.nhs.adaptors.gp2gp.transformjsontoxmltool.XmlSchemaValidator xmlSchemaValidator; public static void main(String[] args) { SpringApplication.run(TransformJsonToXml.class, args).close(); @@ -68,6 +68,7 @@ public void run(String... args) { getFiles().forEach(file -> { String xmlResult = mapJsonToXml(file.getJsonFileInput()); writeToFile(xmlResult, file.getJsonFileName()); + xmlSchemaValidator.validateOutputToXmlSchema(file.getJsonFileName(), xmlResult); }); } catch (NHSNumberNotFound | UnreadableJsonFileException | NoJsonFileFound | Hl7TranslatedResponseError e) { LOGGER.error("error: " + e.getMessage()); diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java new file mode 100644 index 0000000000..8920ef3501 --- /dev/null +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java @@ -0,0 +1,101 @@ +package uk.nhs.adaptors.gp2gp.transformjsontoxmltool; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.springframework.stereotype.Component; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import uk.nhs.adaptors.gp2gp.common.configuration.RedactionsContext; + +import javax.xml.XMLConstants; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; + +@Component +@Slf4j +@RequiredArgsConstructor() +public class XmlSchemaValidator { + private final RedactionsContext redactionsContext; + + private static final String SCHEMA_PATH = "../service/src/test/resources/mim/Schemas/"; + private static final String RCMR_IN030000UK06_SCHEMA_PATH = SCHEMA_PATH + RedactionsContext.NON_REDACTION_INTERACTION_ID + ".xsd"; + private static final String RCMR_IN030000UK07_SCHEMA_PATH = SCHEMA_PATH + RedactionsContext.REDACTION_INTERACTION_ID + ".xsd"; + private static final String OUTPUT_PATH = + Paths.get("src/").toFile().getAbsoluteFile().getAbsolutePath() + "/../../transformJsonToXml/output/"; + + public void validateOutputToXmlSchema(String filename, String xmlResult) { + LOGGER.info("Validating {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); + + var xsdErrorHandler = new uk.nhs.adaptors.gp2gp.transformjsontoxmltool.XsdErrorHandler(); + Validator xmlValidator; + + try { + xmlValidator = getXmlValidator(xsdErrorHandler); + } catch (SAXException e) { + LOGGER.info("Could not load schema file for {} context.", RedactionsContext.REDACTION_INTERACTION_ID); + return; + } + + try { + var xmlResultSource = new StreamSource(new StringReader(xmlResult)); + xmlValidator.validate(xmlResultSource); + } catch (SAXParseException parseException) { + LOGGER.info("Failed to validate {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); + writeValidationExceptionsToFile(xsdErrorHandler, filename); + } catch (IOException e) { + LOGGER.info("Could not read from stream source for produced XML for {}", filename); + return; + } catch (Exception e) { + throw new RuntimeException(e); + } + + if (!xsdErrorHandler.isValid()) { + LOGGER.info("Failed to validate {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); + writeValidationExceptionsToFile(xsdErrorHandler, filename); + return; + } + + LOGGER.info("Successfully validated {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); + } + + private void writeValidationExceptionsToFile( + uk.nhs.adaptors.gp2gp.transformjsontoxmltool.XsdErrorHandler xsdErrorHandler, + String fileName + ) { + String outputFileName = FilenameUtils.removeExtension(fileName) + ".validation-errors.log"; + try (BufferedWriter writer = new BufferedWriter(new FileWriter(OUTPUT_PATH + outputFileName, StandardCharsets.UTF_8))) { + for (SAXParseException e : xsdErrorHandler.getExceptions()) { + var message = String.format("[%d:%d] %s", e.getLineNumber(), e.getColumnNumber(), e.getMessage()); + writer.write(message); + writer.newLine(); + } + LOGGER.info("Validation errors written to {}", outputFileName); + } catch (IOException e) { + LOGGER.error("Could not write validation errors to {}", outputFileName, e); + } + } + + private Validator getXmlValidator(uk.nhs.adaptors.gp2gp.transformjsontoxmltool.XsdErrorHandler xsdErrorHandler) throws SAXException { + var schemaPath = RedactionsContext.REDACTION_INTERACTION_ID.equals(redactionsContext.ehrExtractInteractionId()) + ? RCMR_IN030000UK07_SCHEMA_PATH + : RCMR_IN030000UK06_SCHEMA_PATH; + + var schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + var schemaFileStream = new StreamSource(new File(schemaPath)); + var schema = schemaFactory.newSchema(schemaFileStream); + var validator = schema.newValidator(); + + validator.setErrorHandler(xsdErrorHandler); + + return validator; + } +} diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java new file mode 100644 index 0000000000..aaedc9ecdb --- /dev/null +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java @@ -0,0 +1,36 @@ +package uk.nhs.adaptors.gp2gp.transformjsontoxmltool; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXParseException; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Getter +public class XsdErrorHandler implements ErrorHandler { + + private final List exceptions = new ArrayList<>(); + + public boolean isValid() { + return exceptions.isEmpty(); + } + + @Override + public void warning(SAXParseException exception) { + exceptions.add(exception); + } + + @Override + public void error(SAXParseException exception) { + exceptions.add(exception); + } + + @Override + public void fatalError(SAXParseException exception) throws SAXParseException { + exceptions.add(exception); + throw exception; + } +} From c9020675af18325771c71faed035f80ee6745f58 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Tue, 20 May 2025 13:43:58 +0100 Subject: [PATCH 2/8] * Add sonar exclusions for transform tool --- service/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/service/build.gradle b/service/build.gradle index 2a4b14182f..cfa896b8d3 100644 --- a/service/build.gradle +++ b/service/build.gradle @@ -172,6 +172,7 @@ sonar { property("sonar.host.url", "https://sonarcloud.io") property("sonar.projectKey", "NHSDigital_integration-adaptor-gp2gp") property("sonar.organization", "nhsdigital") + property("sonar.exclusions", "service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/**") } } From 5516d4501152b7bfb9545a8f11898cee3a5b14b6 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Tue, 20 May 2025 14:30:10 +0100 Subject: [PATCH 3/8] * Add sonar exclusions for transform tool * Update XmlSchemaValidator to use newDefaultInstance instead --- service/build.gradle | 2 +- .../gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/service/build.gradle b/service/build.gradle index cfa896b8d3..60ecc5f68f 100644 --- a/service/build.gradle +++ b/service/build.gradle @@ -172,7 +172,7 @@ sonar { property("sonar.host.url", "https://sonarcloud.io") property("sonar.projectKey", "NHSDigital_integration-adaptor-gp2gp") property("sonar.organization", "nhsdigital") - property("sonar.exclusions", "service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/**") + property("sonar.exclusions", "service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/*.java") } } diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java index 8920ef3501..25fbc343fc 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java @@ -89,7 +89,7 @@ private Validator getXmlValidator(uk.nhs.adaptors.gp2gp.transformjsontoxmltool.X ? RCMR_IN030000UK07_SCHEMA_PATH : RCMR_IN030000UK06_SCHEMA_PATH; - var schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + var schemaFactory = SchemaFactory.newDefaultInstance(); var schemaFileStream = new StreamSource(new File(schemaPath)); var schema = schemaFactory.newSchema(schemaFileStream); var validator = schema.newValidator(); From 3ff374949f526e935a3b3734bae8a90120b0d04f Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Tue, 20 May 2025 14:38:49 +0100 Subject: [PATCH 4/8] * Add sonar exclusions for transform tool * Update XmlSchemaValidator to use newDefaultInstance instead --- service/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/build.gradle b/service/build.gradle index 60ecc5f68f..e905da978a 100644 --- a/service/build.gradle +++ b/service/build.gradle @@ -172,7 +172,7 @@ sonar { property("sonar.host.url", "https://sonarcloud.io") property("sonar.projectKey", "NHSDigital_integration-adaptor-gp2gp") property("sonar.organization", "nhsdigital") - property("sonar.exclusions", "service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/*.java") + property("sonar.exclusions", "**/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/**") } } From a26e9cd92a09c343c45d69f66cf5c2af7e70d687 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Tue, 20 May 2025 14:40:32 +0100 Subject: [PATCH 5/8] * Add sonar exclusions for transform tool * Update XmlSchemaValidator to use newDefaultInstance instead --- service/build.gradle | 2 +- .../gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/service/build.gradle b/service/build.gradle index e905da978a..353f0d4a5c 100644 --- a/service/build.gradle +++ b/service/build.gradle @@ -172,7 +172,7 @@ sonar { property("sonar.host.url", "https://sonarcloud.io") property("sonar.projectKey", "NHSDigital_integration-adaptor-gp2gp") property("sonar.organization", "nhsdigital") - property("sonar.exclusions", "**/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/**") + property("sonar.exclusions", "**/transformJsonToXmlTool/*") } } diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java index 25fbc343fc..1e656575c6 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java @@ -8,7 +8,6 @@ import org.xml.sax.SAXParseException; import uk.nhs.adaptors.gp2gp.common.configuration.RedactionsContext; -import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; From ea12fc1945f7c65b7374a1279e70e9f106a341b8 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Thu, 22 May 2025 11:13:55 +0100 Subject: [PATCH 6/8] * Refactor package name to match naming conventions --- service/build.gradle | 2 +- .../transformJsonToXmlTool/TransformJsonToXml.java | 4 ++-- .../transformJsonToXmlTool/XmlSchemaValidator.java | 11 ++++------- .../gp2gp/transformJsonToXmlTool/XsdErrorHandler.java | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/service/build.gradle b/service/build.gradle index 353f0d4a5c..03a6bd4eb0 100644 --- a/service/build.gradle +++ b/service/build.gradle @@ -103,7 +103,7 @@ sourceSets { } task(interoperabilityTestingToolJsonToXml, dependsOn: 'classes', type: JavaExec) { - mainClass.set('uk.nhs.adaptors.gp2gp.transformjsontoxmltool.TransformJsonToXml') + mainClass.set('uk.nhs.adaptors.gp2gp.transformJsonToXmlTool.TransformJsonToXml') classpath = sourceSets.main.runtimeClasspath } diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java index cdf3e7994c..433cfb3a19 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java @@ -1,4 +1,4 @@ -package uk.nhs.adaptors.gp2gp.transformjsontoxmltool; +package uk.nhs.adaptors.gp2gp.transformJsonToXmlTool; import java.io.BufferedWriter; import java.io.File; @@ -56,7 +56,7 @@ public class TransformJsonToXml implements CommandLineRunner { private final MessageContext messageContext; private final OutputMessageWrapperMapper outputMessageWrapperMapper; private final EhrExtractMapper ehrExtractMapper; - private final uk.nhs.adaptors.gp2gp.transformjsontoxmltool.XmlSchemaValidator xmlSchemaValidator; + private final XmlSchemaValidator xmlSchemaValidator; public static void main(String[] args) { SpringApplication.run(TransformJsonToXml.class, args).close(); diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java index 1e656575c6..16386d4ab0 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java @@ -1,4 +1,4 @@ -package uk.nhs.adaptors.gp2gp.transformjsontoxmltool; +package uk.nhs.adaptors.gp2gp.transformJsonToXmlTool; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -34,7 +34,7 @@ public class XmlSchemaValidator { public void validateOutputToXmlSchema(String filename, String xmlResult) { LOGGER.info("Validating {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); - var xsdErrorHandler = new uk.nhs.adaptors.gp2gp.transformjsontoxmltool.XsdErrorHandler(); + var xsdErrorHandler = new XsdErrorHandler(); Validator xmlValidator; try { @@ -66,10 +66,7 @@ public void validateOutputToXmlSchema(String filename, String xmlResult) { LOGGER.info("Successfully validated {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); } - private void writeValidationExceptionsToFile( - uk.nhs.adaptors.gp2gp.transformjsontoxmltool.XsdErrorHandler xsdErrorHandler, - String fileName - ) { + private void writeValidationExceptionsToFile(XsdErrorHandler xsdErrorHandler, String fileName) { String outputFileName = FilenameUtils.removeExtension(fileName) + ".validation-errors.log"; try (BufferedWriter writer = new BufferedWriter(new FileWriter(OUTPUT_PATH + outputFileName, StandardCharsets.UTF_8))) { for (SAXParseException e : xsdErrorHandler.getExceptions()) { @@ -83,7 +80,7 @@ private void writeValidationExceptionsToFile( } } - private Validator getXmlValidator(uk.nhs.adaptors.gp2gp.transformjsontoxmltool.XsdErrorHandler xsdErrorHandler) throws SAXException { + private Validator getXmlValidator(XsdErrorHandler xsdErrorHandler) throws SAXException { var schemaPath = RedactionsContext.REDACTION_INTERACTION_ID.equals(redactionsContext.ehrExtractInteractionId()) ? RCMR_IN030000UK07_SCHEMA_PATH : RCMR_IN030000UK06_SCHEMA_PATH; diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java index aaedc9ecdb..32c5747619 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java @@ -1,4 +1,4 @@ -package uk.nhs.adaptors.gp2gp.transformjsontoxmltool; +package uk.nhs.adaptors.gp2gp.transformJsonToXmlTool; import lombok.Getter; import lombok.extern.slf4j.Slf4j; From 3a7cfdd2561151507b4625f4d7b9aa9638c3e393 Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Thu, 22 May 2025 11:25:31 +0100 Subject: [PATCH 7/8] * Extracted constants for schema validation message templates. * Changed logging to `Error` when the schema file could not be loaded. * Renamed parameter `filename` to be more specific about its intent. --- .../XmlSchemaValidator.java | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java index 16386d4ab0..187a8deef2 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java @@ -31,8 +31,16 @@ public class XmlSchemaValidator { private static final String OUTPUT_PATH = Paths.get("src/").toFile().getAbsoluteFile().getAbsolutePath() + "/../../transformJsonToXml/output/"; - public void validateOutputToXmlSchema(String filename, String xmlResult) { - LOGGER.info("Validating {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); + private static final String VALIDATING_AGAINST_SCHEMA_TEMPLATE = "Validating {} against {} schema"; + private static final String COULD_NOT_LOAD_SCHEMA_FILE_TEMPLATE = "Could not load schema file for {} context."; + private static final String FAILED_TO_VALIDATE_SCHEMA_TEMPLATE = "Failed to validate {} against {} schema"; + private static final String COULD_NOT_READ_FROM_STREAM_SOURCE_TEMPLATE = "Could not read from stream source for produced XML for {}"; + private static final String SUCCESSFULLY_VALIDATED_SCHEMA_TEMPLATE = "Successfully validated {} against {} schema"; + private static final String VALIDATION_ERRORS_WRITTEN_TEMPLATE = "Validation errors written to {}"; + private static final String COULD_NOT_WRITE_VALIDATION_ERRORS_TEMPLATE = "Could not write validation errors to {}"; + + public void validateOutputToXmlSchema(String inputJsonFilename, String xmlResult) { + LOGGER.info(VALIDATING_AGAINST_SCHEMA_TEMPLATE, inputJsonFilename, RedactionsContext.REDACTION_INTERACTION_ID); var xsdErrorHandler = new XsdErrorHandler(); Validator xmlValidator; @@ -40,7 +48,7 @@ public void validateOutputToXmlSchema(String filename, String xmlResult) { try { xmlValidator = getXmlValidator(xsdErrorHandler); } catch (SAXException e) { - LOGGER.info("Could not load schema file for {} context.", RedactionsContext.REDACTION_INTERACTION_ID); + LOGGER.error(COULD_NOT_LOAD_SCHEMA_FILE_TEMPLATE, RedactionsContext.REDACTION_INTERACTION_ID); return; } @@ -48,22 +56,22 @@ public void validateOutputToXmlSchema(String filename, String xmlResult) { var xmlResultSource = new StreamSource(new StringReader(xmlResult)); xmlValidator.validate(xmlResultSource); } catch (SAXParseException parseException) { - LOGGER.info("Failed to validate {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); - writeValidationExceptionsToFile(xsdErrorHandler, filename); + LOGGER.info(FAILED_TO_VALIDATE_SCHEMA_TEMPLATE, inputJsonFilename, RedactionsContext.REDACTION_INTERACTION_ID); + writeValidationExceptionsToFile(xsdErrorHandler, inputJsonFilename); } catch (IOException e) { - LOGGER.info("Could not read from stream source for produced XML for {}", filename); + LOGGER.info(COULD_NOT_READ_FROM_STREAM_SOURCE_TEMPLATE, inputJsonFilename); return; } catch (Exception e) { throw new RuntimeException(e); } if (!xsdErrorHandler.isValid()) { - LOGGER.info("Failed to validate {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); - writeValidationExceptionsToFile(xsdErrorHandler, filename); + LOGGER.info(FAILED_TO_VALIDATE_SCHEMA_TEMPLATE, inputJsonFilename, RedactionsContext.REDACTION_INTERACTION_ID); + writeValidationExceptionsToFile(xsdErrorHandler, inputJsonFilename); return; } - LOGGER.info("Successfully validated {} against {} schema", filename, RedactionsContext.REDACTION_INTERACTION_ID); + LOGGER.info(SUCCESSFULLY_VALIDATED_SCHEMA_TEMPLATE, inputJsonFilename, RedactionsContext.REDACTION_INTERACTION_ID); } private void writeValidationExceptionsToFile(XsdErrorHandler xsdErrorHandler, String fileName) { @@ -74,9 +82,9 @@ private void writeValidationExceptionsToFile(XsdErrorHandler xsdErrorHandler, St writer.write(message); writer.newLine(); } - LOGGER.info("Validation errors written to {}", outputFileName); + LOGGER.info(VALIDATION_ERRORS_WRITTEN_TEMPLATE, outputFileName); } catch (IOException e) { - LOGGER.error("Could not write validation errors to {}", outputFileName, e); + LOGGER.error(COULD_NOT_WRITE_VALIDATION_ERRORS_TEMPLATE, outputFileName, e); } } From 0a4534bf09a6ace702bbdb7294e344e92c0446ab Mon Sep 17 00:00:00 2001 From: MartinWheelerMT Date: Thu, 22 May 2025 11:45:45 +0100 Subject: [PATCH 8/8] * Rename package folder from `transformJsonToXmlTool` to `transformjsontoxmltool` to address checkstyle package name issues --- service/build.gradle | 4 ++-- .../TransformJsonToXml.java | 2 +- .../XmlSchemaValidator.java | 10 +++++----- .../XsdErrorHandler.java | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) rename service/src/main/java/uk/nhs/adaptors/gp2gp/{transformJsonToXmlTool => transformjsontoxmltool}/TransformJsonToXml.java (99%) rename service/src/main/java/uk/nhs/adaptors/gp2gp/{transformJsonToXmlTool => transformjsontoxmltool}/XmlSchemaValidator.java (94%) rename service/src/main/java/uk/nhs/adaptors/gp2gp/{transformJsonToXmlTool => transformjsontoxmltool}/XsdErrorHandler.java (93%) diff --git a/service/build.gradle b/service/build.gradle index 03a6bd4eb0..09df232950 100644 --- a/service/build.gradle +++ b/service/build.gradle @@ -103,7 +103,7 @@ sourceSets { } task(interoperabilityTestingToolJsonToXml, dependsOn: 'classes', type: JavaExec) { - mainClass.set('uk.nhs.adaptors.gp2gp.transformJsonToXmlTool.TransformJsonToXml') + mainClass.set('uk.nhs.adaptors.gp2gp.transformjsontoxmltool.TransformJsonToXml') classpath = sourceSets.main.runtimeClasspath } @@ -172,7 +172,7 @@ sonar { property("sonar.host.url", "https://sonarcloud.io") property("sonar.projectKey", "NHSDigital_integration-adaptor-gp2gp") property("sonar.organization", "nhsdigital") - property("sonar.exclusions", "**/transformJsonToXmlTool/*") + property("sonar.exclusions", "**/transformjsontoxmltool/*") } } diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/TransformJsonToXml.java similarity index 99% rename from service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java rename to service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/TransformJsonToXml.java index 433cfb3a19..19dde3b36b 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/TransformJsonToXml.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/TransformJsonToXml.java @@ -1,4 +1,4 @@ -package uk.nhs.adaptors.gp2gp.transformJsonToXmlTool; +package uk.nhs.adaptors.gp2gp.transformjsontoxmltool; import java.io.BufferedWriter; import java.io.File; diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/XmlSchemaValidator.java similarity index 94% rename from service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java rename to service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/XmlSchemaValidator.java index 187a8deef2..096ec7e674 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XmlSchemaValidator.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/XmlSchemaValidator.java @@ -1,4 +1,4 @@ -package uk.nhs.adaptors.gp2gp.transformJsonToXmlTool; +package uk.nhs.adaptors.gp2gp.transformjsontoxmltool; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -56,17 +56,17 @@ public void validateOutputToXmlSchema(String inputJsonFilename, String xmlResult var xmlResultSource = new StreamSource(new StringReader(xmlResult)); xmlValidator.validate(xmlResultSource); } catch (SAXParseException parseException) { - LOGGER.info(FAILED_TO_VALIDATE_SCHEMA_TEMPLATE, inputJsonFilename, RedactionsContext.REDACTION_INTERACTION_ID); + LOGGER.warn(FAILED_TO_VALIDATE_SCHEMA_TEMPLATE, inputJsonFilename, RedactionsContext.REDACTION_INTERACTION_ID); writeValidationExceptionsToFile(xsdErrorHandler, inputJsonFilename); } catch (IOException e) { - LOGGER.info(COULD_NOT_READ_FROM_STREAM_SOURCE_TEMPLATE, inputJsonFilename); + LOGGER.error(COULD_NOT_READ_FROM_STREAM_SOURCE_TEMPLATE, inputJsonFilename); return; } catch (Exception e) { throw new RuntimeException(e); } if (!xsdErrorHandler.isValid()) { - LOGGER.info(FAILED_TO_VALIDATE_SCHEMA_TEMPLATE, inputJsonFilename, RedactionsContext.REDACTION_INTERACTION_ID); + LOGGER.warn(FAILED_TO_VALIDATE_SCHEMA_TEMPLATE, inputJsonFilename, RedactionsContext.REDACTION_INTERACTION_ID); writeValidationExceptionsToFile(xsdErrorHandler, inputJsonFilename); return; } @@ -102,4 +102,4 @@ private Validator getXmlValidator(XsdErrorHandler xsdErrorHandler) throws SAXExc return validator; } -} +} \ No newline at end of file diff --git a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/XsdErrorHandler.java similarity index 93% rename from service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java rename to service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/XsdErrorHandler.java index 32c5747619..aaedc9ecdb 100644 --- a/service/src/main/java/uk/nhs/adaptors/gp2gp/transformJsonToXmlTool/XsdErrorHandler.java +++ b/service/src/main/java/uk/nhs/adaptors/gp2gp/transformjsontoxmltool/XsdErrorHandler.java @@ -1,4 +1,4 @@ -package uk.nhs.adaptors.gp2gp.transformJsonToXmlTool; +package uk.nhs.adaptors.gp2gp.transformjsontoxmltool; import lombok.Getter; import lombok.extern.slf4j.Slf4j;