/*
jBilling - The Enterprise Open Source Billing System
Copyright (C) 2003-2011 Enterprise jBilling Software Ltd. and Emiliano Conde
This file is part of jbilling.
jbilling 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.
jbilling 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 jbilling. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Created on Jul 14, 2004
*
*/
package com.sapienter.jbilling.client.process;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import com.sapienter.jbilling.common.SessionInternalError;
import com.sapienter.jbilling.common.Util;
import com.sapienter.jbilling.server.invoice.IInvoiceSessionBean;
import com.sapienter.jbilling.server.order.IOrderSessionBean;
import com.sapienter.jbilling.server.process.IBillingProcessSessionBean;
import com.sapienter.jbilling.server.provisioning.IProvisioningProcessSessionBean;
import com.sapienter.jbilling.server.user.IUserSessionBean;
import com.sapienter.jbilling.server.util.Context;
/**
* @author Emil
*
*/
public class Trigger implements Job {
private static final Logger LOG = Logger.getLogger(Trigger.class);
/**
* Initialize tool Trigger. Load properties from jbilling.properties and set up Quartz job/trigger
*
* process.time=YYYYMMDD-HHmm (a full date followed by HH is the hours in 24hs format and mm the minutes).
* process.frequency=X (where X is an integer >= 0 and < 1440
*
* The fist property indicates at what time of the day the trigger has to happen for the very first time. After this first
* run you will need X minutes (specified by 'process.frequency') to run the trigger again. Since only the billing process
* can run more than once per day, we need some logic in the ejbTimout method to verify if the call is the first one of the
* day (where it runs all the services) or not (where it runs only the billing process).
*
* The first property is optional. If it is not present, or its value is null, then the next trigger will happen at
* startup + minutes indicated in 'process.frequency'.
*
*/
public static void Initialize() {
// Load properties from jbilling.properties
String time = null;
String frequency = null;
try {
time = Util.getSysProp("process.time");
frequency = Util.getSysProp("process.frequency");
} catch (Exception e) {
// just eat it
}
// both null or empty, log one message and return
if ((time == null || time.length() == 0) && (frequency == null || frequency.length() == 0)) {
LOG.info("No schedule information found.");
return;
}
Date startTime = null;
int interval = 0;
// if process.time absents and frequency is zero, fire every 0:00AM
GregorianCalendar cal = new GregorianCalendar();
if ((time == null || time.length() == 0) && "0".equals(frequency)) {
cal.add(Calendar.DATE, 1);
startTime = Util.truncateDate(cal.getTime());
interval = 24 * 60;
} else if (time == null || time.length() == 0) { // process.time is not present, start at startup + frequency
try {
interval = Integer.parseInt(frequency);
} catch (NumberFormatException e) {
LOG.debug(e);
LOG.info("Error:" + e.getMessage() + " Schedule does not start.");
// Leave
return;
}
cal.add(Calendar.MINUTE, interval);
startTime = Util.truncateDate(cal.getTime());
} else { // Its normal one
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd-HHmm");
try {
interval = Integer.parseInt(frequency);
if (interval == 0) {
LOG.info("The frequency can not be zero when time is specified.");
return;
}
startTime = df.parse(time);
} catch (ParseException e) {
LOG.debug(e);
LOG.info("Error:" + e.getMessage() + " Schedule does not start.");
// Leave
return;
} catch (NumberFormatException e) {
LOG.debug(e);
LOG.info("Error:" + e.getMessage() + " Schedule does not start.");
//Leave
return;
}
}
// set up trigger
try {
JobDetail jbillingJob = new JobDetail("jbilling", Scheduler.DEFAULT_GROUP, Trigger.class);
SimpleTrigger trigger = new SimpleTrigger("jbillingTrigger",
Scheduler.DEFAULT_GROUP,
startTime,
null,
SimpleTrigger.REPEAT_INDEFINITELY,
interval * 60 * 1000);
trigger.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT);
JobScheduler.getInstance().getScheduler().scheduleJob(jbillingJob, trigger);
} catch (SchedulerException e) {
LOG.error("An exception occurred scheduling the jBilling batch processes.",e);
}
}
public static void main(String[] args) {
}
public void execute(JobExecutionContext ctx) throws JobExecutionException {
IBillingProcessSessionBean remoteBillingProcess = null;
try {
// get a session for the remote interfaces
IUserSessionBean remoteUser = (IUserSessionBean) Context.getBean(
Context.Name.USER_SESSION);
IOrderSessionBean remoteOrder = (IOrderSessionBean) Context.getBean(
Context.Name.ORDER_SESSION);
IInvoiceSessionBean remoteInvoice = (IInvoiceSessionBean)
Context.getBean(Context.Name.INVOICE_SESSION);
IProvisioningProcessSessionBean remoteProvisioningProcess =
(IProvisioningProcessSessionBean) Context.getBean(
Context.Name.PROVISIONING_PROCESS_SESSION);
// determine the date for this run
Date today = Calendar.getInstance().getTime();
today = Util.truncateDate(today);
// Determine if this call first time of today
boolean firstOfToday = true;
Date lastFire = ctx.getPreviousFireTime();
if (lastFire == null) { // Should be first time call
firstOfToday = true;
} else {
lastFire = Util.truncateDate(lastFire);
firstOfToday = lastFire.before(today);
}
// now the ageing process
if (firstOfToday) {
if (Util.getSysPropBooleanTrue("process.run_partner")) {
// now the partner payout process
LOG.info("Starting partner process at " + Calendar.getInstance().getTime());
remoteUser.processPayouts(today);
LOG.info("Ended partner process at " + Calendar.getInstance().getTime());
}
if (Util.getSysPropBooleanTrue("process.run_order_expire")) {
// finally the orders about to expire notification
LOG.info("Starting order notification at " + Calendar.getInstance().getTime());
remoteOrder.reviewNotifications(today);
LOG.info("Ended order notification at " + Calendar.getInstance().getTime());
}
if (Util.getSysPropBooleanTrue("process.run_invoice_reminder")) {
// the invoice reminders
LOG.info("Starting invoice reminders at " + Calendar.getInstance().getTime());
remoteInvoice.sendReminders(today);
LOG.info("Ended invoice reminders at " + Calendar.getInstance().getTime());
}
if (Util.getSysPropBooleanTrue("process.run_cc_expire")) {
// send credit card expiration emails
LOG.info("Starting credit card expiration at " + Calendar.getInstance().getTime());
remoteUser.notifyCreditCardExpiration(today);
LOG.info("Ended credit card expiration at " + Calendar.getInstance().getTime());
}
// run the provisioning process
if (Util.getSysPropBooleanTrue("process.run_provisioning")) {
LOG.info("Running trigger for " + today);
LOG.info("Starting provisioning process at " +
Calendar.getInstance().getTime());
remoteProvisioningProcess.trigger();
LOG.info("Ended provisioning process at " +
Calendar.getInstance().getTime());
}
}
} catch (SessionInternalError e) {
LOG.debug(e);
}
}
}