/** * Overridable method for custom processing after the message has been processed by the SMTP * agent. Includes the tracking information if available and the message direction. For passivity, * this method calls {@link #onPostprocessMessage(Mail, MessageProcessResult)} by default after * performing its operations. * * @param mail The incoming mail message. The contents of the message may have changed from when * it was originally received. * @param result Contains results of the message processing including the resulting message. * @param isOutgoing Indicate the direction of the message: incoming or outgoing. * @param tx Contains tracking information if available. */ protected void onPostprocessMessage( Mail mail, MessageProcessResult result, boolean isOutgoing, Tx tx) { // if there are rejected recipients and an outgoing IMF message, then we may need to send a DSN // message boolean sendDSN = false; if (isOutgoing && tx != null && tx.getMsgType() == TxMessageType.IMF && result.getProcessedMessage().hasRejectedRecipients()) { final boolean timely = TxUtil.isReliableAndTimelyRequested(tx); if ((timely && this.autoDSNForTimelyAndReliable) || (!timely && this.autoDSNForGeneral)) sendDSN = true; } if (sendDSN) sendDSN(tx, result.getProcessedMessage().getRejectedRecipients(), true); this.onPostprocessMessage(mail, result); }
/** * Overridable method for custom processing when a message is rejected by the SMTP agent. Includes * the tracking information if available and the message direction. For passivity, this method * calls {@link #onMessageRejected(Mail, NHINDAddressCollection, NHINDAddress, Throwable)} by * default after performing its operations. * * @param message The mail message that the agent attempted to process. * @param recipients A collection of recipients that this message was intended to be delievered * to. * @param sender The sender of the message. * @param isOutgoing Indicate the direction of the message: incoming or outgoing. * @param tx Contains tracking information if available. Generally this information will only be * available for outgoing messages as rejected incoming messages more than likely will not * have been decrypted yet. * @param t Exception thrown by the agent when the message was rejected. May be null; */ protected void onMessageRejected( Mail mail, NHINDAddressCollection recipients, NHINDAddress sender, boolean isOutgoing, Tx tx, Throwable t) { // if this is an outgoing IMF message, then we may need to send a DSN message boolean sendDSN = false; if (isOutgoing && tx != null && tx.getMsgType() == TxMessageType.IMF) { final boolean timely = TxUtil.isReliableAndTimelyRequested(tx); if ((timely && this.autoDSNForTimelyAndReliable) || (!timely && this.autoDSNForGeneral)) sendDSN = true; } if (sendDSN) sendDSN(tx, recipients, true); this.onMessageRejected(mail, recipients, sender, t); }
/** * Determines if the pre-parsed message is requesting timely and reliable delivery. This is * determined by the existence of the X-DIRECT-FINAL-DESTINATION-DELIVERY message disposition * option on the original message. * * @param imfMessage The message that is being inspected for timely and reliable messaging. * @return true if the original message indicates that it requires timely and reliable delivery; * false otherwise */ public static boolean isReliableAndTimelyRequested(Tx imfMessage) { boolean relAndTimelyRequired = false; if (imfMessage != null) { // check to see if this message requires the timely and reliable messaging // logic as defined by the implementation guide Map<String, TxDetail> details = imfMessage.getDetails(); if (!details.isEmpty()) { // look for the Disposition options detail TxDetail dispositionOptionDetail = details.get(TxDetailType.DISPOSITION_OPTIONS.getType()); if (dispositionOptionDetail != null) // check for the X-DIRECT-FINAL-DESTINATION-DELIVERY option if (dispositionOptionDetail .getDetailValue() .toLowerCase(Locale.getDefault()) .contains( MDNStandard.DispositionOption_TimelyAndReliable.toLowerCase(Locale.getDefault()))) relAndTimelyRequired = true; } } return relAndTimelyRequired; }
/** * Tracks message that meet the following qualifications <br> * 1. Outgoing IMF message * * @param tx The message to monitor and track * @param isOutgoing Indicates the message direction: incoming or outgoing */ @SuppressWarnings("incomplete-switch") protected void trackMessage(Tx tx, boolean isOutgoing) { // only track the following message.. // 1. Outgoing IMF message boolean track = false; if (tx != null) { switch (tx.getMsgType()) { case IMF: { track = isOutgoing; break; } } } if (track) { try { txService.trackMessage(tx); } catch (ServiceException ex) { LOGGER.warn("Failed to submit message to monitoring service.", ex); } } }