quartz-app
quartz-app/pom.xml
quartz-app/quartz-beans
quartz-app/quartz-beans/pom.xml
quartz-app/quartz-beans/src/main/java/org/superbiz/quartz/JobBean.java
quartz-app/quartz-beans/src/main/java/org/superbiz/quartz/JobScheduler.java
quartz-app/quartz-beans/src/main/java/org/superbiz/quartz/QuartzMdb.java
quartz-app/quartz-beans/src/main/resources/META-INF
quartz-app/quartz-beans/src/main/resources/META-INF/ejb-jar.xml
quartz-app/quartz-beans/src/test/java/org/superbiz/quartz/QuartzMdbTest.java
quartz-app/quartz-ra
quartz-app/quartz-ra/pom.xml
quartz-app/quartz-ra/src/main/resources/META-INF
quartz-app/quartz-ra/src/main/resources/META-INF/ra.xml
Uso do Adaptador de Recursos de Quartz
Este exemplo é um pouco datado. Ele antecede a API de agendamento que
foi adicionado ao EJB 3.1. Aplicações modernas devem usar a API de agendamento, que possui muitos, se não todos, os mesmos recursos que o Quartz. De fato, o Quartz é o mecanismo que aciona o suporte @Schedule e ScheduleExpression no OpenEJB e TomEE.
|
Apesar de datado de uma perspectiva de programação, ainda é uma excelente referência sobre como conectar e testar um Java EE Resource Adapter personalizado..
Estrutura do projeto
Como os arquivos .rar
não se saem bem em uma estrutura padrão do classpath, o
objetivo é efetivamente desembrulhar
o .rar
para que suas dependências
estejam no classpath e seu arquivo ra.xml
ser encontrado e verificado pelo
OpenEJB.
Fazemos isso criando um módulo mini-maven para representar o .rar
no
termos maven. O pom.xml
do módulo rar
declara todos os
jars que estariam dentro do .rar
como dependências automatizadas. O arquivo ra.xml
é adicionado ao projeto em src/main/resources/META-INF/ra.xml
onde será visível para outros módulos.
ra.xml
O conector em questão possui adaptadores de recursos de entrada e saída.
O adaptador de recursos de entrada pode ser usado para conduzir message driven beans (MDBs).
O adaptador de recursos de saída, QuartzResourceAdapter
, pode ser injetado em qualquer componente via`@Resource` e usado para originar e enviar mensagens ou eventos.
<connector xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
version="1.5">
<description>Quartz ResourceAdapter</description>
<display-name>Quartz ResourceAdapter</display-name>
<vendor-name>OpenEJB</vendor-name>
<eis-type>Quartz Adapter</eis-type>
<resourceadapter-version>1.0</resourceadapter-version>
<resourceadapter id="QuartzResourceAdapter">
<resourceadapter-class>org.apache.openejb.resource.quartz.QuartzResourceAdapter</resourceadapter-class>
<inbound-resourceadapter>
<messageadapter>
<messagelistener>
<messagelistener-type>org.quartz.Job</messagelistener-type>
<activationspec>
<activationspec-class>org.apache.openejb.resource.quartz.JobSpec</activationspec-class>
</activationspec>
</messagelistener>
</messageadapter>
</inbound-resourceadapter>
</resourceadapter>
</connector>
Usando o Adaptador de Recursos de Saída
Aqui vemos o adaptador de recursos de saída usado em um bean de sessão stateless para agendar uma tarefa que será executada pelo MDB
package org.superbiz.quartz;
import org.apache.openejb.resource.quartz.QuartzResourceAdapter;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.quartz.SimpleTrigger;
import javax.ejb.Stateless;
import javax.naming.InitialContext;
import java.util.Date;
@Stateless
public class JobBean implements JobScheduler {
@Override
public Date createJob() throws Exception {
final QuartzResourceAdapter ra = (QuartzResourceAdapter) new InitialContext().lookup("java:openejb/Resource/QuartzResourceAdapter");
final Scheduler s = ra.getScheduler();
//Add a job type
final JobDetail jd = new JobDetail("job1", "group1", JobBean.MyTestJob.class);
jd.getJobDataMap().put("MyJobKey", "MyJobValue");
//Schedule my 'test' job to run now
final SimpleTrigger trigger = new SimpleTrigger("trigger1", "group1", new Date());
return s.scheduleJob(jd, trigger);
}
public static class MyTestJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("This is a simple test job to get: " + context.getJobDetail().getJobDataMap().get("MyJobKey"));
}
}
}
Recebendo dados do adaptador de recursos de entrada
package org.superbiz.quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "cronExpression", propertyValue = "* * * * * ?")})
public class QuartzMdb implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("Executing Job");
}
}
Caso de teste
package org.superbiz.quartz;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Date;
import java.util.Properties;
public class QuartzMdbTest {
private static InitialContext initialContext = null;
@BeforeClass
public static void beforeClass() throws Exception {
if (null == initialContext) {
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.core.LocalInitialContextFactory");
initialContext = new InitialContext(properties);
}
}
@AfterClass
public static void afterClass() throws Exception {
if (null != initialContext) {
initialContext.close();
initialContext = null;
}
}
@Test
public void testLookup() throws Exception {
final JobScheduler jbi = (JobScheduler) initialContext.lookup("JobBeanLocal");
final Date d = jbi.createJob();
Thread.sleep(500);
System.out.println("Scheduled test job should have run at: " + d.toString());
}
@Test
public void testMdb() throws Exception {
// Sleep 3 seconds and give quartz a chance to execute our MDB
Thread.sleep(3000);
}
}
Executando
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.superbiz.quartz.QuartzMdbTest
Apache OpenEJB 4.0.0-beta-1 build: 20111002-04:06
http://tomee.apache.org/
INFO - openejb.home = /Users/dblevins/examples/quartz-app/quartz-beans
INFO - openejb.base = /Users/dblevins/examples/quartz-app/quartz-beans
INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
INFO - Found ConnectorModule in classpath: /Users/dblevins/examples/quartz-app/quartz-ra/target/quartz-ra-1.0.jar
INFO - Found EjbModule in classpath: /Users/dblevins/examples/quartz-app/quartz-beans/target/classes
INFO - Beginning load: /Users/dblevins/examples/quartz-app/quartz-ra/target/quartz-ra-1.0.jar
INFO - Extracting jar: /Users/dblevins/examples/quartz-app/quartz-ra/target/quartz-ra-1.0.jar
INFO - Extracted path: /Users/dblevins/examples/quartz-app/quartz-ra/target/quartz-ra-1.0
INFO - Beginning load: /Users/dblevins/examples/quartz-app/quartz-beans/target/classes
INFO - Configuring enterprise application: /Users/dblevins/examples/quartz-app/quartz-beans/classpath.ear
INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
INFO - Auto-creating a container for bean JobBean: Container(type=STATELESS, id=Default Stateless Container)
INFO - Configuring Service(id=QuartzResourceAdapter, type=Resource, provider-id=QuartzResourceAdapter)
INFO - Configuring Service(id=quartz-ra-1.0, type=Container, provider-id=Default MDB Container)
INFO - Enterprise application "/Users/dblevins/examples/quartz-app/quartz-beans/classpath.ear" loaded.
INFO - Assembling app: /Users/dblevins/examples/quartz-app/quartz-beans/classpath.ear
INFO - Jndi(name=JobBeanLocal) --> Ejb(deployment-id=JobBean)
INFO - Jndi(name=global/classpath.ear/quartz-beans/JobBean!org.superbiz.quartz.JobScheduler) --> Ejb(deployment-id=JobBean)
INFO - Jndi(name=global/classpath.ear/quartz-beans/JobBean) --> Ejb(deployment-id=JobBean)
INFO - Created Ejb(deployment-id=JobBean, ejb-name=JobBean, container=Default Stateless Container)
INFO - Created Ejb(deployment-id=QuartzMdb, ejb-name=QuartzMdb, container=quartz-ra-1.0)
Executing Job
INFO - Started Ejb(deployment-id=JobBean, ejb-name=JobBean, container=Default Stateless Container)
INFO - Started Ejb(deployment-id=QuartzMdb, ejb-name=QuartzMdb, container=quartz-ra-1.0)
INFO - Deployed Application(path=/Users/dblevins/examples/quartz-app/quartz-beans/classpath.ear)
This is a simple test job to get: MyJobValue
Scheduled test job should have run at: Fri Oct 28 17:05:12 PDT 2011
Executing Job
Executing Job
Executing Job
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4.971 sec
Results :
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0