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.
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();
}
}
}
Terceiro Passo: criar a classe que irá executar a tarefa.
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
}
}
}
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.
Kleber Parabéns e Obrigado campeão, só uma duvida eesas clases ficam dentro da sua aplicação Web?
ResponderExcluir