Skip to content

Commit

Permalink
PW-922: reduce log in MxSwiftMessage parse when the XML is not recogn…
Browse files Browse the repository at this point in the history
…ized (#59)
  • Loading branch information
zubri authored Aug 18, 2022
1 parent 98a1f2d commit 86f39df
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 10 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Prowide ISO 20022 - CHANGELOG
-----------------------------------------------------------------------------------------------------------------------

RELEASE 9.2.8 - August 2022
* (PW-922) Added a parameter in the MxReadParams used by the AbstractMX#parse to control the log verbosity when parsing unrecognized messages

RELEASE 9.2.7 - August 2022
* Added model for "trck" types
* (GH-45) Fixed Json serialization in Java 17
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ configure(subprojects.findAll {it.name.endsWith('-types')}) {
project(':iso20022-core') {
dependencies {
// included build
api 'com.prowidesoftware:pw-swift-core:SRU2021-9.2.16'
api 'com.prowidesoftware:pw-swift-core:SRU2021-9.2.17'

implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation 'com.google.code.gson:gson:2.8.9'
Expand Down Expand Up @@ -227,7 +227,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:SRU2021-9.2.16'
api 'com.prowidesoftware:pw-swift-core:SRU2021-9.2.17'
implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation 'com.google.code.gson:gson:2.8.9'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,13 @@ public void updateMetadata(MessageMetadataStrategy strategy) {

private void applyStrategy(String xml, MessageMetadataStrategy strategy) {
boolean isKnownType = this.businessProcess != null && this.functionality != null && this.variant != null && this.version != null;
AbstractMX mx = isKnownType ? AbstractMX.parse(xml, getMxId()) : AbstractMX.parse(xml);
MxId mxId = isKnownType ? getMxId() : null;

// when parsing the message just for the metadata extraction, we want to avoid underlying error logs
// since this MxSwiftMessage is lenient on the constraints of the parsed XML payload
MxReadParams params = new MxReadParams();
params.verbose = false;
AbstractMX mx = MxReadImpl.parse(xml, mxId, params);

if (mx == null) {
// could not parse the XML into a message model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
* @since 9.0
*/
public class MxReadImpl implements MxRead {
private static final transient Logger log = Logger.getLogger(MxReadImpl.class.getName());
private static final Logger log = Logger.getLogger(MxReadImpl.class.getName());

/**
* Static parse implementation of {@link MxRead#read(Class, String, Class[])}
Expand Down Expand Up @@ -109,7 +109,7 @@ public static AbstractMX parse(final String xml, MxId id) {
/**
* @since 9.2.6
*/
static AbstractMX parse(final String xml, final MxId id, final MxReadParams params) {
public static AbstractMX parse(final String xml, final MxId id, final MxReadParams params) {
Objects.requireNonNull(xml, "XML to parse must not be null");
Validate.notBlank(xml, "XML to parse must not be a blank string");
Objects.requireNonNull(params, "unmarshalling params cannot be null");
Expand All @@ -121,7 +121,8 @@ static AbstractMX parse(final String xml, final MxId id, final MxReadParams para
if (namespace.isPresent()) {
resolvedId = new MxId(namespace.get());
} else {
log.severe("Cannot detect the Mx type from the XML, ensure the XML contains proper namespaces or provide an MxId object as parameter to the parse call");
Level level = params.verbose? Level.SEVERE: Level.FINE;
log.log(level, "Cannot detect the Mx type from the XML, make sure the XML contains proper namespaces or provide an MxId object as parameter to the parse call");
return null;
}
}
Expand All @@ -135,9 +136,17 @@ static AbstractMX parse(final String xml, final MxId id, final MxReadParams para
java.lang.reflect.Field _classes = clazz.getDeclaredField("_classes");
mx = parse(clazz, xml, (Class[]) _classes.get(null), params);
} catch (ClassNotFoundException e) {
log.log(Level.SEVERE, "MX model implementation not found for " + fqn, e);
if (params.verbose) {
log.log(Level.SEVERE, "Cannot find class " + fqn + " to parse the XML", e);
} else {
log.fine("MX model implementation not found for " + fqn);
}
} catch (Exception e) {
log.log(Level.SEVERE, "Error calling parse in specific MX model implementation", e);
if (params.verbose) {
log.log(Level.SEVERE, "Error calling parse in specific MX model implementation", e);
} else {
log.fine("Error calling parse in specific MX model implementation");
}
}
return mx;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ public class MxReadParams {
*/
public TypeAdaptersConfiguration adapters;

/**
* When true; errors during parsing, such as a ClassNotFoundException, will generate a log error, while when set
* to false those errors will generate finer log entries.
*
* @since 9.2.8
*/
public boolean verbose = true;

public MxReadParams() {
this.adapters = new TypeAdaptersConfiguration();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,78 @@ public void category() {
assertEquals("camt", mx.getCategory());
}

/**
* Tests the MxSwiftMessage can parse an XML, even if the corresponding AbstractMX subclass is missing
*/
@Test
public void testUnrecognizedMessage() {
String xmlInput = "<Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:DRAFT6camt.077.001.01\">\n" +
"<BllgRpt>\n" +
" <MsgHdr>\n" +
" <MsgId>12345</MsgId>\n" +
" <CreDtTm>2022-05-24T10:29:05+08:00</CreDtTm>\n" +
" <ReqTp>\n" +
" <Prtry>\n" +
" <Id>Tax Invoice for RTGS Billing</Id>\n" +
" </Prtry>\n" +
" </ReqTp>\n" +
" </MsgHdr>\n" +
" <BllgRptOrErr>\n" +
" <BllgRpt>\n" +
" <RgltryData>\n" +
" <Invcr>\n" +
" <Nm>The Monetary Authority of Foobar</Nm>\n" +
" <PstlAdr>\n" +
" <AdrLine>99 Foo Way, FOO Building 012345</AdrLine>\n" +
" </PstlAdr>\n" +
" <Id>\n" +
" <OrgId>\n" +
" <Othr>\n" +
" <Id>M12343076J</Id>\n" +
" </Othr>\n" +
" </OrgId>\n" +
" </Id>\n" +
" </Invcr>\n" +
" <Invcee>\n" +
" <Nm>FOO BANK OF FOOBAR</Nm>\n" +
" <PstlAdr>\n" +
" <AdrLine>44 Street Unit 27-01/08 Foobar Hub 012345</AdrLine>\n" +
" </PstlAdr>\n" +
" </Invcee>\n" +
" <InvcLglStmt>See further information on the RTGS Billing Detail screen</InvcLglStmt>\n" +
" </RgltryData>\n" +
" <InvcDt>2022-05-24</InvcDt>\n" +
" <BllgId>I22/123/0123</BllgId>\n" +
" <BllgPrd>\n" +
" <FrDt>2022-05-25</FrDt>\n" +
" <ToDt>2022-05-25</ToDt>\n" +
" </BllgPrd>\n" +
" <InvcTtls>\n" +
" <Tax>\n" +
" <Rate>7</Rate>\n" +
" <TaxblAmt Ccy=\"SGD\">0.30</TaxblAmt>\n" +
" <Amt Ccy=\"SGD\">0.02</Amt>\n" +
" </Tax>\n" +
" <TtlInvcAmt Ccy=\"SGD\">0.32</TtlInvcAmt>\n" +
" <PmtDueDt>2022-05-24</PmtDueDt>\n" +
" </InvcTtls>\n" +
" <SvcCtgyTtls>\n" +
" <AcctId>\n" +
" <CshAcctId>\n" +
" <Othr>\n" +
" <Id>12340100</Id>\n" +
" </Othr>\n" +
" </CshAcctId>\n" +
" </AcctId>\n" +
" <TtlInvcAmt Ccy=\"SGD\">0.32</TtlInvcAmt>\n" +
" <SvcCtgy>CHAR</SvcCtgy>\n" +
" </SvcCtgyTtls>\n" +
" </BllgRpt>\n" +
" </BllgRptOrErr>\n" +
"</BllgRpt>\n" +
"</Document>\n";
MxSwiftMessage mx = new MxSwiftMessage(xmlInput);
assertNotNull(mx);
assertEquals("camt.077.001.01", mx.getIdentifier());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@

/**
* Test for the Mx parser API in the base {@link AbstractMX} class
*
* @since 9.0
*/
public class AbstractMXTest {

Expand Down Expand Up @@ -113,6 +111,78 @@ public void testParseXsys() {
" </Doc:xsys.011.001.02>\n" +
" </Doc:Document>";
AbstractMX mx = AbstractMX.parse(xml);
assertNotNull(mx);
}

@Test
public void testUnrecognizedMessage() {
String xml = "<Document xmlns=\"urn:iso:std:iso:20022:tech:xsd:DRAFT6camt.077.001.01\">\n" +
"<BllgRpt>\n" +
" <MsgHdr>\n" +
" <MsgId>12345</MsgId>\n" +
" <CreDtTm>2022-05-24T10:29:05+08:00</CreDtTm>\n" +
" <ReqTp>\n" +
" <Prtry>\n" +
" <Id>Tax Invoice for RTGS Billing</Id>\n" +
" </Prtry>\n" +
" </ReqTp>\n" +
" </MsgHdr>\n" +
" <BllgRptOrErr>\n" +
" <BllgRpt>\n" +
" <RgltryData>\n" +
" <Invcr>\n" +
" <Nm>The Monetary Authority of Foobar</Nm>\n" +
" <PstlAdr>\n" +
" <AdrLine>99 Foo Way, FOO Building 012345</AdrLine>\n" +
" </PstlAdr>\n" +
" <Id>\n" +
" <OrgId>\n" +
" <Othr>\n" +
" <Id>M12343076J</Id>\n" +
" </Othr>\n" +
" </OrgId>\n" +
" </Id>\n" +
" </Invcr>\n" +
" <Invcee>\n" +
" <Nm>FOO BANK OF FOOBAR</Nm>\n" +
" <PstlAdr>\n" +
" <AdrLine>44 Street Unit 27-01/08 Foobar Hub 012345</AdrLine>\n" +
" </PstlAdr>\n" +
" </Invcee>\n" +
" <InvcLglStmt>See further information on the RTGS Billing Detail screen</InvcLglStmt>\n" +
" </RgltryData>\n" +
" <InvcDt>2022-05-24</InvcDt>\n" +
" <BllgId>I22/123/0123</BllgId>\n" +
" <BllgPrd>\n" +
" <FrDt>2022-05-25</FrDt>\n" +
" <ToDt>2022-05-25</ToDt>\n" +
" </BllgPrd>\n" +
" <InvcTtls>\n" +
" <Tax>\n" +
" <Rate>7</Rate>\n" +
" <TaxblAmt Ccy=\"SGD\">0.30</TaxblAmt>\n" +
" <Amt Ccy=\"SGD\">0.02</Amt>\n" +
" </Tax>\n" +
" <TtlInvcAmt Ccy=\"SGD\">0.32</TtlInvcAmt>\n" +
" <PmtDueDt>2022-05-24</PmtDueDt>\n" +
" </InvcTtls>\n" +
" <SvcCtgyTtls>\n" +
" <AcctId>\n" +
" <CshAcctId>\n" +
" <Othr>\n" +
" <Id>12340100</Id>\n" +
" </Othr>\n" +
" </CshAcctId>\n" +
" </AcctId>\n" +
" <TtlInvcAmt Ccy=\"SGD\">0.32</TtlInvcAmt>\n" +
" <SvcCtgy>CHAR</SvcCtgy>\n" +
" </SvcCtgyTtls>\n" +
" </BllgRpt>\n" +
" </BllgRptOrErr>\n" +
"</BllgRpt>\n" +
"</Document>\n";
AbstractMX mx = AbstractMX.parse(xml);
assertNull(mx);
}

}

0 comments on commit 86f39df

Please sign in to comment.