View Javadoc
1   /*
2    * Copyright 2007 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.gl.batch.service.impl;
17  
18  import java.io.File;
19  import java.io.InputStream;
20  import java.util.Collection;
21  import java.util.HashSet;
22  import java.util.List;
23  import java.util.Set;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.kuali.ole.gl.batch.EnterpriseFeedStep;
27  import org.kuali.ole.gl.batch.service.EnterpriseFeederNotificationService;
28  import org.kuali.ole.sys.OLEConstants;
29  import org.kuali.ole.sys.OLEKeyConstants;
30  import org.kuali.ole.sys.Message;
31  import org.kuali.ole.sys.service.impl.OleParameterConstants;
32  import org.kuali.rice.core.api.config.property.ConfigurationService;
33  import org.kuali.rice.core.api.mail.MailMessage;
34  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
35  import org.kuali.rice.krad.service.MailService;
36  
37  /**
38   * The base implementation of EnterpriseFeederNotificationService; performs email-based notifications
39   */
40  public class EnterpriseFeederNotificationServiceImpl implements EnterpriseFeederNotificationService {
41      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EnterpriseFeederNotificationServiceImpl.class);
42  
43      private ParameterService parameterService;
44      private ConfigurationService configurationService;
45      private MailService mailService;
46  
47      /**
48       * Performs notification about the status of the upload (i.e. feeding) of a single file set (i.e. done file, data file, and
49       * recon file).
50       * 
51       * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the
52       *        feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its
53       *        value.
54       * @param event The event/status of the upload of the file set
55       * @param doneFile The done file
56       * @param dataFile The data file
57       * @param reconFile The recon file
58       * @param errorMessages Any error messages for which to provide notification
59       * @see org.kuali.ole.gl.batch.service.EnterpriseFeederNotificationService#notifyFileFeedStatus(java.lang.String,
60       *      org.kuali.module.gl.util.EnterpriseFeederEvent, java.io.File, java.io.File, java.io.File, java.util.List)
61       */
62      @Override
63      public void notifyFileFeedStatus(String feederProcessName, EnterpriseFeederStatus status, File doneFile, File dataFile, File reconFile, List<Message> errorMessages) {
64          String doneFileDescription = doneFile == null ? "Done file missing" : doneFile.getAbsolutePath();
65          String dataFileDescription = dataFile == null ? "Data file missing" : dataFile.getAbsolutePath();
66          String reconFileDescription = reconFile == null ? "Recon file missing" : reconFile.getAbsolutePath();
67  
68          // this implementation does not use the contents of the file, so we don't bother opening up the files
69          notifyFileFeedStatus(feederProcessName, status, doneFileDescription, null, dataFileDescription, null, reconFileDescription, null, errorMessages);
70      }
71  
72      /**
73       * Performs notifications
74       * 
75       * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the
76       *        feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its
77       *        value.
78       * @param status The event/status of the upload of the file set
79       * @param doneFileDescription The file name
80       * @param doneFileContents Not used; can be set to null
81       * @param dataFileDescription The file name
82       * @param dataFileContents Not used; can be set to null
83       * @param reconFileDescription The file name
84       * @param reconFileContents Not used; can be set to null
85       * @param errorMessages Any error messages for which to provide notification
86       * @see org.kuali.ole.gl.batch.service.EnterpriseFeederNotificationService#notifyFileFeedStatus(java.lang.String,
87       *      org.kuali.module.gl.util.EnterpriseFeederEvent, java.lang.String, java.io.InputStream, java.lang.String,
88       *      java.io.InputStream, java.lang.String, java.io.InputStream, java.util.List)
89       */
90      @Override
91      public void notifyFileFeedStatus(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, InputStream doneFileContents, String dataFileDescription, InputStream dataFileContents, String reconFileDescription, InputStream reconFileContents, List<Message> errorMessages) {
92          try {
93              if (isStatusNotifiable(feederProcessName, status, doneFileDescription, dataFileDescription, reconFileDescription, errorMessages)) {
94                  Set<String> toEmailAddresses = generateToEmailAddresses(feederProcessName, status, doneFileDescription, dataFileDescription, reconFileDescription, errorMessages);
95  
96                  MailMessage mailMessage = new MailMessage();
97                  String returnAddress = parameterService.getParameterValueAsString(OleParameterConstants.GENERAL_LEDGER_BATCH.class, OLEConstants.FROM_EMAIL_ADDRESS_PARM_NM);
98                  if(StringUtils.isEmpty(returnAddress)) {
99                      returnAddress = mailService.getBatchMailingList();
100                 }
101                 mailMessage.setFromAddress(returnAddress);
102                 mailMessage.setToAddresses(toEmailAddresses);
103                 mailMessage.setSubject(getSubjectLine(doneFileDescription, dataFileDescription, reconFileDescription, errorMessages, feederProcessName, status));
104                 mailMessage.setMessage(buildFileFeedStatusMessage(doneFileDescription, dataFileDescription, reconFileDescription, errorMessages, feederProcessName, status));
105 
106                 mailService.sendMessage(mailMessage);
107             }
108         }
109         catch (Exception e) {
110             // Have to try to prevent notification exceptions from breaking control flow in the caller
111             // log and swallow the exception
112             LOG.error("Error occured trying to send notifications.", e);
113         }
114     }
115 
116     /**
117      * Generates the destination address(s) for the email notifications, possibly depending on the parameter values
118      * 
119      * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the
120      *        feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its
121      *        value.
122      * @param status The event/status of the upload of the file set
123      * @param doneFileDescription The file name
124      * @param dataFileDescription The file name
125      * @param reconFileDescription The file name
126      * @param errorMessages Any error messages for which to provide notification
127      * @return the destination addresses
128      */
129     protected Set<String> generateToEmailAddresses(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, String dataFileDescription, String reconFileDescription, List<Message> errorMessages) {
130         Set<String> addresses = new HashSet<String>();
131         Collection<String> addressesArray = parameterService.getParameterValuesAsString(EnterpriseFeedStep.class, OLEConstants.EnterpriseFeederApplicationParameterKeys.TO_ADDRESS);
132         for (String address : addressesArray) {
133             addresses.add(address);
134         }
135         return addresses;
136     }
137 
138     /**
139      * Generates the "From:" address for the email
140      * 
141      * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the
142      *        feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its
143      *        value.
144      * @param status The event/status of the upload of the file set
145      * @param doneFileDescription The file name
146      * @param dataFileDescription The file name
147      * @param reconFileDescription The file name
148      * @param errorMessages Any error messages for which to provide notification
149      * @return the source address
150      */
151     protected String generateFromEmailAddress(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, String dataFileDescription, String reconFileDescription, List<Message> errorMessages) {
152         return mailService.getBatchMailingList();
153     }
154 
155     /**
156      * Generates the status message that would be generated by a call to notifyFileFeedStatus with the same parameters.
157      * 
158      * @param feederProcessName The name of the feeder process; this may correspond to the name of the Spring definition of the
159      *        feeder step, but each implementation may define how to use the value of this parameter and/or restrictions on its
160      *        value.
161      * @param event The event/status of the upload of the file set
162      * @param doneFile The done file
163      * @param dataFile The data file
164      * @param reconFile The recon file
165      * @param errorMessages Any error messages for which to provide notification
166      * @see org.kuali.ole.gl.batch.service.EnterpriseFeederNotificationService#getFileFeedStatusMessage(java.lang.String,
167      *      org.kuali.module.gl.util.EnterpriseFeederEvent, java.io.File, java.io.File, java.io.File, java.util.List)
168      */
169     @Override
170     public String getFileFeedStatusMessage(String feederProcessName, EnterpriseFeederStatus status, File doneFile, File dataFile, File reconFile, List<Message> errorMessages) {
171         String doneFileDescription = doneFile.getAbsolutePath();
172         String dataFileDescription = dataFile.getAbsolutePath();
173         String reconFileDescription = reconFile.getAbsolutePath();
174 
175         return buildFileFeedStatusMessage(doneFileDescription, dataFileDescription, reconFileDescription, errorMessages, feederProcessName, status);
176     }
177 
178     /**
179      * @see org.kuali.ole.gl.batch.service.EnterpriseFeederNotificationService#getFileFeedStatusMessage(java.lang.String,
180      *      org.kuali.module.gl.util.EnterpriseFeederEvent, java.lang.String, java.io.InputStream, java.lang.String,
181      *      java.io.InputStream, java.lang.String, java.io.InputStream, java.util.List)
182      */
183     @Override
184     public String getFileFeedStatusMessage(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, InputStream doneFileContents, String dataFileDescription, InputStream dataFileContents, String reconFileDescription, InputStream reconFileContents, List<Message> errorMessages) {
185         return buildFileFeedStatusMessage(doneFileDescription, dataFileDescription, reconFileDescription, errorMessages, feederProcessName, status);
186     }
187 
188     /**
189      * Builds the status message for the status of a feed.
190      * 
191      * @param doneFileDescription the name of the done file
192      * @param dataFileDescription the name of the file to read data from
193      * @param reconFileDescription the name of the reconciliation file
194      * @param errorMessages a List of error messages
195      * @param feederProcessName the name of the feeder process
196      * @return the String of the subject line
197      */
198     protected String getSubjectLine(String doneFileDescription, String dataFileDescription, String reconFileDescription, List<Message> errorMessages, String feederProcessName, EnterpriseFeederStatus status) {
199         String subject = configurationService.getPropertyValueAsString(OLEKeyConstants.ERROR_ENTERPRISE_FEEDER_RECONCILIATION_OR_LOADING_ERROR);
200         if (subject == null) {
201             return "ERROR in reconciling or loading GL origin entries from file.";
202         }
203         String productionEnvironmentCode = configurationService.getPropertyValueAsString(OLEConstants.PROD_ENVIRONMENT_CODE_KEY);
204         String environmentCode = configurationService.getPropertyValueAsString(OLEConstants.ENVIRONMENT_KEY);
205         if (!StringUtils.equals(productionEnvironmentCode, environmentCode)) {
206             subject = environmentCode + ": " + subject;
207         }
208         return subject;
209     }
210 
211     /**
212      * Builds the status message for the status of a feed.
213      * 
214      * @param doneFileName the name of the done file
215      * @param dataFileName the name of the file to get data from
216      * @param reconFileName the reconciliation file
217      * @param errorMessages a List of error messages generated during the process
218      * @param feederProcessName the name of the feeder process
219      * @return a String with the status message
220      */
221     protected String buildFileFeedStatusMessage(String doneFileName, String dataFileName, String reconFileName, List<Message> errorMessages, String feederProcessName, EnterpriseFeederStatus status) {
222         StringBuilder buf = new StringBuilder();
223 
224         buf.append("Data file: ").append(dataFileName).append("\n");
225         buf.append("Reconciliation File: ").append(reconFileName).append("\n");
226         buf.append("Done file: ").append(doneFileName).append("\n\n\n");
227 
228         buf.append("Status: ").append(status.getStatusDescription()).append("\n\n\n");
229 
230         if (status.isErrorEvent()) {
231             buf.append("The done file has been removed and ");
232             if (StringUtils.isNotBlank(feederProcessName)) {
233                 buf.append(feederProcessName);
234             }
235             else {
236                 buf.append("<process name unavailable>");
237             }
238             buf.append(" will continue without processing this set of files (see below).");
239 
240             buf.append("  Please correct and resend the files for the next day's batch.");
241         }
242 
243         buf.append("\n\n");
244 
245         if (!errorMessages.isEmpty()) {
246             buf.append("Error/warning messages:\n");
247             for (Message message : errorMessages) {
248                 if (message.getType() == Message.TYPE_FATAL) {
249                     buf.append("ERROR: ");
250                 }
251                 if (message.getType() == Message.TYPE_WARNING) {
252                     buf.append("WARNING: ");
253                 }
254                 buf.append(message.getMessage()).append("\n");
255             }
256         }
257 
258         return buf.toString();
259     }
260 
261     /**
262      * Returns whether a notification is necessary given the values of the parameters
263      * 
264      * @param feederProcessName the name of the process that invoked the feeder
265      * @param status the status of the feed
266      * @param doneFileDescription the done file description
267      * @param dataFileDescription the data file description
268      * @param reconFileDescription the recon file description
269      * @param errorMessages a list of error messages
270      * @return whether to notify
271      */
272     protected boolean isStatusNotifiable(String feederProcessName, EnterpriseFeederStatus status, String doneFileDescription, String dataFileDescription, String reconFileDescription, List<Message> errorMessages) {
273         if (status instanceof FileReconOkLoadOkStatus) {
274             return false;
275         }
276         return true;
277     }
278 
279 
280     /**
281      * Sets the mailService attribute value.
282      * 
283      * @param mailService The mailService to set.
284      */
285     public void setMailService(MailService mailService) {
286         this.mailService = mailService;
287     }
288 
289     public void setConfigurationService(ConfigurationService configurationService) {
290         this.configurationService = configurationService;
291     }
292 
293     public void setParameterService(ParameterService parameterService) {
294         this.parameterService = parameterService;
295     }
296 }