From 7cc0e5923471ddfae6c13da801187c517e94bb33 Mon Sep 17 00:00:00 2001 From: Sebastian Zubrinic Date: Fri, 31 May 2024 21:19:11 -0300 Subject: [PATCH 1/4] PW-1875: Zulu time zone conversion for BAH v1 (#117) Co-authored-by: fernando.desarriera --- CHANGELOG.md | 3 +++ .../mx/adapters/ZuluDateTimeAdapter.java | 19 +++++++++++++++++-- .../mx/adapters/ZuluDateTimeAdapterTest.java | 8 ++++---- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89516dfe9..19712d237 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Prowide ISO 20022 - CHANGELOG +#### 9.4.6 - May 2024 + * (PW-1875) Fixed the `ZuluDateTimeAdapter` to convert the datetime to UTC offset if needed + #### 9.4.5 - May 2024 * (PW-1875) Changed the BusinessApplicationHeaderV01 marshaller to always use Zulu timezone with "Z" indicator diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/adapters/ZuluDateTimeAdapter.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/adapters/ZuluDateTimeAdapter.java index b4906d274..384107c75 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/adapters/ZuluDateTimeAdapter.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/adapters/ZuluDateTimeAdapter.java @@ -16,7 +16,11 @@ package com.prowidesoftware.swift.model.mx.adapters; import java.text.SimpleDateFormat; +import java.util.GregorianCalendar; +import java.util.TimeZone; import javax.xml.bind.annotation.adapters.XmlAdapter; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; /** @@ -93,10 +97,21 @@ public String marshal(XMLGregorianCalendar cal) throws Exception { } else { String formatted; synchronized (marshalFormat) { - // Viene un calendar no UTC? - formatted = AdapterUtils.format(this.marshalFormat, cal); + // Create a new Calendar with the Date represented in Zulu Time + XMLGregorianCalendar xmlGregorianCalendarZulu = getXmlGregorianCalendarInZulu(cal); + formatted = AdapterUtils.format(this.marshalFormat, xmlGregorianCalendarZulu); } return formatted.replace(".000", ""); } } + + private static XMLGregorianCalendar getXmlGregorianCalendarInZulu(XMLGregorianCalendar cal) + throws DatatypeConfigurationException { + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + XMLGregorianCalendar xmlGregorianCalendar = datatypeFactory.newXMLGregorianCalendar(); + GregorianCalendar gregorianCalendar = xmlGregorianCalendar.toGregorianCalendar(); + gregorianCalendar.setTime(cal.toGregorianCalendar().getTime()); + gregorianCalendar.setTimeZone(TimeZone.getTimeZone("Z")); + return datatypeFactory.newXMLGregorianCalendar(gregorianCalendar); + } } diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/ZuluDateTimeAdapterTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/ZuluDateTimeAdapterTest.java index 3566b838f..9ad132b4b 100644 --- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/ZuluDateTimeAdapterTest.java +++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/ZuluDateTimeAdapterTest.java @@ -71,14 +71,14 @@ public void testUnmarshallNoOffset() throws Exception { public void testMarshallFractionOfSeconds() throws Exception { XMLGregorianCalendar cal = DatatypeFactory.newInstance() .newXMLGregorianCalendar(BigInteger.valueOf(2022), 3, 4, 12, 50, 8, new BigDecimal("0.123"), -180); - assertEquals("2022-03-04T12:50:08.123Z", adapter.marshal(cal)); + assertEquals("2022-03-04T15:50:08.123Z", adapter.marshal(cal)); } @Test public void testMarshallNoFractionOfSeconds() throws Exception { XMLGregorianCalendar cal = DatatypeFactory.newInstance() .newXMLGregorianCalendar(BigInteger.valueOf(2022), 3, 4, 12, 50, 8, null, -180); - assertEquals("2022-03-04T12:50:08Z", adapter.marshal(cal)); + assertEquals("2022-03-04T15:50:08Z", adapter.marshal(cal)); } @Test @@ -154,7 +154,7 @@ public void test_marshall_message_with_BAH1_and_CreDt_OffsetDateTime() { // Create a new instance of MxPacs00800110 with AppHdr CreDtTm ZuluDateTime MxPacs00800110 mxPacs00800110 = MxPacs00800110.parse(xml); - // After CreDtTm is parsed, it should be 2024-03-27T20:45:56Z - assertTrue(mxPacs00800110.message().contains("2024-03-27T20:45:56Z")); + // After CreDtTm is parsed, it should be in UTC offset and formatted with Zulu indicator + assertTrue(mxPacs00800110.message().contains("2024-03-27T23:45:56Z")); } } From 4d991d893937288e4c7c875dd4bf986faca5809c Mon Sep 17 00:00:00 2001 From: zubri Date: Fri, 28 Jun 2024 15:49:53 -0300 Subject: [PATCH 2/4] enhanced parsing to detect business service from header --- CHANGELOG.md | 4 ++++ .../swift/model/mx/AppHdrFactory.java | 6 ++++++ .../swift/model/mx/MxParseUtils.java | 19 +++++++++++++++++-- .../swift/model/mx/MxParseUtilsTest.java | 1 + 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4ce8abcc..a749a8e5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Prowide ISO 20022 - CHANGELOG +#### 9.5.1 - SNAPSHOT + * Enhanced the AppHdrFactory to honor the business service set in the parameter MxId + * Enhanced the MxParseUtils#identifyMessage to set the business service in the MxId when present + #### 9.5.0 - May 2024 * SWIFT Standard release update 2024 (live 16 November 2024) * Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2024/getting-started/deprecation/) diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrFactory.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrFactory.java index ec24220fd..2a4743512 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrFactory.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrFactory.java @@ -105,6 +105,9 @@ public static BusinessAppHdrV02 createBusinessAppHdrV02( if (id != null) { h.setMsgDefIdr(id.id()); + if (id.getBusinessService().isPresent()) { + h.setBizSvc(id.getBusinessService().get()); + } } h.setCreDt(XMLGregorianCalendarUtils.now()); @@ -149,6 +152,9 @@ public static BusinessAppHdrV03 createBusinessAppHdrV03( if (id != null) { h.setMsgDefIdr(id.id()); + if (id.getBusinessService().isPresent()) { + h.setBizSvc(id.getBusinessService().get()); + } } h.setCreDt(XMLGregorianCalendarUtils.now()); diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/MxParseUtils.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/MxParseUtils.java index 8be6018fb..c9820b43a 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/MxParseUtils.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/MxParseUtils.java @@ -194,7 +194,7 @@ public static String getBICFromDN(final String dn) { public static Optional identifyMessage(final String xml) { Optional namespace = NamespaceReader.findDocumentNamespace(xml); if (namespace.isPresent()) { - return namespace.map(MxId::new); + return enrichBusinessService(namespace.map(MxId::new).orElse(null), xml); } // if the Document does not have a namespace, try to identify the message from the header @@ -205,7 +205,7 @@ public static Optional identifyMessage(final String xml) { } if (element.isPresent()) { try { - return Optional.of(new MxId(element.get().getElementText())); + return enrichBusinessService(new MxId(element.get().getElementText()), xml); } catch (XMLStreamException e) { log.finer("Error identifying message: " + e.getMessage()); } @@ -214,6 +214,21 @@ public static Optional identifyMessage(final String xml) { return Optional.empty(); } + private static Optional enrichBusinessService(MxId mxId, final String xml) { + if (mxId == null) { + return Optional.empty(); + } + Optional element = NamespaceReader.findElement(xml, "BizSvc"); + if (element.isPresent()) { + try { + mxId.setBusinessService(element.get().getElementText()); + } catch (XMLStreamException e) { + log.finer("Error identifying business service: " + e.getMessage()); + } + } + return Optional.of(mxId); + } + /** * This method is intended to fix some malformed XML content that is not compliant with the XML specification * to enable the parsing and processing of the payload to be lenient. diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/MxParseUtilsTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/MxParseUtilsTest.java index 3cca91dbe..239e524f3 100644 --- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/MxParseUtilsTest.java +++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/MxParseUtilsTest.java @@ -128,6 +128,7 @@ public void testIdentifyMessage_FromBAH() { MxId id = MxParseUtils.identifyMessage(xml).orElse(null); assertNotNull(id); assertEquals("seev.031.002.03", id.id()); + assertEquals("CSD", id.getBusinessService().orElse(null)); } @Test From b25d8769ca6a745dbd184874fbe89657d7146b0d Mon Sep 17 00:00:00 2001 From: zubri Date: Fri, 28 Jun 2024 21:09:56 -0300 Subject: [PATCH 3/4] release --- CHANGELOG.md | 2 +- build.gradle | 2 +- .../java/com/prowidesoftware/swift/model/MxId.java | 3 ++- .../swift/model/mx/AppHdrFactoryTest.java | 11 +++++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a749a8e5e..04a74aa41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Prowide ISO 20022 - CHANGELOG -#### 9.5.1 - SNAPSHOT +#### 9.5.1 - June 2024 * Enhanced the AppHdrFactory to honor the business service set in the parameter MxId * Enhanced the MxParseUtils#identifyMessage to set the business service in the MxId when present diff --git a/build.gradle b/build.gradle index 120d4412b..5eeb7bd8f 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { dependencies { classpath 'ru.vyarus:gradle-quality-plugin:4.7.0' classpath 'pl.allegro.tech.build:axion-release-plugin:1.13.6' - classpath 'io.github.gradle-nexus:publish-plugin:1.1.0' + classpath 'io.github.gradle-nexus:publish-plugin:2.0.0' classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.13.0' // above this version requires Java 11 } } diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/MxId.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/MxId.java index 40fa3cd07..49eab5393 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/MxId.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/MxId.java @@ -323,7 +323,8 @@ public Optional getBusinessService() { * @param businessService a string value to set as discriminator, for example "swift.cbprplus.cov.02" * @since 9.5.0 */ - public void setBusinessService(String businessService) { + public MxId setBusinessService(String businessService) { this.businessService = businessService; + return this; } } diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AppHdrFactoryTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AppHdrFactoryTest.java index de93fafca..ae1b41e51 100644 --- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AppHdrFactoryTest.java +++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AppHdrFactoryTest.java @@ -22,4 +22,15 @@ void createBusinessAppHdrV01() { // for BAH v01 the date time must be ISONormalisedDateTime assertTrue(xml.contains("Z")); } + + @Test + void createBusinessAppHdrV02_WithBusinessService() { + BusinessAppHdrV02 h = AppHdrFactory.createBusinessAppHdrV02( + "AAAAUSXXXXX", + "BBBBUSXXXXX", + "REF12345", + new MxId("pacs.009.001.08").setBusinessService("swift.cbprplus.cov.02")); + assertNotNull(h); + assertEquals("swift.cbprplus.cov.02", h.getBizSvc()); + } } From 5ff39e8eef59ee22f5f93a507fc0980912241e08 Mon Sep 17 00:00:00 2001 From: zubri Date: Sat, 29 Jun 2024 13:53:51 -0300 Subject: [PATCH 4/4] core update and release --- CHANGELOG.md | 2 +- build.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08b948e98..dd8f7d8da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Prowide ISO 20022 - CHANGELOG -#### 9.5.2 - SNAPSHOT +#### 9.5.2 - June 2024 * (PW-1875) Fixed the `ZuluDateTimeAdapter` to convert the datetime to UTC offset if needed #### 9.5.1 - June 2024 diff --git a/build.gradle b/build.gradle index 5eeb7bd8f..b2460395f 100644 --- a/build.gradle +++ b/build.gradle @@ -134,7 +134,7 @@ configure(subprojects.findAll {it.name.endsWith('-mx')}) { project(':iso20022-core') { dependencies { // included build - api 'com.prowidesoftware:pw-swift-core:SRU2024-9.5.0' + api 'com.prowidesoftware:pw-swift-core:SRU2024-9.5.1' implementation 'org.apache.commons:commons-lang3:3.14.0' implementation 'com.google.code.gson:gson:2.11.0' @@ -313,7 +313,7 @@ artifacts { // declared dependencies for pom generation dependencies { // included build (keep in sync with the latest Prowide Core version) - api 'com.prowidesoftware:pw-swift-core:SRU2024-9.5.0' + api 'com.prowidesoftware:pw-swift-core:SRU2024-9.5.1' implementation 'org.apache.commons:commons-lang3:3.14.0' implementation 'com.google.code.gson:gson:2.10' }