/*
* 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.module.cg.batch;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import javax.mail.MessagingException;
import org.apache.log4j.Logger;
import org.kuali.kfs.module.cg.businessobject.CfdaUpdateResults;
import org.kuali.kfs.module.cg.service.CfdaService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSKeyConstants;
import org.kuali.kfs.sys.batch.AbstractStep;
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.exception.InvalidAddressException;
import org.kuali.rice.krad.service.MailService;
/**
* Parses data from a government web page listing the valid CFDA codes. The codes are then compared with what's in the CFDA table in
* Kuali. Codes set to be managed automatically are reconciled with what's on the web page. Codes managed manually are left alone.
* Finally an email containing a summary of what was done by the step execution is sent to the member of the CG_CFDA_BATCH_NOTIFY workgroup.
*/
public class CfdaBatchStep extends AbstractStep {
private static final Logger LOG = org.apache.log4j.Logger.getLogger(CfdaBatchStep.class);
protected CfdaService cfdaService;
protected MailService mailService;
protected ParameterService parameterService;
protected ConfigurationService configurationService;
/**
* See the class description.
*
* @see org.kuali.kfs.sys.batch.Step#execute(String, Date)
*/
@Override
public boolean execute(String jobName, Date jobRunDate) throws InterruptedException {
MailMessage message = new MailMessage();
try {
CfdaUpdateResults results = cfdaService.update();
// TODO this message should come from some config file.
StringBuilder builder = new StringBuilder();
builder.append("The CFDA batch script is complete.\n");
builder.append(" - ");
builder.append(results.getNumberOfRecordsDeactivatedBecauseNoLongerOnWebSite());
builder.append(" records were deactivated because they are no longer on the web site.\n");
builder.append(" - ");
builder.append(results.getNumberOfRecordsInKfsDatabase());
builder.append(" records were in the KFS database.\n");
builder.append(" - ");
builder.append(results.getNumberOfRecordsNewlyAddedFromWebSite());
builder.append(" records were newly added from the web site.\n");
builder.append(" - ");
builder.append(results.getNumberOfRecordsNotUpdatedBecauseManual());
builder.append(" records were not updated because they are manual.\n");
builder.append(" - ");
builder.append(results.getNumberOfRecordsReActivated());
builder.append(" records were re-activated.\n");
builder.append(" - ");
builder.append(results.getNumberOfRecordsRetrievedFromWebSite());
builder.append(" records were retrieved from the web site.\n");
builder.append(" - ");
builder.append(results.getNumberOfRecordsUpdatedBecauseAutomatic());
builder.append(" records were updated because they are automatic.\n");
builder.append(" - ");
builder.append(results.getNumberOfRecrodsNotUpdatedForHistoricalPurposes());
builder.append(" records were not updated for historical reasons.\n");
builder.append(" - Message\n");
builder.append(null != results.getMessage() ? results.getMessage() : "");
LOG.info(message.toString());
Collection<String> listservAddresses = parameterService.getParameterValuesAsString(CfdaBatchStep.class, KFSConstants.RESULT_SUMMARY_TO_EMAIL_ADDRESSES);
if (listservAddresses.isEmpty()) {
LOG.fatal("No addresses for notification to in " + KFSConstants.RESULT_SUMMARY_TO_EMAIL_ADDRESSES + " parameter. Aborting Email.");
return true;
}
for (String listserv : listservAddresses) {
if (LOG.isInfoEnabled()) {
LOG.info("Mailing to: "+listserv);
}
message.addToAddress(listserv);
}
message.setFromAddress(listservAddresses.iterator().next() );
message.setSubject(getConfigurationService().getPropertyValueAsString(KFSKeyConstants.CFDA_UPDATE_EMAIL_SUBJECT_LINE));
message.setMessage(builder.toString());
mailService.sendMessage(message);
}
catch (IOException ioe) {
LOG.warn("Exception while updating CFDA codes.", ioe);
return false;
}
catch (MessagingException | InvalidAddressException ex) {
LOG.warn("The email address for "+CfdaBatchStep.class+":"+KFSConstants.RESULT_SUMMARY_TO_EMAIL_ADDRESSES+" is invalid.", ex);
return true;
}
return true;
}
/**
* Sets the {@link CfdaService}. For use by Spring.
*
* @param cfdaService The service to be assigned.
*/
public void setCfdaService(CfdaService cfdaService) {
this.cfdaService = cfdaService;
}
/**
* Set the {@link MailService}. For use by Spring.
*
* @param mailService The service to be assigned.
*/
public void setMailService(MailService mailService) {
this.mailService = mailService;
}
/**
* Sets the {@link ParameterService}. For use by Spring.
*
* @param parameterService The service to be assigned.
*/
@Override
public void setParameterService(ParameterService parameterService) {
this.parameterService = parameterService;
}
/**
* Gets the configurationService attribute.
* @return Returns the configurationService.
*/
public ConfigurationService getConfigurationService() {
return configurationService;
}
/**
* Sets the configurationService attribute value.
* @param configurationService The configurationService to set.
*/
public void setConfigurationService(ConfigurationService configurationService) {
this.configurationService = configurationService;
}
}