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

DMP-2948: Encoding Event element as escaped string #383

Merged
merged 2 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
36 changes: 32 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ def sonarExclusions = [
'**/uk/gov/hmcts/darts/**/config/**',
'**/enums/**',
'**/DocumentumIdToJwtCache*',
'**/CacheValueWithJwt*'
'**/CacheValueWithJwt*',
'**/com/service/viq/event/**'

]

sonarqube {
Expand Down Expand Up @@ -329,7 +331,7 @@ dependencies {

implementation group: 'wsdl4j', name: 'wsdl4j', version: wsdl4jVersion
jaxb( 'org.glassfish.jaxb:jaxb-xjc:4.0.5')
jaxb( 'org.glassfish.jaxb:jaxb-runtime:4.0.5')
implementation( 'org.glassfish.jaxb:jaxb-runtime:4.0.5')

// https://mvnrepository.com/artifact/io.github.openfeign/feign-jackson
implementation 'com.fasterxml.jackson.core:jackson-databind'
Expand Down Expand Up @@ -359,6 +361,8 @@ dependencies {

implementation 'org.mapstruct:mapstruct:1.5.5.Final'
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
implementation group: 'org.apache.xmlbeans', name: 'xmlbeans', version: '5.2.0'


implementation project(path: ':context')

Expand All @@ -373,6 +377,7 @@ dependencies {

implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.5.4'
implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.5.4'
implementation group: 'com.sun.xml.bind', name: 'jaxb-impl', version: '2.0.1'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'

testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
Expand Down Expand Up @@ -435,6 +440,7 @@ tasks.withType(Checkstyle) {
exclude 'uk/gov/courtservice/**/*.java'
exclude 'uk/gov/addcase/**/*.java'
exclude 'com/viqsoultions/**/*.java'
exclude 'com/service/viq/event/**/*.java'
}

tasks.withType(Pmd) {
Expand All @@ -444,17 +450,20 @@ tasks.withType(Pmd) {
exclude 'uk/gov/courtservice/**/*.java'
exclude 'uk/gov/addcase/**/*.java'
exclude 'com/viqsoultions/**/*.java'
exclude 'com/service/viq/event/**/*.java'
}

sourceSets {
main {
java {
srcDir 'src/main/java'
srcDir 'build/generated-sources/jaxb'
srcDir 'src/main/java/generated'
srcDir 'build/generated-sources/jaxb'
srcDir 'build/generated-sources/jaxbViqEvent'
srcDir 'build/generated-sources/jaxbRegisterNode'
srcDir 'build/generated-sources/jaxbAddCase'
srcDir 'build/generated-sources/jaxbAddAudio'
srcDir 'build/generated-sources/jaxbViqEvent'
}
}
}
Expand All @@ -478,6 +487,25 @@ task genJaxb {
}
}

task genJaxbViqEvent {
ext.sourcesDir = "${buildDir}/generated-sources/jaxbViqEvent"
ext.schema = "src/main/resources/schemas/internal-dar-notify-event.xsd"

outputs.dir sourcesDir

doLast() {
project.ant {
taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask", classpath: configurations.jaxb.asPath
mkdir(dir: sourcesDir)

xjc(destdir: sourcesDir, package: "com.service.viq.event", schema: schema) {
arg(value: "-wsdl")
produces(dir: sourcesDir, includes: "**/*.java")
}
}
}
}

task genJaxbRegisterNode {
ext.sourcesDir = "${buildDir}/generated-sources/jaxbRegisterNode"
ext.schema = "src/main/resources/schemas/darts-register-node.xsd"
Expand Down Expand Up @@ -587,4 +615,4 @@ project.tasks.processResources.dependsOn processDartsServiceWSDL
project.tasks.wsdl2java.dependsOn processDartsServiceWSDL
compileJava.dependsOn generateCodeFromSpecification
generateCodeFromSpecification.dependsOn extractOpenSpecification
compileJava.dependsOn genJaxbAddCase, genJaxbRegisterNode, genJaxbAddAudio
compileJava.dependsOn genJaxbAddCase, genJaxbRegisterNode, genJaxbAddAudio, genJaxbViqEvent
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,21 @@ class DarNotifyControllerTest {
{
"notification_url": "http://localhost:8090/VIQDARNotifyEvent/DARNotifyEvent.asmx",
"notification_type": "3",
"timestamp": "2023-06-19T14:52:40.637Z",
"courthouse": "Test Court",
"timestamp": "2024-04-25T14:20:40.637Z",
"courthouse": "York",
"courtroom": "1",
"case_numbers": [
"A123456"
"T20240000"
]
}
""";
private static final String EXPECTED_DAR_PC_NOTIFICATION = """
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns3:DARNotifyEvent xmlns:ns3="http://www.VIQSoultions.com">
<XMLEventDocument>
<event D="19" H="15" M="6" MIN="52" S="40" Y="2023" type="3">
<courthouse>Test Court</courthouse>
<courtroom>1</courtroom>
<case_numbers>
<case_number>A123456</case_number>
</case_numbers>
</event>
</XMLEventDocument>
</ns3:DARNotifyEvent>
<DARNotifyEvent xmlns="http://www.VIQSoultions.com">
<XMLEventDocument>&lt;Event type="3" Y="2024" M="4" D="25" H="15" MIN="20" S="40"&gt;&lt;courthouse&gt;York&lt;/courthouse&gt;&lt;courtroom&gt;1&lt;/courtroom&gt;&lt;case_numbers&gt;&lt;case_number&gt;T20240000&lt;/case_number&gt;&lt;/case_numbers&gt;&lt;/Event&gt;</XMLEventDocument>
</DARNotifyEvent>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
""";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.gov.hmcts.darts.event.client;

import com.service.viq.event.Event;
import com.viqsoultions.DARNotifyEvent;
import com.viqsoultions.DARNotifyEventResponse;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -29,11 +30,10 @@ public class DarNotifyEventClient {
private final LogApi logApi;

// This SOAP Web Service operation (DARNotifyEvent) still needs to be fully integration tested
public boolean darNotifyEvent(String uri, DARNotifyEvent request) {
public boolean darNotifyEvent(String uri, DARNotifyEvent request, Event event) {
boolean successful = false;

var caseNumber = request.getXMLEventDocument().getEvent().getCaseNumbers().getCaseNumber().toString();
var event = request.getXMLEventDocument().getEvent();
var caseNumber = event.getCaseNumbers().getCaseNumber().toString();

try {
log.info("Sending notification to to DAR PC with case number: {}", caseNumber);
Expand All @@ -42,7 +42,7 @@ public boolean darNotifyEvent(String uri, DARNotifyEvent request) {
var result = DarNotifyEventResult.findByResult(response.getDARNotifyEventResult());

if (OK.equals(result)) {
logApi.notificationSucceeded(uri, event.getCourthouse(), event.getCourtroom(), caseNumber, dateTimeFrom(request),
logApi.notificationSucceeded(uri, event.getCourthouse(), event.getCourtroom(), caseNumber, dateTimeFrom(event),
response.getDARNotifyEventResult());
successful = true;
} else if (result != null) {
Expand All @@ -51,7 +51,7 @@ public boolean darNotifyEvent(String uri, DARNotifyEvent request) {
event.getCourthouse(),
event.getCourtroom(),
caseNumber,
dateTimeFrom(request),
dateTimeFrom(event),
"FAILED",
result.getMessage(),
response.getDARNotifyEventResult(),
Expand All @@ -63,7 +63,7 @@ public boolean darNotifyEvent(String uri, DARNotifyEvent request) {
event.getCourthouse(),
event.getCourtroom(),
caseNumber,
dateTimeFrom(request),
dateTimeFrom(event),
"FAILED",
"result code not recognised",
response.getDARNotifyEventResult(),
Expand All @@ -72,27 +72,26 @@ public boolean darNotifyEvent(String uri, DARNotifyEvent request) {
}
} else {
logApi.notificationFailed(
uri, event.getCourthouse(), event.getCourtroom(), caseNumber, dateTimeFrom(request), "FAILED", "No response", WARN);
uri, event.getCourthouse(), event.getCourtroom(), caseNumber, dateTimeFrom(event), "FAILED", "No response", WARN);
}

} catch (WebServiceException webServiceException) {
logApi.notificationFailed(
uri, event.getCourthouse(), event.getCourtroom(), caseNumber, dateTimeFrom(request), "FAILED",
uri, event.getCourthouse(), event.getCourtroom(), caseNumber, dateTimeFrom(event), "FAILED",
"WebServiceException thrown. Failed to send", ERROR);
}

return successful;
}

private static OffsetDateTime dateTimeFrom(DARNotifyEvent darNotifyEvent) {
var eventDetails = darNotifyEvent.getXMLEventDocument().getEvent();
private static OffsetDateTime dateTimeFrom(Event event) {
return OffsetDateTime.of(
parseInt(eventDetails.getY()),
parseInt(eventDetails.getM()),
parseInt(eventDetails.getD()),
parseInt(eventDetails.getH()),
parseInt(eventDetails.getMIN()),
parseInt(eventDetails.getS()),
parseInt(event.getY()),
parseInt(event.getM()),
parseInt(event.getD()),
parseInt(event.getH()),
parseInt(event.getMIN()),
parseInt(event.getS()),
0,
ZoneOffset.UTC
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.gov.hmcts.darts.event.config;

import org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -11,6 +12,8 @@
import uk.gov.hmcts.darts.log.api.impl.LogApiImpl;
import uk.gov.hmcts.darts.log.service.impl.DarNotificationLoggerServiceImpl;

import java.util.Map;

@Configuration
@EnableConfigurationProperties(DarNotifyEventConfigurationProperties.class)
public class DarNotifyEventConfiguration {
Expand All @@ -23,8 +26,9 @@ public HttpComponentsMessageSender httpComponentsMessageSender() {

@Bean
public Jaxb2Marshaller marshaller() {
var marshaller = new Jaxb2Marshaller();
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.viqsoultions");
marshaller.setMarshallerProperties(Map.of("org.glassfish.jaxb.namespacePrefixMapper", new MyNsPrefixMapper()));
return marshaller;
}

Expand All @@ -49,4 +53,18 @@ public LogApi logApi() {
new DarNotificationLoggerServiceImpl());
}

public static class MyNsPrefixMapper extends NamespacePrefixMapper {

public String getPreferredPrefix(String uri, String suggest, boolean require) {
if ("http://www.VIQSoultions.com".equals(uri)) {
return "";
}

return suggest;
}

public String[] getPreDeclaredNamespaceUris() {
return new String[0];
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package uk.gov.hmcts.darts.event.service.impl;

import com.service.viq.event.Event;
import com.service.viq.event.Event.CaseNumbers;
import com.viqsoultions.DARNotifyEvent;
import com.viqsoultions.Event;
import com.viqsoultions.Event.CaseNumbers;
import com.viqsoultions.ObjectFactory;
import com.viqsoultions.XMLEventDocument;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -13,6 +14,7 @@
import uk.gov.hmcts.darts.event.model.DarNotifyEvent;
import uk.gov.hmcts.darts.event.service.DarNotifyEventService;

import java.io.StringWriter;
import java.time.OffsetDateTime;
import java.time.ZoneId;

Expand All @@ -31,15 +33,15 @@ public class DarNotifyEventServiceImpl implements DarNotifyEventService {
@Override
public void darNotify(DarNotifyEvent darNotifyEvent) {
if (enableDarNotify) {
DARNotifyEvent xmlDarNotifyEvent = convertToXmlDarNotifyEvent(darNotifyEvent);
darNotifyEventClient.darNotifyEvent(darNotifyEvent.getNotificationUrl(), xmlDarNotifyEvent);
var eventAsXml = createEvent(darNotifyEvent);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this Xml? If not, maybe rename var

var darNotifyEventAsXml = convertToXmlDarNotifyEvent(eventAsXml);

darNotifyEventClient.darNotifyEvent(darNotifyEvent.getNotificationUrl(), darNotifyEventAsXml, eventAsXml);
}
}

private DARNotifyEvent convertToXmlDarNotifyEvent(DarNotifyEvent darNotifyEvent) {
ObjectFactory factory = new ObjectFactory();

Event event = factory.createEvent();
private Event createEvent(DarNotifyEvent darNotifyEvent) {
Event event = new Event();
event.setType(darNotifyEvent.getNotificationType());

OffsetDateTime localDateTime = OffsetDateTime.ofInstant(
Expand All @@ -56,17 +58,36 @@ private DARNotifyEvent convertToXmlDarNotifyEvent(DarNotifyEvent darNotifyEvent)
event.setCourthouse(darNotifyEvent.getCourthouse());
event.setCourtroom(darNotifyEvent.getCourtroom());

CaseNumbers caseNumbers = factory.createEventCaseNumbers();
CaseNumbers caseNumbers = new CaseNumbers();
caseNumbers.getCaseNumber().addAll(darNotifyEvent.getCaseNumbers());
event.setCaseNumbers(caseNumbers);

XMLEventDocument xmlEventDocument = factory.createXMLEventDocument();
xmlEventDocument.setEvent(event);
return event;
}

DARNotifyEvent xmlDarNotifyEvent = factory.createDARNotifyEvent();
xmlDarNotifyEvent.setXMLEventDocument(xmlEventDocument);
private DARNotifyEvent convertToXmlDarNotifyEvent(Event eventAsXml) {
DARNotifyEvent xmlDarNotifyEvent = new DARNotifyEvent();
xmlDarNotifyEvent.setXMLEventDocument(serialized(eventAsXml));

return xmlDarNotifyEvent;
}

private String serialized(Event event) {
var writer = new StringWriter();
try {
var context = JAXBContext.newInstance(Event.class);
var marshaller = context.createMarshaller();

marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

marshaller.marshal(event, writer);
} catch (JAXBException e) {
log.error("Error marshalling XML", e);
}

return writer.toString();
}

}
Loading