diff --git a/ejb/timer/src/main/java/org/javaee7/ejb/timer/TimerSessionBean.java b/ejb/timer/src/main/java/org/javaee7/ejb/timer/AutomaticTimerBean.java similarity index 95% rename from ejb/timer/src/main/java/org/javaee7/ejb/timer/TimerSessionBean.java rename to ejb/timer/src/main/java/org/javaee7/ejb/timer/AutomaticTimerBean.java index 473e3bb73..88a9da361 100644 --- a/ejb/timer/src/main/java/org/javaee7/ejb/timer/TimerSessionBean.java +++ b/ejb/timer/src/main/java/org/javaee7/ejb/timer/AutomaticTimerBean.java @@ -15,7 +15,7 @@ */ @Startup @Singleton -public class TimerSessionBean { +public class AutomaticTimerBean { @Resource SessionContext ctx; diff --git a/ejb/timer/src/main/java/org/javaee7/ejb/timer/MultipleScheduleTimerBean.java b/ejb/timer/src/main/java/org/javaee7/ejb/timer/MultipleScheduleTimerBean.java new file mode 100644 index 000000000..a109c2466 --- /dev/null +++ b/ejb/timer/src/main/java/org/javaee7/ejb/timer/MultipleScheduleTimerBean.java @@ -0,0 +1,33 @@ +package org.javaee7.ejb.timer; + +import javax.ejb.Schedule; +import javax.ejb.Singleton; +import javax.ejb.Startup; +import javax.ejb.Timer; +import javax.enterprise.event.Event; +import javax.inject.Inject; + +/** + * @author Jacek Jackowiak + */ +@Startup +@Singleton +public class MultipleScheduleTimerBean { + + @Inject + Event pingEvent; + + @Schedule(hour = "*", minute = "*", second = "*/5", info = "Every 5 second timer") + public void fastAutomaticallyScheduled(Timer timer) { + fireEvent(timer); + } + + @Schedule(hour = "*", minute = "*", second = "*/10", info = "Every 10 second timer") + public void slowlyAutomaticallyScheduled(Timer timer) { + fireEvent(timer); + } + + private void fireEvent(Timer timer) { + pingEvent.fire(new Ping(timer.getInfo().toString())); + } +} diff --git a/ejb/timer/src/main/java/org/javaee7/ejb/timer/ProgrammaticTimerBean.java b/ejb/timer/src/main/java/org/javaee7/ejb/timer/ProgrammaticTimerBean.java new file mode 100644 index 000000000..0eb5e57ef --- /dev/null +++ b/ejb/timer/src/main/java/org/javaee7/ejb/timer/ProgrammaticTimerBean.java @@ -0,0 +1,39 @@ +package org.javaee7.ejb.timer; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.ejb.*; +import javax.enterprise.event.Event; +import javax.inject.Inject; + +/** + * author: Jacek Jackowiak + */ +@Startup +@Singleton +public class ProgrammaticTimerBean { + + @Inject + Event pingEvent; + + @Resource + TimerService timerService; + + @PostConstruct + public void initialize() { + ScheduleExpression scheduleExpression = new ScheduleExpression() + .hour("*") + .minute("*") + .second("*/5"); + + TimerConfig timerConfig = new TimerConfig(); + timerConfig.setInfo("Every 5 second timer"); + + timerService.createCalendarTimer(scheduleExpression, timerConfig); + } + + @Timeout + public void programmaticTimout(Timer timer) { + pingEvent.fire(new Ping(timer.getInfo().toString())); + } +} diff --git a/ejb/timer/src/main/java/org/javaee7/ejb/timer/SchedulesTimerBean.java b/ejb/timer/src/main/java/org/javaee7/ejb/timer/SchedulesTimerBean.java new file mode 100644 index 000000000..826fc626b --- /dev/null +++ b/ejb/timer/src/main/java/org/javaee7/ejb/timer/SchedulesTimerBean.java @@ -0,0 +1,25 @@ +package org.javaee7.ejb.timer; + +import javax.ejb.*; +import javax.enterprise.event.Event; +import javax.inject.Inject; + +/** + * @author Jacek Jackowiak + */ +@Startup +@Singleton +public class SchedulesTimerBean { + + @Inject + Event pingEvent; + + @Schedules({ + @Schedule(hour = "*", minute = "*", second = "*/5", info = "Every 5 second timer"), + @Schedule(hour = "*", minute = "*", second = "*/10", info = "Every 10 second timer") + }) + public void automaticallyScheduled(Timer timer) { + pingEvent.fire(new Ping(timer.getInfo().toString())); + } + +} diff --git a/ejb/timer/src/test/java/org/javaee7/ejb/timer/TimerSessionBeanTest.java b/ejb/timer/src/test/java/org/javaee7/ejb/timer/AutomaticTimerBeanTest.java similarity index 70% rename from ejb/timer/src/test/java/org/javaee7/ejb/timer/TimerSessionBeanTest.java rename to ejb/timer/src/test/java/org/javaee7/ejb/timer/AutomaticTimerBeanTest.java index 0882d1c03..563bd1701 100644 --- a/ejb/timer/src/test/java/org/javaee7/ejb/timer/TimerSessionBeanTest.java +++ b/ejb/timer/src/test/java/org/javaee7/ejb/timer/AutomaticTimerBeanTest.java @@ -17,12 +17,13 @@ import static com.jayway.awaitility.Awaitility.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; +import static org.javaee7.ejb.timer.WithinWindowMatcher.withinWindow; /** * author: Jakub Marchwicki */ @RunWith(Arquillian.class) -public class TimerSessionBeanTest { +public class AutomaticTimerBeanTest { final static long TIMEOUT = 5000l; final static long TOLERANCE = 1000l; @@ -38,7 +39,7 @@ public static WebArchive deploy() { return ShrinkWrap.create(WebArchive.class) .addAsLibraries(jars) - .addClasses(Ping.class, PingsListener.class, TimerSessionBean.class); + .addClasses(WithinWindowMatcher.class, Ping.class, PingsListener.class, AutomaticTimerBean.class); } @Test @@ -52,20 +53,4 @@ public void should_receive_two_pings() { System.out.println("Actual timeout = " + delay); assertThat(delay, is(withinWindow(TIMEOUT, TOLERANCE))); } - - private Matcher withinWindow(final long timeout, final long tolerance) { - return new BaseMatcher() { - @Override - public boolean matches(Object item) { - final Long actual = (Long) item; - return Math.abs(actual - timeout) < tolerance; - } - - @Override - public void describeTo(Description description) { - //To change body of implemented methods use File | Settings | File Templates. - } - }; - } - } diff --git a/ejb/timer/src/test/java/org/javaee7/ejb/timer/MultipleScheduleTimerBeanTest.java b/ejb/timer/src/test/java/org/javaee7/ejb/timer/MultipleScheduleTimerBeanTest.java new file mode 100644 index 000000000..ac2844829 --- /dev/null +++ b/ejb/timer/src/test/java/org/javaee7/ejb/timer/MultipleScheduleTimerBeanTest.java @@ -0,0 +1,62 @@ +package org.javaee7.ejb.timer; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.inject.Inject; +import java.io.File; + +import static com.jayway.awaitility.Awaitility.await; +import static com.jayway.awaitility.Awaitility.to; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.javaee7.ejb.timer.WithinWindowMatcher.withinWindow; + +/** + * author: Jacek Jackowiak + */ +@RunWith(Arquillian.class) +public class MultipleScheduleTimerBeanTest { + + final static long TIMEOUT = 0l; + final static long TOLERANCE = 1000l; + + @Inject + PingsListener pings; + + @Deployment + public static WebArchive deploy() { + File[] jars = Maven.resolver().loadPomFromFile("pom.xml") + .resolve("com.jayway.awaitility:awaitility") + .withTransitivity().asFile(); + + return ShrinkWrap.create(WebArchive.class) + .addAsLibraries(jars) + .addClasses(WithinWindowMatcher.class, Ping.class, PingsListener.class, MultipleScheduleTimerBean.class); + } + + @Test + public void should_receive_three_pings() { + await().untilCall(to(pings.getPings()).size(), equalTo(3)); + + Ping firstPing = pings.getPings().get(0); + Ping secondPing = pings.getPings().get(1); + Ping thirdPing = pings.getPings().get(2); + + long delay = secondPing.getTime() - firstPing.getTime(); + System.out.println("Actual timeout = " + delay); + long delay2 = thirdPing.getTime() - secondPing.getTime(); + System.out.println("Actual timeout = " + delay2); + long smallerDelay = Math.min(delay, delay2); + assertThat(smallerDelay, is(withinWindow(TIMEOUT, TOLERANCE))); + } +} diff --git a/ejb/timer/src/test/java/org/javaee7/ejb/timer/ProgrammaticTimerBeanTest.java b/ejb/timer/src/test/java/org/javaee7/ejb/timer/ProgrammaticTimerBeanTest.java new file mode 100644 index 000000000..22fd534b6 --- /dev/null +++ b/ejb/timer/src/test/java/org/javaee7/ejb/timer/ProgrammaticTimerBeanTest.java @@ -0,0 +1,58 @@ +package org.javaee7.ejb.timer; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.inject.Inject; +import java.io.File; + +import static com.jayway.awaitility.Awaitility.await; +import static com.jayway.awaitility.Awaitility.to; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.javaee7.ejb.timer.WithinWindowMatcher.withinWindow; + +/** + * author: Jacek Jackowiak + */ +@RunWith(Arquillian.class) +public class ProgrammaticTimerBeanTest { + + final static long TIMEOUT = 5000l; + final static long TOLERANCE = 1000l; + + @Inject + PingsListener pings; + + @Deployment + public static WebArchive deploy() { + File[] jars = Maven.resolver().loadPomFromFile("pom.xml") + .resolve("com.jayway.awaitility:awaitility") + .withTransitivity().asFile(); + + return ShrinkWrap.create(WebArchive.class) + .addAsLibraries(jars) + .addClasses(WithinWindowMatcher.class, Ping.class, PingsListener.class, ProgrammaticTimerBean.class); + } + + @Test + public void should_receive_two_pings() { + await().untilCall(to(pings.getPings()).size(), equalTo(2)); + + Ping firstPing = pings.getPings().get(0); + Ping secondPing = pings.getPings().get(1); + + long delay = secondPing.getTime() - firstPing.getTime(); + System.out.println("Actual timeout = " + delay); + assertThat(delay, is(withinWindow(TIMEOUT, TOLERANCE))); + } +} \ No newline at end of file diff --git a/ejb/timer/src/test/java/org/javaee7/ejb/timer/SchedulesTimerBeanTest.java b/ejb/timer/src/test/java/org/javaee7/ejb/timer/SchedulesTimerBeanTest.java new file mode 100644 index 000000000..ee0031b59 --- /dev/null +++ b/ejb/timer/src/test/java/org/javaee7/ejb/timer/SchedulesTimerBeanTest.java @@ -0,0 +1,60 @@ +package org.javaee7.ejb.timer; + +import org.hamcrest.Matcher; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.resolver.api.maven.Maven; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.inject.Inject; +import java.io.File; + +import static com.jayway.awaitility.Awaitility.await; +import static com.jayway.awaitility.Awaitility.to; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.javaee7.ejb.timer.WithinWindowMatcher.withinWindow; + +/** + * author: Jacek Jackowiak + */ +@RunWith(Arquillian.class) +public class SchedulesTimerBeanTest { + + final static long TIMEOUT = 0l; + final static long TOLERANCE = 1000l; + + @Inject + PingsListener pings; + + @Deployment + public static WebArchive deploy() { + File[] jars = Maven.resolver().loadPomFromFile("pom.xml") + .resolve("com.jayway.awaitility:awaitility") + .withTransitivity().asFile(); + + return ShrinkWrap.create(WebArchive.class) + .addAsLibraries(jars) + .addClasses(WithinWindowMatcher.class, Ping.class, PingsListener.class, SchedulesTimerBean.class); + } + + @Test + public void should_receive_three_pings() { + await().untilCall(to(pings.getPings()).size(), equalTo(3)); + + Ping firstPing = pings.getPings().get(0); + Ping secondPing = pings.getPings().get(1); + Ping thirdPing = pings.getPings().get(2); + + long delay = secondPing.getTime() - firstPing.getTime(); + System.out.println("Actual timeout = " + delay); + long delay2 = thirdPing.getTime() - secondPing.getTime(); + System.out.println("Actual timeout = " + delay2); + long smallerDelay = Math.min(delay, delay2); + assertThat(smallerDelay, is(withinWindow(TIMEOUT, TOLERANCE))); + } +} diff --git a/ejb/timer/src/test/java/org/javaee7/ejb/timer/WithinWindowMatcher.java b/ejb/timer/src/test/java/org/javaee7/ejb/timer/WithinWindowMatcher.java new file mode 100644 index 000000000..da432dbc1 --- /dev/null +++ b/ejb/timer/src/test/java/org/javaee7/ejb/timer/WithinWindowMatcher.java @@ -0,0 +1,30 @@ +package org.javaee7.ejb.timer; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; + +class WithinWindowMatcher extends BaseMatcher { + private final long timeout; + private final long tolerance; + + public WithinWindowMatcher(long timeout, long tolerance) { + this.timeout = timeout; + this.tolerance = tolerance; + } + + @Override + public boolean matches(Object item) { + final Long actual = (Long) item; + return Math.abs(actual - timeout) < tolerance; + } + + @Override + public void describeTo(Description description) { + //To change body of implemented methods use File | Settings | File Templates. + } + + public static Matcher withinWindow(final long timeout, final long tolerance) { + return new WithinWindowMatcher(timeout, tolerance); + } +}