Author: dallen6
Date: 2009-03-08 13:56:37 -0400 (Sun, 08 Mar 2009)
New Revision: 1816
Added:
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/AsynchronousTransactionalEventNotification.java
Modified:
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/DeferredEventNotification.java
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/EventManager.java
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/TransactionalObserverImpl.java
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/DogAgent.java
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/EventTest.java
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/Pomeranian.java
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/PomeranianInterface.java
Log:
Added support for asynchronously called transactional observers; updated tests for
transactional observers.
Added:
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/AsynchronousTransactionalEventNotification.java
===================================================================
---
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/AsynchronousTransactionalEventNotification.java
(rev 0)
+++
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/AsynchronousTransactionalEventNotification.java 2009-03-08
17:56:37 UTC (rev 1816)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.webbeans.event;
+
+import org.jboss.webbeans.context.DependentContext;
+import org.jboss.webbeans.log.Log;
+import org.jboss.webbeans.log.Logging;
+
+/**
+ * @author David Allen
+ *
+ */
+public class AsynchronousTransactionalEventNotification<T> extends
DeferredEventNotification<T>
+{
+ private static Log log = Logging.getLog(DeferredEventNotification.class);
+
+ public AsynchronousTransactionalEventNotification(T event, ObserverImpl<T>
observer)
+ {
+ super(event, observer);
+ }
+
+ @Override
+ public void run()
+ {
+ // Let the event be deferred again as just an asynchronous event
+ DependentContext.INSTANCE.setActive(true);
+ try
+ {
+ log.trace("Sending event [" + event + "] asynchronously to
transaction observer " + observer);
+ observer.sendEventAsynchronously(event);
+ }
+ catch (Exception e)
+ {
+ log.error("Failure while queuing observer for event [" + event +
"]", e);
+ }
+ finally
+ {
+ DependentContext.INSTANCE.setActive(false);
+ }
+ }
+
+}
Property changes on:
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/AsynchronousTransactionalEventNotification.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/DeferredEventNotification.java
===================================================================
---
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/DeferredEventNotification.java 2009-03-08
16:07:18 UTC (rev 1815)
+++
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/DeferredEventNotification.java 2009-03-08
17:56:37 UTC (rev 1816)
@@ -31,9 +31,9 @@
private static Log log = Logging.getLog(DeferredEventNotification.class);
// The observer
- private ObserverImpl<T> observer;
+ protected ObserverImpl<T> observer;
// The event object
- private T event;
+ protected T event;
/**
* Creates a new deferred event notifier.
@@ -52,15 +52,22 @@
DependentContext.INSTANCE.setActive(true);
try
{
+ log.debug("Sending event [" + event + "] directly to observer
" + observer);
observer.sendEvent(event);
}
- catch (RuntimeException e)
+ catch (Exception e)
{
- log.error("Failure while notifying an observer of an event", e);
+ log.error("Failure while notifying an observer of event [" + event +
"]", e);
}
finally
{
DependentContext.INSTANCE.setActive(false);
}
}
+
+ @Override
+ public String toString()
+ {
+ return "Deferred event [" + event + "] for [" + observer +
"]";
+ }
}
Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/event/EventManager.java
===================================================================
--- ri/trunk/impl/src/main/java/org/jboss/webbeans/event/EventManager.java 2009-03-08
16:07:18 UTC (rev 1815)
+++ ri/trunk/impl/src/main/java/org/jboss/webbeans/event/EventManager.java 2009-03-08
17:56:37 UTC (rev 1816)
@@ -28,6 +28,8 @@
import javax.event.Observer;
import org.jboss.webbeans.context.DependentContext;
+import org.jboss.webbeans.log.Log;
+import org.jboss.webbeans.log.Logging;
import org.jboss.webbeans.util.Reflections;
import org.jboss.webbeans.util.Strings;
import org.jboss.webbeans.util.collections.ForwardingMap;
@@ -40,7 +42,8 @@
*/
public class EventManager
{
-
+ private static Log log = Logging.getLog(EventManager.class);
+
/**
* An event type -> observer list map
*/
@@ -142,6 +145,7 @@
{
EventObserver<T> eventObserver = new EventObserver<T>(observer,
eventType, bindings);
registeredObservers.put(eventType, eventObserver);
+ log.debug("Added observer " + observer + " observing event type
" + eventType);
}
/**
@@ -160,11 +164,13 @@
{
for (EventObserver<?> observer : registeredObservers.get(clazz))
{
+ log.debug("Checking observer " + observer + " to see if it is
interested in event [" + event + "]");
if (observer.isObserverInterested(bindings))
{
@SuppressWarnings("unchecked")
Observer<T> o = (Observer<T>) observer.getObserver();
interestedObservers.add(o);
+ log.debug("Added observer " + observer + " for event
[" + event + "]");
}
}
}
Modified:
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/TransactionalObserverImpl.java
===================================================================
---
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/TransactionalObserverImpl.java 2009-03-08
16:07:18 UTC (rev 1815)
+++
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/TransactionalObserverImpl.java 2009-03-08
17:56:37 UTC (rev 1816)
@@ -23,6 +23,7 @@
import javax.event.AfterTransactionCompletion;
import javax.event.AfterTransactionFailure;
import javax.event.AfterTransactionSuccess;
+import javax.event.Asynchronously;
import javax.event.BeforeTransactionCompletion;
import javax.inject.DefinitionException;
import javax.inject.manager.Bean;
@@ -85,10 +86,10 @@
*/
public static boolean isObserverMethodTransactional(AnnotatedMethod<?>
observer)
{
- boolean transactional = false;
- if ((!observer.getAnnotatedParameters(BeforeTransactionCompletion.class).isEmpty())
|| (!observer.getAnnotatedParameters(AfterTransactionCompletion.class).isEmpty()) ||
(!observer.getAnnotatedParameters(AfterTransactionSuccess.class).isEmpty()) ||
(!observer.getAnnotatedParameters(AfterTransactionFailure.class).isEmpty()))
+ boolean transactional = true;
+ if ((observer.getAnnotatedParameters(BeforeTransactionCompletion.class).isEmpty())
|| (observer.getAnnotatedParameters(AfterTransactionCompletion.class).isEmpty()) ||
(observer.getAnnotatedParameters(AfterTransactionSuccess.class).isEmpty()) ||
(observer.getAnnotatedParameters(AfterTransactionFailure.class).isEmpty()))
{
- transactional = true;
+ transactional = false;
}
return transactional;
}
@@ -165,7 +166,15 @@
*/
private void deferEvent(T event)
{
- DeferredEventNotification<T> deferredEvent = new
DeferredEventNotification<T>(event, this);
+ DeferredEventNotification<T> deferredEvent = null;
+ if (this.observerMethod.getAnnotatedParameters(Asynchronously.class).isEmpty())
+ {
+ deferredEvent = new DeferredEventNotification<T>(event, this);
+ }
+ else
+ {
+ deferredEvent = new AsynchronousTransactionalEventNotification<T>(event,
this);
+ }
transactionObservationPhase.registerTask(manager.getTransactionServices(),
deferredEvent);
}
Modified:
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/DogAgent.java
===================================================================
---
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/DogAgent.java 2009-03-08
16:07:18 UTC (rev 1815)
+++
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/DogAgent.java 2009-03-08
17:56:37 UTC (rev 1816)
@@ -1,18 +1,17 @@
package org.jboss.jsr299.tck.tests.event.transactionalObservers;
+import static javax.ejb.TransactionManagementType.BEAN;
+
import javax.annotation.Named;
import javax.annotation.Resource;
import javax.annotation.security.RunAs;
import javax.ejb.EJBException;
-import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.inject.Current;
import javax.inject.manager.Manager;
import javax.transaction.UserTransaction;
-import static javax.ejb.TransactionManagementType.BEAN;
-
@Stateless
@TransactionManagement(BEAN)
@RunAs("Bubba")
Modified:
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/EventTest.java
===================================================================
---
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/EventTest.java 2009-03-08
16:07:18 UTC (rev 1815)
+++
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/EventTest.java 2009-03-08
17:56:37 UTC (rev 1816)
@@ -30,6 +30,8 @@
import org.jboss.jsr299.tck.impl.packaging.Artifact;
import org.jboss.jsr299.tck.impl.packaging.IntegrationTest;
import org.jboss.jsr299.tck.impl.packaging.Packaging;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
@@ -49,27 +51,45 @@
private static final Annotation TAME_LITERAL = new AnnotationLiteral<Tame>()
{
};
+ private PomeranianInterface dog;
+ @BeforeMethod(alwaysRun = true)
+ public void setupTest()
+ {
+ dog = (PomeranianInterface)
getCurrentManager().getInstanceByName("Teddy");
+ }
+
+// @AfterMethod(alwaysRun = true)
+// public void teardownTest()
+// {
+// try
+// {
+// dog.removeSessionBean();
+// }
+// catch (Exception e)
+// {
+// // Not important since the bean is now gone one way or the other
+// }
+// }
+
@Test(groups = { "events", "integration" })
@SpecAssertion(section = "7.5.6", id = "a")
public void testTransactionalObserverNotifiedImmediatelyWhenNoTransactionInProgress()
{
- PomeranianInterface dog = (PomeranianInterface)
getCurrentManager().getInstanceByName("Teddy");
dog.setCorrectContext(false);
dog.setCorrectTransactionState(false);
Agent dogAgent = getCurrentManager().getInstanceByType(Agent.class);
assert dogAgent != null;
dogAgent.sendOutsideTransaction(BigInteger.TEN);
assert dog.isCorrectTransactionState();
- //TODO Fix the security contexts
-// assert dog.isCorrectContext();
+ // TODO Fix the security contexts
+ // assert dog.isCorrectContext();
}
@Test(groups = { "events", "integration" })
- @SpecAssertions( { @SpecAssertion(section = "7.5.6", id = "c"),
@SpecAssertion(section = "7.5.6", id = "f"), @SpecAssertion(section =
"7.5.6", id = "i") })
+ @SpecAssertions( { @SpecAssertion(section = "7.5.6", id = "c"),
@SpecAssertion(section = "7.5.6", id = "f"), @SpecAssertion(section =
"7.5.6", id = "i"), @SpecAssertion(section = "7.5.8", id =
"f") })
public void testAfterTransactionCompletionObserver()
{
- PomeranianInterface dog = (PomeranianInterface)
getCurrentManager().getInstanceByName("Teddy");
dog.setCorrectContext(false);
dog.setCorrectTransactionState(false);
assert !getCurrentManager().resolveObservers("event").isEmpty();
@@ -82,7 +102,6 @@
@SpecAssertions( { @SpecAssertion(section = "7.5.6", id = "d"),
@SpecAssertion(section = "7.5.6", id = "j") })
public void testAfterTransactionSuccessObserver()
{
- PomeranianInterface dog = (PomeranianInterface)
getCurrentManager().getInstanceByName("Teddy");
dog.setCorrectContext(false);
dog.setCorrectTransactionState(false);
Agent dogAgent = getCurrentManager().getInstanceByType(Agent.class);
@@ -90,11 +109,10 @@
assert dog.isCorrectTransactionState();
}
- @Test(groups = { "events", "integration", "broken" })
+ @Test(groups = { "events", "integration" })
@SpecAssertions( { @SpecAssertion(section = "7.5.6", id = "e"),
@SpecAssertion(section = "7.5.6", id = "k") })
public void testAfterTransactionFailureObserver()
{
- PomeranianInterface dog = (PomeranianInterface)
getCurrentManager().getInstanceByName("Teddy");
dog.setCorrectContext(false);
dog.setCorrectTransactionState(false);
Agent dogAgent = getCurrentManager().getInstanceByType(Agent.class);
@@ -106,7 +124,6 @@
@SpecAssertions( { @SpecAssertion(section = "7.5.6", id = "b"),
@SpecAssertion(section = "7.5.6", id = "h") })
public void testBeforeTransactionCompletionObserver()
{
- PomeranianInterface dog = (PomeranianInterface)
getCurrentManager().getInstanceByName("Teddy");
dog.setCorrectContext(false);
dog.setCorrectTransactionState(false);
Agent dogAgent = getCurrentManager().getInstanceByType(Agent.class);
@@ -121,11 +138,15 @@
assert false;
}
- @Test(groups = { "stub", "events" })
+ @Test(groups = { "events", "broken" })
@SpecAssertion(section = "7.5.7", id = "c")
public void testAsynchronousObserverAlsoTransactional()
{
- assert false;
+ dog.setCorrectContext(false);
+ dog.setCorrectTransactionState(false);
+ Agent dogAgent = getCurrentManager().getInstanceByType(Agent.class);
+ dogAgent.sendInTransaction('a');
+ assert dog.isCorrectTransactionState();
}
/**
@@ -141,23 +162,11 @@
assert false;
}
- /**
- * Otherwise, if the observer method is a transactional observer method and
- * there is currently a JTA transaction in progress, the observer object
- * calls the observer method during the appropriate transaction completion
- * phase.
- */
- @Test(groups = { "stub", "events" })
- @SpecAssertion(section = "7.5.8", id = "f")
- public void testTransactionalObserverMethodCalledDuringTransactionCompletionPhase()
- {
- assert false;
- }
-
- @Test(groups = { "stub", "events", "integration" })
+ @Test(groups = { "broken", "events", "integration" })
@SpecAssertion(section = "7.5.8", id = "p")
public void testTransactionalObserverThrownExceptionIsCaughtAndLogged()
{
+ // TODO There really is no way to verify that something is logged
assert false;
}
Modified:
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/Pomeranian.java
===================================================================
---
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/Pomeranian.java 2009-03-08
16:07:18 UTC (rev 1815)
+++
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/Pomeranian.java 2009-03-08
17:56:37 UTC (rev 1816)
@@ -1,16 +1,16 @@
package org.jboss.jsr299.tck.tests.event.transactionalObservers;
import static javax.ejb.TransactionManagementType.BEAN;
-import static javax.transaction.Status.STATUS_COMMITTED;
import static javax.transaction.Status.STATUS_NO_TRANSACTION;
-import static javax.transaction.Status.STATUS_ROLLEDBACK;
import java.math.BigInteger;
+import java.util.logging.Logger;
import javax.annotation.Named;
import javax.annotation.Resource;
import javax.context.SessionScoped;
import javax.ejb.EJBException;
+import javax.ejb.Remove;
import javax.ejb.SessionContext;
import javax.ejb.Stateful;
import javax.ejb.TransactionManagement;
@@ -30,6 +30,8 @@
@SessionScoped
public class Pomeranian implements PomeranianInterface
{
+ private static final Logger log = Logger.getLogger(Pomeranian.class.getName());
+
@Resource
private UserTransaction transaction;
@@ -68,14 +70,11 @@
{
try
{
- if (transaction.getStatus() == STATUS_COMMITTED)
+ log.warning("Observing integer event with tx status: " +
transaction.getStatus());
+ if (transaction.getStatus() == STATUS_NO_TRANSACTION)
{
setCorrectTransactionState(true);
}
- else
- {
- throw new EJBException("Incorrect transaction state " +
transaction.getStatus());
- }
}
catch (SystemException e)
{
@@ -92,14 +91,10 @@
{
try
{
- if (transaction.getStatus() == STATUS_ROLLEDBACK)
+ if (transaction.getStatus() == STATUS_NO_TRANSACTION)
{
setCorrectTransactionState(true);
}
- else
- {
- throw new EJBException("Incorrect transaction state " +
transaction.getStatus());
- }
}
catch (SystemException e)
{
@@ -120,6 +115,7 @@
{
setCorrectContext(true);
}
+ log.warning("Principal caller is " +
context.getCallerPrincipal().getName());
}
catch (SystemException e)
{
@@ -135,15 +131,12 @@
{
setCorrectTransactionState(true);
}
- else
- {
- throw new EJBException("Incorrect transaction state " +
transaction.getStatus());
- }
if (context.getCallerPrincipal().getName().equals("Bubba"))
{
setCorrectContext(true);
}
+ log.warning("Principal caller is " +
context.getCallerPrincipal().getName());
}
catch (SystemException e)
{
@@ -151,6 +144,22 @@
}
}
+ public void observeCharEvent(Character event)
+ {
+ try
+ {
+ log.warning("Observing character event with tx status: " +
transaction.getStatus());
+ if (transaction.getStatus() == STATUS_NO_TRANSACTION)
+ {
+ setCorrectTransactionState(true);
+ }
+ }
+ catch (SystemException e)
+ {
+ throw new EJBException("Failed to detect transaction status", e);
+ }
+ }
+
public boolean isCorrectContext()
{
return correctContext;
@@ -170,5 +179,11 @@
{
this.correctTransactionState = correctTransactionState;
}
+
+ @Remove
+ public void removeSessionBean()
+ {
+
+ }
}
Modified:
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/PomeranianInterface.java
===================================================================
---
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/PomeranianInterface.java 2009-03-08
16:07:18 UTC (rev 1815)
+++
tck/trunk/impl/src/main/java/org/jboss/jsr299/tck/tests/event/transactionalObservers/PomeranianInterface.java 2009-03-08
17:56:37 UTC (rev 1816)
@@ -31,6 +31,8 @@
public void observeBigIntegerEvent(BigInteger event);
public void observeDoubleEvent(Double event);
+
+ public void observeCharEvent(Character event);
public boolean isCorrectContext();
@@ -39,4 +41,6 @@
public boolean isCorrectTransactionState();
public void setCorrectTransactionState(boolean correctTransactionState);
+
+ public void removeSessionBean();
}