/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.gl.batch.service.impl; import java.io.File; import java.io.InputStream; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.gl.batch.EnterpriseFeedStep; import org.kuali.kfs.gl.batch.service.EnterpriseFeederNotificationService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSKeyConstants; import org.kuali.kfs.sys.Message; import org.kuali.kfs.sys.service.impl.KfsParameterConstants; import org.kuali.rice.core.api.config.property.ConfigurationService; import org.kuali.rice.core.api.mail.MailMessage; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.krad.service.MailService; /** * The base implementation of EnterpriseFeederNotificationService; performs email-based notifications */ public class EnterpriseFeederNotificationServiceImpl implements EnterpriseFeederNotificationService { private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EnterpriseFeederNotificationServiceImpl.class); private ParameterService parameterService; private ConfigurationService configurationService; private MailService mailService; /** * Performs notification about the status of the upload (i.e. feeding) of a single file set (i.e. done file, data file, and * recon file). * * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the * feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its * value. * @param event The event/status of the upload of the file set * @param doneFile The done file * @param dataFile The data file * @param reconFile The recon file * @param errorMessages Any error messages for which to provide notification * @see org.kuali.kfs.gl.batch.service.EnterpriseFeederNotificationService#notifyFileFeedStatus(java.lang.String, * org.kuali.module.gl.util.EnterpriseFeederEvent, java.io.File, java.io.File, java.io.File, java.util.List) */ @Override public void notifyFileFeedStatus(String feederProcessName, EnterpriseFeederStatus status, File doneFile, File dataFile, File reconFile, List<Message> errorMessages) { String doneFileDescription = doneFile == null ? "Done file missing" : doneFile.getAbsolutePath(); String dataFileDescription = dataFile == null ? "Data file missing" : dataFile.getAbsolutePath(); String reconFileDescription = reconFile == null ? "Recon file missing" : reconFile.getAbsolutePath(); // this implementation does not use the contents of the file, so we don't bother opening up the files notifyFileFeedStatus(feederProcessName, status, doneFileDescription, null, dataFileDescription, null, reconFileDescription, null, errorMessages); } /** * Performs notifications * * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the * feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its * value. * @param status The event/status of the upload of the file set * @param doneFileDescription The file name * @param doneFileContents Not used; can be set to null * @param dataFileDescription The file name * @param dataFileContents Not used; can be set to null * @param reconFileDescription The file name * @param reconFileContents Not used; can be set to null * @param errorMessages Any error messages for which to provide notification * @see org.kuali.kfs.gl.batch.service.EnterpriseFeederNotificationService#notifyFileFeedStatus(java.lang.String, * org.kuali.module.gl.util.EnterpriseFeederEvent, java.lang.String, java.io.InputStream, java.lang.String, * java.io.InputStream, java.lang.String, java.io.InputStream, java.util.List) */ @Override public void notifyFileFeedStatus(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, InputStream doneFileContents, String dataFileDescription, InputStream dataFileContents, String reconFileDescription, InputStream reconFileContents, List<Message> errorMessages) { try { if (isStatusNotifiable(feederProcessName, status, doneFileDescription, dataFileDescription, reconFileDescription, errorMessages)) { Set<String> toEmailAddresses = generateToEmailAddresses(feederProcessName, status, doneFileDescription, dataFileDescription, reconFileDescription, errorMessages); MailMessage mailMessage = new MailMessage(); String returnAddress = parameterService.getParameterValueAsString(KfsParameterConstants.GENERAL_LEDGER_BATCH.class, KFSConstants.FROM_EMAIL_ADDRESS_PARM_NM); if(StringUtils.isEmpty(returnAddress)) { returnAddress = mailService.getBatchMailingList(); } mailMessage.setFromAddress(returnAddress); mailMessage.setToAddresses(toEmailAddresses); mailMessage.setSubject(getSubjectLine(doneFileDescription, dataFileDescription, reconFileDescription, errorMessages, feederProcessName, status)); mailMessage.setMessage(buildFileFeedStatusMessage(doneFileDescription, dataFileDescription, reconFileDescription, errorMessages, feederProcessName, status)); mailService.sendMessage(mailMessage); } } catch (Exception e) { // Have to try to prevent notification exceptions from breaking control flow in the caller // log and swallow the exception LOG.error("Error occured trying to send notifications.", e); } } /** * Generates the destination address(s) for the email notifications, possibly depending on the parameter values * * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the * feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its * value. * @param status The event/status of the upload of the file set * @param doneFileDescription The file name * @param dataFileDescription The file name * @param reconFileDescription The file name * @param errorMessages Any error messages for which to provide notification * @return the destination addresses */ protected Set<String> generateToEmailAddresses(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, String dataFileDescription, String reconFileDescription, List<Message> errorMessages) { Set<String> addresses = new HashSet<String>(); Collection<String> addressesArray = parameterService.getParameterValuesAsString(EnterpriseFeedStep.class, KFSConstants.EnterpriseFeederApplicationParameterKeys.TO_ADDRESS); for (String address : addressesArray) { addresses.add(address); } return addresses; } /** * Generates the "From:" address for the email * * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the * feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its * value. * @param status The event/status of the upload of the file set * @param doneFileDescription The file name * @param dataFileDescription The file name * @param reconFileDescription The file name * @param errorMessages Any error messages for which to provide notification * @return the source address */ protected String generateFromEmailAddress(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, String dataFileDescription, String reconFileDescription, List<Message> errorMessages) { return mailService.getBatchMailingList(); } /** * Generates the status message that would be generated by a call to notifyFileFeedStatus with the same parameters. * * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the * feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its * value. * @param event The event/status of the upload of the file set * @param doneFile The done file * @param dataFile The data file * @param reconFile The recon file * @param errorMessages Any error messages for which to provide notification * @see org.kuali.kfs.gl.batch.service.EnterpriseFeederNotificationService#getFileFeedStatusMessage(java.lang.String, * org.kuali.module.gl.util.EnterpriseFeederEvent, java.io.File, java.io.File, java.io.File, java.util.List) */ @Override public String getFileFeedStatusMessage(String feederProcessName, EnterpriseFeederStatus status, File doneFile, File dataFile, File reconFile, List<Message> errorMessages) { String doneFileDescription = doneFile.getAbsolutePath(); String dataFileDescription = dataFile.getAbsolutePath(); String reconFileDescription = reconFile.getAbsolutePath(); return buildFileFeedStatusMessage(doneFileDescription, dataFileDescription, reconFileDescription, errorMessages, feederProcessName, status); } /** * @see org.kuali.kfs.gl.batch.service.EnterpriseFeederNotificationService#getFileFeedStatusMessage(java.lang.String, * org.kuali.module.gl.util.EnterpriseFeederEvent, java.lang.String, java.io.InputStream, java.lang.String, * java.io.InputStream, java.lang.String, java.io.InputStream, java.util.List) */ @Override public String getFileFeedStatusMessage(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, InputStream doneFileContents, String dataFileDescription, InputStream dataFileContents, String reconFileDescription, InputStream reconFileContents, List<Message> errorMessages) { return buildFileFeedStatusMessage(doneFileDescription, dataFileDescription, reconFileDescription, errorMessages, feederProcessName, status); } /** * Builds the status message for the status of a feed. * * @param doneFileDescription the name of the done file * @param dataFileDescription the name of the file to read data from * @param reconFileDescription the name of the reconciliation file * @param errorMessages a List of error messages * @param feederProcessName the name of the feeder process * @return the String of the subject line */ protected String getSubjectLine(String doneFileDescription, String dataFileDescription, String reconFileDescription, List<Message> errorMessages, String feederProcessName, EnterpriseFeederStatus status) { String subject = configurationService.getPropertyValueAsString(KFSKeyConstants.ERROR_ENTERPRISE_FEEDER_RECONCILIATION_OR_LOADING_ERROR); if (subject == null) { return "ERROR in reconciling or loading GL origin entries from file."; } return subject; } /** * Builds the status message for the status of a feed. * * @param doneFileName the name of the done file * @param dataFileName the name of the file to get data from * @param reconFileName the reconciliation file * @param errorMessages a List of error messages generated during the process * @param feederProcessName the name of the feeder process * @return a String with the status message */ protected String buildFileFeedStatusMessage(String doneFileName, String dataFileName, String reconFileName, List<Message> errorMessages, String feederProcessName, EnterpriseFeederStatus status) { StringBuilder buf = new StringBuilder(); buf.append("Data file: ").append(dataFileName).append("\n"); buf.append("Reconciliation File: ").append(reconFileName).append("\n"); buf.append("Done file: ").append(doneFileName).append("\n\n\n"); buf.append("Status: ").append(status.getStatusDescription()).append("\n\n\n"); if (status.isErrorEvent()) { buf.append("The done file has been removed and "); if (StringUtils.isNotBlank(feederProcessName)) { buf.append(feederProcessName); } else { buf.append("<process name unavailable>"); } buf.append(" will continue without processing this set of files (see below)."); buf.append(" Please correct and resend the files for the next day's batch."); } buf.append("\n\n"); if (!errorMessages.isEmpty()) { buf.append("Error/warning messages:\n"); for (Message message : errorMessages) { if (message.getType() == Message.TYPE_FATAL) { buf.append("ERROR: "); } if (message.getType() == Message.TYPE_WARNING) { buf.append("WARNING: "); } buf.append(message.getMessage()).append("\n"); } } return buf.toString(); } /** * Returns whether a notification is necessary given the values of the parameters * * @param feederProcessName the name of the process that invoked the feeder * @param status the status of the feed * @param doneFileDescription the done file description * @param dataFileDescription the data file description * @param reconFileDescription the recon file description * @param errorMessages a list of error messages * @return whether to notify */ protected boolean isStatusNotifiable(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, String dataFileDescription, String reconFileDescription, List<Message> errorMessages) { if (status instanceof FileReconOkLoadOkStatus) { return false; } return true; } /** * Sets the mailService attribute value. * * @param mailService The mailService to set. */ public void setMailService(MailService mailService) { this.mailService = mailService; } public void setConfigurationService(ConfigurationService configurationService) { this.configurationService = configurationService; } public void setParameterService(ParameterService parameterService) { this.parameterService = parameterService; } }