| :index-group: Java EE Connectors |
| :jbake-type: page |
| :jbake-status: status=published |
| = Uso do Adaptador de Recursos de Quartz |
| |
| NOTE: 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. |
| |
| [source,java] |
| ---- |
| 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 |
| ---- |
| |
| === 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. |
| |
| [source,xml] |
| ---- |
| <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 |
| |
| [source,java] |
| ---- |
| 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 |
| |
| [source,java] |
| ---- |
| 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 |
| |
| [source,java] |
| ---- |
| 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 |
| |
| [source,console] |
| ---- |
| ------------------------------------------------------- |
| 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 |
| ---- |