Agendamento com o Quartz, backup do banco de dados e envio do banco/email

Olá pessoal, boa noite.

Depois de pesquisar um pouco sobre o agendamento de tarefas no Java, li sobre algumas API’s e escolhi o Quartz pela flexibilidade na execução das tarefas e facilidade de implementação no projeto. Entretanto, a maioria dos exemplos e tutorias sobre esta API demonstra casos muito básicos e até inúteis, como demonstrar uma simples mensagem de aviso em um determinado intervalo de tempo, entre outros.
Por conta disto, decidi postar um exemplo bem prático que consiste no agendamento de um backup do banco de dados da aplicação Web em determinado horário e o envio de uma cópia desse backup por email usando a API do apache commons mail com o Gmail.

As linhas de código abaixo foram extraídas de exemplos de outros autores e adaptadas para a nossa situação.

Vou tentar demonstrar da forma mais simples possível:

Primeiro Passo: fazer o download dos arquivos .jar necessários.
Apache commons mail: http://linorg.usp.br/apache//commons/email/commons-email-current.jar
Quartz: http://d2zwv9pap9ylyd.cloudfront.net/quartz-1.8.3.tar.gz

Segundo Passo: vamos criar a classe com uma determinada tarefa. Em nosso caso, a tarefa será primeiramente o backup do banco de dados e em seguida a configuração do email para envio.

[code]package teste.quartz.tarefa;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;

import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.MultiPartEmail;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class Tarefa implements Job {

public void execute(JobExecutionContext jec) throws JobExecutionException {
	File diretorio = new File("/home/viper/Documentos/bkpdb"); //defino o nome do diretório
	File bkp = new File("/home/viper/Documentos/bkpdb/bkp.sql"); //defino o nome do arquivo de bkp inicial

	if (!diretorio.isDirectory()) { //caso o diretorio nao tenha sido criado, utiliza-se a expressão abaixo para criá-lo 
		new File("/home/viper/Documentos/bkpdb").mkdir(); 
	} else {

	}

	try {
		if (!bkp.isFile()) { //verifica-se se já existe arquivo de bkp criado, caso negativo, ele cria o arquivo de bkp inicial
			System.out.println("ainda nao existe bkp criado");
			Runtime
					.getRuntime()
					.exec(
							"pg_dump -U usuario bancodedados -f /home/viper/Documentos/bkpdb/bkp.sql");
		} else {
			System.out.println("ja existe bkp criado");
			while (bkp.isFile()) { //caso já exista o arquivo acima, ele criará um arquivo com o nomedoarquivo+data+hora.sql. Dessa forma, um arquivo não
                            //sobrescreve o outro;

				GregorianCalendar calendar = new GregorianCalendar(); //utiliza-se o GregorianCalendar para pegar a data/hora correta do sistema
				int dia = calendar.get(Calendar.DAY_OF_MONTH);
				int mes = calendar.get(Calendar.MONTH);
				int ano = calendar.get(Calendar.YEAR);
				int hora = calendar.get(Calendar.HOUR_OF_DAY);
				int minuto = calendar.get(Calendar.MINUTE);
				int segundo = calendar.get(Calendar.SECOND);
				bkp = new File(
						"/home/viper/Documentos/bkpdb/bkp"
								+ dia + mes + ano + hora + minuto + segundo
								+ ".sql"); //nome do arquivo de bkp criado com a data/hora atual
				System.out
						.println("Backup realizado com sucesso. Data atual: "
								+ dia + "/" + mes + "/" + ano + "-" + hora + ":" + minuto + ":" + segundo);
			}

			Runtime.getRuntime()
					.exec("pg_dump -U usuario bancodedados -f" + bkp); //executa o comando com o nome do arquivo de bkp acima

			File f = new File("");
			f = bkp; //pegamos aqui sempre o nome e o caminho do ultimo arquivo criado
			System.out.println("nome do arquivo/caminho: " + f);
			EmailAttachment attachment = new EmailAttachment(); //classe utilizada para criar anexos no email
			attachment.setPath(f.getPath()); //envia o caminho do arquivo
			attachment.setDisposition(EmailAttachment.ATTACHMENT);
			attachment.setDescription("File");
			attachment.setName(f.getName());

			try {

				MultiPartEmail email = new MultiPartEmail(); //classe utilizada para permitir anexos no email
				email.setDebug(true);
				email.setHostName("smtp.gmail.com"); //servidor SMTP. Aqui usamos um do Gmail
				email.setAuthentication("login_do_email", "senha"); // login e senha da conta Gmail
				email.setSSL(true); //Autenticação de segurança SSL setada como True
				email.addTo("seuemail@teste.com"); //nome do email que vai receber o bkp do banco de dados. Pode ser o seu para teste
				email.setFrom("remetentedoemail"); //endereço de email do remetente
				email.setSubject("Bkp Base de dados"); //assunto
				email.setMsg("Segue em anexo base de dados"); //mensagem de texto

				email.attach(attachment); //anexa o arquivo de bkp

				email.send(); //envia o email
			} catch (EmailException e) { //exception caso aconteça algum erro ao enviar o email
                                    System.out.println("erro no envio: " + e.printStackTrace());
                                    e.printStackTrace()
			}

		}
	} catch (IOException ex) {
		ex.printStackTrace();
	}

}

}[/code]

Terceiro Passo: criar a classe que irá executar a tarefa.

[code]package teste.quartz.tarefa;

import java.io.IOException;
import java.util.GregorianCalendar;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;

public class ExecTarefa {

static GregorianCalendar calendar = new GregorianCalendar();

    public static void main(String[] args) {

	Trigger trigger = TriggerUtils.makeDailyTrigger("Tarefa", hora, minuto); //aqui utilizamos o "makeDailyTrigger" que executa a tarefa determinada hora/minuto

	trigger.setName("Tarefa"); //setamos o nome da tarefa

	JobDetail jobDetail = new JobDetail("Tarefa", "Tarefa group",
			Tarefa.class); //definimos o JobDetail com o nome da tarefa, o grupo e a classe que contém a tarefa a ser executada

	Scheduler scheduler; //criamos o agendamento

	try {

		scheduler = new StdSchedulerFactory().getScheduler();

		scheduler.scheduleJob(jobDetail, trigger);

		scheduler.start(); //inicializando o agendamento da tarefa
		System.out.println("Agendando bkp e enviando por email");

	} catch (SchedulerException ex) {
		ex.printStackTrace(); //caso haja algum erro no agendamento, ele retorna uma exception
	}
}

}[/code]

Pessoal, como eu disse antes, eu fiz meio que uma salada de códigos de outros autores para viabilizar esse exemplo. Espero que seja útil a quem está passando por uma dificuldade semelhante à que eu passei.

Abs e obrigado.

Créditos:
gabrielmassote - http://www.guj.com.br/java/104645-api-commons-mail---usando-gmail;
Camilo Lopes - http://blog.camilolopes.com.br/tag/mysql/;
Outros.

Bela iniciativa! Parabéns!

Valeu man.

Eu uso na web, como eu faço ??

O coloco no filtro inicializando o Quartz ou coloco no XML ???

Pq o meu está funcionando, sendo que ele só printa… ele não chama outras classes :confused: