JAMES-2134 Finally contruct MDN Report when parsing
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/94fbfda9 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/94fbfda9 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/94fbfda9 Branch: refs/heads/master Commit: 94fbfda948ea593c57796fef17ea4e5637a593fe Parents: 270c6dd Author: Raphael Ouazana <[email protected]> Authored: Wed Apr 4 14:16:23 2018 +0200 Committer: Raphael Ouazana <[email protected]> Committed: Thu Apr 5 14:48:43 2018 +0200 ---------------------------------------------------------------------- .../org/apache/james/mdn/MDNReportParser.java | 76 +++++++++++++++++--- .../apache/james/mdn/MDNReportParserTest.java | 70 +++++++++++++----- 2 files changed, 122 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/94fbfda9/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java ---------------------------------------------------------------------- diff --git a/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java b/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java index daf096f..421ed55 100644 --- a/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java +++ b/mdn/src/main/java/org/apache/james/mdn/MDNReportParser.java @@ -19,6 +19,8 @@ package org.apache.james.mdn; +import java.util.Optional; + import org.apache.james.mdn.action.mode.DispositionActionMode; import org.apache.james.mdn.fields.AddressType; import org.apache.james.mdn.fields.Disposition; @@ -34,7 +36,10 @@ import org.apache.james.mdn.modifier.DispositionModifier; import org.apache.james.mdn.sending.mode.DispositionSendingMode; import org.apache.james.mdn.type.DispositionType; import org.parboiled.BaseParser; +import org.parboiled.Parboiled; import org.parboiled.Rule; +import org.parboiled.parserunners.ReportingParseRunner; +import org.parboiled.support.ParsingResult; import com.google.common.annotations.VisibleForTesting; @@ -42,6 +47,15 @@ public class MDNReportParser { public MDNReportParser() { } + public Optional<MDNReport> parse(String mdnReport) { + Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); + ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionNotificationContent()).run(mdnReport); + if (result.matched) { + return Optional.of((MDNReport)result.resultValue); + } + return Optional.empty(); + } + @VisibleForTesting static class Parser extends BaseParser<Object> { // CFWS = (1*([FWS] comment) [FWS]) / FWS @@ -307,14 +321,60 @@ public class MDNReportParser { Rule dispositionNotificationContent() { return Sequence( push(MDNReport.builder()), - Optional(Sequence(reportingUaField(), crlf())), - Optional(Sequence(mdnGatewayField(), crlf())), - Optional(Sequence(originalRecipientField(), crlf())), - Sequence(finalRecipientField(), crlf()), - Optional(Sequence(originalMessageIdField(), crlf())), - Sequence(dispositionField(), crlf()), - ZeroOrMore(Sequence(errorField(), crlf())), - ZeroOrMore(Sequence(extentionField(), crlf()))); + Optional(Sequence(reportingUaField(), ACTION(setReportingUaField()), crlf())), + Optional(Sequence(mdnGatewayField(), ACTION(setMdnGatewayField()), crlf())), + Optional(Sequence(originalRecipientField(), ACTION(setOriginalRecipientField()), crlf())), + Sequence(finalRecipientField(), ACTION(setFinalRecipientField()), crlf()), + Optional(Sequence(originalMessageIdField(), ACTION(setOriginalMessageIdField()), crlf())), + Sequence(dispositionField(), ACTION(setDispositionField()), crlf()), + ZeroOrMore(Sequence(errorField(), ACTION(addErrorField()), crlf())), + ZeroOrMore(Sequence(extentionField(), ACTION(addExtensionField()), crlf())), + ACTION(buildMDNReport())); + } + + boolean setReportingUaField() { + this.<MDNReport.Builder>peekParent().reportingUserAgentField(popT()); + return true; + } + + boolean setMdnGatewayField() { + this.<MDNReport.Builder>peekParent().gatewayField(popT()); + return true; + } + + boolean setOriginalRecipientField() { + this.<MDNReport.Builder>peekParent().originalRecipientField(this.<OriginalRecipient>popT()); + return true; + } + + boolean setFinalRecipientField() { + this.<MDNReport.Builder>peekParent().finalRecipientField(this.<FinalRecipient>popT()); + return true; + } + + boolean setOriginalMessageIdField() { + this.<MDNReport.Builder>peekParent().originalMessageIdField(this.<OriginalMessageId>popT()); + return true; + } + + boolean setDispositionField() { + this.<MDNReport.Builder>peekParent().dispositionField(popT()); + return true; + } + + boolean addErrorField() { + this.<MDNReport.Builder>peekParent().addErrorField(this.<Error>popT()); + return true; + } + + boolean addExtensionField() { + this.<MDNReport.Builder>peekParent().withExtensionField(this.<ExtensionField>popT()); + return true; + } + + boolean buildMDNReport() { + push(this.<MDNReport.Builder>popT().build()); + return true; } /* reporting-ua-field = "Reporting-UA" ":" OWS ua-name OWS [ http://git-wip-us.apache.org/repos/asf/james-project/blob/94fbfda9/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java ---------------------------------------------------------------------- diff --git a/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java b/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java index dabe94c..50c2815 100644 --- a/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java +++ b/mdn/src/test/java/org/apache/james/mdn/MDNReportParserTest.java @@ -21,6 +21,8 @@ package org.apache.james.mdn; import static org.assertj.core.api.Assertions.assertThat; +import java.util.Optional; + import org.apache.james.mdn.MDNReportParser.Parser; import org.apache.james.mdn.action.mode.DispositionActionMode; import org.apache.james.mdn.fields.AddressType; @@ -44,15 +46,14 @@ import org.parboiled.support.ParsingResult; public class MDNReportParserTest { @Test - public void dispositionNotificationContentShouldNotParseWhenMissingFinalRecipient() { + public void parseShouldReturnEmptyWhenMissingFinalRecipient() { String missing = "Disposition: automatic-action/MDN-sent-automatically;processed\r\n"; - Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); - ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionNotificationContent()).run(missing); - assertThat(result.matched).isFalse(); + MDNReportParser testee = new MDNReportParser(); + assertThat(testee.parse(missing)).isEmpty(); } @Test - public void dispositionNotificationContentShouldParseWhenMaximalSubset() { + public void parseShouldReturnMdnReportWhenMaximalSubset() { String maximal = "Reporting-UA: UA_name; UA_product\r\n" + "MDN-Gateway: smtp; apache.org\r\n" + "Original-Recipient: rfc822; originalRecipient\r\n" + @@ -63,28 +64,65 @@ public class MDNReportParserTest { "Error: Message2\r\n" + "X-OPENPAAS-IP: 177.177.177.77\r\n" + "X-OPENPAAS-PORT: 8000\r\n"; - Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); - ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionNotificationContent()).run(maximal); - assertThat(result.matched).isTrue(); + Optional<MDNReport> expected = Optional.of(MDNReport.builder() + .reportingUserAgentField(ReportingUserAgent.builder() + .userAgentName("UA_name") + .userAgentProduct("UA_product") + .build()) + .gatewayField(Gateway.builder() + .nameType(new AddressType("smtp")) + .name(Text.fromRawText("apache.org")) + .build()) + .originalRecipientField("originalRecipient") + .finalRecipientField("final_recipient") + .originalMessageIdField("<[email protected]>") + .dispositionField(Disposition.builder() + .actionMode(DispositionActionMode.Automatic) + .sendingMode(DispositionSendingMode.Automatic) + .type(DispositionType.Processed) + .addModifier(DispositionModifier.Error) + .addModifier(DispositionModifier.Failed) + .build()) + .addErrorField("Message1") + .addErrorField("Message2") + .withExtensionField(ExtensionField.builder() + .fieldName("X-OPENPAAS-IP") + .rawValue(" 177.177.177.77") + .build()) + .withExtensionField(ExtensionField.builder() + .fieldName("X-OPENPAAS-PORT") + .rawValue(" 8000") + .build()) + .build()); + MDNReportParser testee = new MDNReportParser(); + Optional<MDNReport> actual = testee.parse(maximal); + assertThat(actual).isEqualTo(expected); } @Test - public void dispositionNotificationContentShouldParseWhenMinimalSubset() { + public void parseShouldReturnMdnReportWhenMinimalSubset() { String minimal = "Final-Recipient: rfc822; final_recipient\r\n" + "Disposition: automatic-action/MDN-sent-automatically;processed\r\n"; - Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); - ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionNotificationContent()).run(minimal); - assertThat(result.matched).isTrue(); + Optional<MDNReport> expected = Optional.of(MDNReport.builder() + .finalRecipientField("final_recipient") + .dispositionField(Disposition.builder() + .actionMode(DispositionActionMode.Automatic) + .sendingMode(DispositionSendingMode.Automatic) + .type(DispositionType.Processed) + .build()) + .build()); + MDNReportParser testee = new MDNReportParser(); + Optional<MDNReport> actual = testee.parse(minimal); + assertThat(actual).isEqualTo(expected); } @Test - public void dispositionNotificationContentShouldNotParseWhenDuplicatedFields() { + public void parseShouldReturnEmptyWhenDuplicatedFields() { String duplicated = "Final-Recipient: rfc822; final_recipient\r\n" + "Final-Recipient: rfc822; final_recipient\r\n" + "Disposition: automatic-action/MDN-sent-automatically;processed\r\n"; - Parser parser = Parboiled.createParser(MDNReportParser.Parser.class); - ParsingResult<Object> result = new ReportingParseRunner<>(parser.dispositionNotificationContent()).run(duplicated); - assertThat(result.matched).isFalse(); + MDNReportParser testee = new MDNReportParser(); + assertThat(testee.parse(duplicated)).isEmpty(); } @Test --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
