/** Shutsdown the gateway and cleans up resources associated with it. */ public void shutdown() { GatewayState.getInstance().lockForUpdating(); try { // place holder for shutdown code } finally { GatewayState.getInstance().unlockFromUpdating(); } }
/** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public void service(Mail mail) throws MessagingException { GatewayState.getInstance().lockForProcessing(); try { Tx txToMonitor = null; LOGGER.trace("Entering service(Mail mail)"); onPreprocessMessage(mail); final MimeMessage msg = mail.getMessage(); final NHINDAddressCollection recipients = getMailRecipients(mail); // get the sender final NHINDAddress sender = getMailSender(mail); LOGGER.info("Proccessing incoming message from sender " + sender.toString()); MessageProcessResult result = null; final boolean isOutgoing = this.isOutgoing(msg, sender); // if the message is outgoing, then the tracking information must be // gathered now before the message is transformed if (isOutgoing) txToMonitor = getTxToTrack(msg, sender, recipients); // recipients can get modified by the security and trust agent, so make a local copy // before processing final NHINDAddressCollection originalRecipList = NHINDAddressCollection.create(recipients); try { // process the message with the agent stack LOGGER.trace("Calling agent.processMessage"); result = agent.processMessage(msg, recipients, sender); LOGGER.trace("Finished calling agent.processMessage"); if (result == null) { LOGGER.error("Failed to process message. processMessage returned null."); onMessageRejected(mail, originalRecipList, sender, isOutgoing, txToMonitor, null); mail.setState(Mail.GHOST); LOGGER.trace("Exiting service(Mail mail)"); return; } } catch (Exception e) { // catch all LOGGER.error("Failed to process message: " + e.getMessage(), e); onMessageRejected(mail, originalRecipList, sender, isOutgoing, txToMonitor, e); mail.setState(Mail.GHOST); LOGGER.trace("Exiting service(Mail mail)"); return; } if (result.getProcessedMessage() != null) { mail.setMessage(result.getProcessedMessage().getMessage()); } else { /* * TODO: Handle exception... GHOST the message for now and eat it */ LOGGER.debug("Processed message is null. GHOST and eat the message."); onMessageRejected(mail, recipients, sender, null); mail.setState(Mail.GHOST); return; } // remove reject recipients from the RCTP headers if (result.getProcessedMessage().getRejectedRecipients() != null && result.getProcessedMessage().getRejectedRecipients().size() > 0 && mail.getRecipients() != null && mail.getRecipients().size() > 0) { final Collection<MailAddress> newRCPTList = new ArrayList<MailAddress>(); for (MailAddress rctpAdd : (Collection<MailAddress>) mail.getRecipients()) { if (!isRcptRejected(rctpAdd, result.getProcessedMessage().getRejectedRecipients())) { newRCPTList.add(rctpAdd); } } mail.setRecipients(newRCPTList); } /* * Handle sending MDN messages */ final Collection<NotificationMessage> notifications = result.getNotificationMessages(); if (notifications != null && notifications.size() > 0) { LOGGER.info("MDN messages requested. Sending MDN \"processed\" messages"); // create a message for each notification and put it on James "stack" for (NotificationMessage message : notifications) { try { this.getMailetContext().sendMail(message); } catch (Throwable t) { // don't kill the process if this fails LOGGER.error("Error sending MDN message.", t); } } } // track message trackMessage(txToMonitor, isOutgoing); onPostprocessMessage(mail, result, isOutgoing, txToMonitor); LOGGER.trace("Exiting service(Mail mail)"); } finally { GatewayState.getInstance().unlockFromProcessing(); } }
/** {@inheritDoc} */ @Override public void init() throws MessagingException { LOGGER.info("Initializing NHINDSecurityAndTrustMailet"); super.init(); // set the outbound policy for notifications if possible try { final boolean useOutboundPolicy = Boolean.parseBoolean( GatewayConfiguration.getConfigurationParam( SecurityAndTrustMailetOptions.USE_OUTGOING_POLICY_FOR_INCOMING_NOTIFICATIONS, this, "false")); // we don't know if this parameter came from the mailet config or the options manager, so just // go ahead and set it at // the options manager level because that it where the agent reads the value... no danger that // we will overwrite the value that we want... // we would just be writing the same value if the information came from the options manager // module // the mailet parameter gets precedence, so we want to overwrite the options manager if the // value exists in the mailet configuration OptionsManager.getInstance() .setOptionsParameter( new OptionsParameter( OptionsParameter.USE_OUTGOING_POLICY_FOR_INCOMING_NOTIFICATIONS, Boolean.toString(useOutboundPolicy))); } catch (Exception e) { // log a warning that the parameter could not be set } // set the rejection policy for tampered routing headers try { final boolean rejectOnTamperPolicy = Boolean.parseBoolean( GatewayConfiguration.getConfigurationParam( SecurityAndTrustMailetOptions.REJECT_ON_ROUTING_TAMPER, this, "false")); OptionsManager.getInstance() .setOptionsParameter( new OptionsParameter( OptionsParameter.REJECT_ON_ROUTING_TAMPER, Boolean.toString(rejectOnTamperPolicy))); } catch (Exception e) { // log a warning that the parameter could not be set } // set the JCE providers if available final String JCEName = GatewayConfiguration.getConfigurationParam( SecurityAndTrustMailetOptions.JCE_PROVIDER_NAME, this, ""); if (!StringUtils.isEmpty(JCEName)) OptionsManager.getInstance() .setOptionsParameter(new OptionsParameter(OptionsParameter.JCE_PROVIDER, JCEName)); final String sensitiveJCEName = GatewayConfiguration.getConfigurationParam( SecurityAndTrustMailetOptions.JCE_SENTITIVE_PROVIDER, this, ""); if (!StringUtils.isEmpty(sensitiveJCEName)) OptionsManager.getInstance() .setOptionsParameter( new OptionsParameter(OptionsParameter.JCE_SENTITIVE_PROVIDER, sensitiveJCEName)); // Get the configuration URL final String configURLParam = getInitParameter(SecurityAndTrustMailetOptions.CONFIG_URL_PARAM); if (StringUtils.isEmpty(configURLParam)) { LOGGER.error("NHINDSecurityAndTrustMailet Configuration URL cannot be empty or null."); throw new MessagingException( "NHINDSecurityAndTrustMailet Configuration URL cannot be empty or null."); } // parse into a URL and validate it is properly formed URL configURL = null; try { configURL = new URL(configURLParam); } catch (MalformedURLException ex) { LOGGER.error("Invalid configuration URL:" + ex.getMessage(), ex); throw new MessagingException( "NHINDSecurityAndTrustMailet Configuration URL cannot be empty or null.", ex); } final Collection<Module> modules = getInitModules(); Provider<SmtpAgentConfig> configProvider; try { configProvider = this.getConfigProvider(); if (configProvider == null) configProvider = createCompatConfigProvider(configURL); if (configProvider instanceof URLAccessedConfigProvider) ((URLAccessedConfigProvider) configProvider).setConfigURL(configURL); final Provider<ServiceSecurityManager> srvSecMgr = getServiceSecurityManagerProvider(); if (configProvider instanceof SecureURLAccessedConfigProvider) ((SecureURLAccessedConfigProvider) configProvider).setServiceSecurityManager(srvSecMgr); final Provider<KeyStoreProtectionManager> keyStoreManagerProvider = getKeyStoreManagerProvider(); if (configProvider instanceof KeyStoreProtectionConfigProvider && keyStoreManagerProvider != null) ((KeyStoreProtectionConfigProvider) configProvider) .setKeyStoreProtectionManger(keyStoreManagerProvider); agent = SmtpAgentFactory.createAgent(configURL, configProvider, null, modules); } catch (SmtpAgentException e) { LOGGER.error("Failed to create the SMTP agent: " + e.getMessage(), e); throw new MessagingException("Failed to create the SMTP agent: " + e.getMessage(), e); } // this should never happen because an exception should be thrown by Guice or one of the // providers, but check // just in case... /// CLOVER:OFF if (agent == null) { LOGGER.error("Failed to create the SMTP agent. Reason unknown."); throw new MessagingException("Failed to create the SMTP agent. Reason unknown."); } /// CLOVER:ON // get the DSN creation options // default is RELIABLE_DSN_OPTION final String dnsCreateOptions = GatewayConfiguration.getConfigurationParam( SecurityAndTrustMailetOptions.AUTO_DSN_FAILURE_CREATION_PARAM, this, RELIABLE_DSN_OPTION); for (String dsnOption : dnsCreateOptions.split(",")) { if (dsnOption.equalsIgnoreCase(RELIABLE_DSN_OPTION)) autoDSNForTimelyAndReliable = true; else if (dsnOption.equalsIgnoreCase(GENERAL_DSN_OPTION)) autoDSNForGeneral = true; } // set the agent and config in the Gateway state final GatewayState gwState = GatewayState.getInstance(); if (gwState.isAgentSettingManagerRunning()) gwState.stopAgentSettingsManager(); gwState.setSmtpAgent(agent); gwState.setSmptAgentConfig( SmptAgentConfigFactory.createSmtpAgentConfig(configURL, configProvider, null)); gwState.startAgentSettingsManager(); LOGGER.info("NHINDSecurityAndTrustMailet initialization complete."); }