MdnMimeMessageInspector { public Map<String, String> getMdnFields() { Map<String, String> ret = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); try { BodyPart bp = getMessageDispositionNotificationPart(); boolean contentIsBase64Encoded = false; String[] contentTransferEncodings = bp.getHeader("Content-Transfer-Encoding"); if (contentTransferEncodings != null && contentTransferEncodings.length > 0) { if (contentTransferEncodings.length > 1) log.warn("MDN has multiple Content-Transfer-Encoding, we only try the first one"); String encoding = contentTransferEncodings[0]; if (encoding == null) encoding = ""; encoding = encoding.trim(); log.debug("MDN specifies Content-Transfer-Encoding : '" + encoding + "'"); if ("base64".equalsIgnoreCase(encoding)) { contentIsBase64Encoded = true; } } Object content = bp.getContent(); if (content instanceof InputStream) { InputStream contentInputStream = (InputStream) content; if (contentIsBase64Encoded) { log.debug("MDN seems to be base64 encoded, wrapping content stream in Base64 decoding stream"); contentInputStream = new Base64InputStream(contentInputStream); } BufferedReader r = new BufferedReader(new InputStreamReader(contentInputStream)); while (r.ready()) { String line = r.readLine(); int firstColon = line.indexOf(":"); if (firstColon > 0) { String key = line.substring(0, firstColon).trim(); String value = line.substring(firstColon + 1).trim(); ret.put(key, value); } } } else { throw new Exception("Unsupported MDN content, expected InputStream found @ " + content.toString()); } } catch (Exception e) { throw new IllegalStateException("Unable to retrieve the values from the MDN : " + e.getMessage(), e); } return ret; } MdnMimeMessageInspector(MimeMessage mdnMimeMessage); MimeMultipart getSignedMultiPart(); MimeMultipart getMultipartReport(); BodyPart getPlainTextBodyPart(); BodyPart getMessageDispositionNotificationPart(); String getPlainTextPartAsText(); Map<String, String> getMdnFields(); boolean isOkOrWarning(Mic outboundMic);  }
@Test public void parseOpenAS2MDNFields() throws Exception { InputStream resourceAsStream = MdnMimeMessageInspectorTest.class.getClassLoader().getResourceAsStream(OPENAS2_MDN_TXT); assertNotNull(resourceAsStream, "Unable to find " + OPENAS2_MDN_TXT + " in class path"); MimeMessage mimeMessage = MimeMessageHelper.parse(resourceAsStream); MdnMimeMessageInspector mdnMimeMessageInspector = new MdnMimeMessageInspector(mimeMessage); Map<String, String> fields = mdnMimeMessageInspector.getMdnFields(); assertEquals(fields.get("Original-Recipient"), "rfc822; OpenAS2A"); assertEquals(fields.get("Final-Recipient"), "rfc822; OpenAS2A"); assertEquals(fields.get("Original-Message-ID"), "42"); assertEquals(fields.get("Received-Content-MIC"), "Fp67Ews9SJa5pKGXVl07dBuVW4I=, sha1"); }
@Test public void parseBase64EncodedMDN() throws Exception { InputStream resourceAsStream = MdnMimeMessageInspectorTest.class.getClassLoader().getResourceAsStream(IBX_MDN_BASE64); assertNotNull(resourceAsStream, "Unable to find " + IBX_MDN_BASE64 + " in class path"); MimeMessage mimeMessage = MimeMessageHelper.parse(resourceAsStream); MdnMimeMessageInspector mdnMimeMessageInspector = new MdnMimeMessageInspector(mimeMessage); Map<String, String> fields = mdnMimeMessageInspector.getMdnFields(); assertEquals(fields.size(), 6); assertEquals(fields.get("Reporting-UA"), "Oxalis"); assertEquals(fields.get("Disposition"), "automatic-action/MDN-sent-automatically; processed"); assertEquals(fields.get("Original-Recipient"), "rfc822; APP_1000000030"); assertEquals(fields.get("Final-Recipient"), "rfc822; APP_1000000030"); assertEquals(fields.get("Original-Message-ID"), "19a9099c-c553-4ffa-9c60-de2fcfa2922f"); assertEquals(fields.get("Received-Content-MIC"), "VZOW8aRv9e8uEQEdGRdxwcOYH1g=, sha1"); }