[jboss-cvs] JBossAS SVN: r105156 - in projects/ejb-book/trunk/chxx-poker/src: main/java/org/jboss/ejb3/examples/chxx/transactions/impl and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Mon May 24 14:06:23 EDT 2010


Author: ALRubinger
Date: 2010-05-24 14:06:22 -0400 (Mon, 24 May 2010)
New Revision: 105156

Added:
   projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/BlackjackGameLocalBusiness.java
   projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/BlackjackGameBean.java
   projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/BlackjackServiceConstants.java
   projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalBlackjackGameIntegrationTest.java
Removed:
   projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/PokerGameLocalBusiness.java
   projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerGameBean.java
   projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerServiceConstants.java
   projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalPokerGameIntegrationTest.java
Modified:
   projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/ejb/DbInitializerBean.java
Log:
[EJBBOOK-23] Update from Poker to Blackjack

Copied: projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/BlackjackGameLocalBusiness.java (from rev 105147, projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/PokerGameLocalBusiness.java)
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/BlackjackGameLocalBusiness.java	                        (rev 0)
+++ projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/BlackjackGameLocalBusiness.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.chxx.transactions.api;
+
+import java.math.BigDecimal;
+
+import org.jboss.ejb3.examples.chxx.transactions.entity.User;
+
+/**
+ * Contract of a service capable of simulating
+ * a single game of blackjack.  The actual gameplay is not modeled,
+ * only the inputs and outputs of a single trial. 
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface BlackjackGameLocalBusiness
+{
+   //-------------------------------------------------------------------------------------||
+   // Constants --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Name to which we'll bind in JNDI
+    */
+   String JNDI_NAME = "PokerGameLocal";
+
+   //-------------------------------------------------------------------------------------||
+   // Contracts --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Places a single bet, returning if the bet won or lost.  If the result 
+    * is a win, the amount specified will be transferred from the Blackjack Service
+    * account to {@link User#getAccount()}, else it will be deducted from the user account
+    * and placed into the Blackjack Service account.
+    *   
+    * @return Whether the bet won or lost
+    * @param userId The ID of the user placing the bet
+    * @param amount The amount of the bet
+    * @throws IllegalArgumentException If either the user of the amount is not specified or
+    *   the amount is a negative number.
+    * @throws InsufficientBalanceException If the user does not have enough in his/her account
+    *       to cover the bet
+    */
+   boolean bet(long userId, BigDecimal amount) throws IllegalArgumentException, InsufficientBalanceException;
+
+}

Deleted: projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/PokerGameLocalBusiness.java
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/PokerGameLocalBusiness.java	2010-05-24 17:50:55 UTC (rev 105155)
+++ projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/api/PokerGameLocalBusiness.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -1,67 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
-  *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.examples.chxx.transactions.api;
-
-import java.math.BigDecimal;
-
-import org.jboss.ejb3.examples.chxx.transactions.entity.User;
-
-/**
- * Contract of a service capable of simulating
- * a single game of poker.  The actual gameplay is not modeled,
- * only the inputs and outputs of a single trial. 
- *
- * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
- * @version $Revision: $
- */
-public interface PokerGameLocalBusiness
-{
-   //-------------------------------------------------------------------------------------||
-   // Constants --------------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Name to which we'll bind in JNDI
-    */
-   String JNDI_NAME = "PokerGameLocal";
-
-   //-------------------------------------------------------------------------------------||
-   // Contracts --------------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Places a single bet, returning if the bet won or lost.  If the result 
-    * is a win, the amount specified will be transferred from the Poker Service
-    * account to {@link User#getAccount()}, else it will be deducted from the user account
-    * and placed into the Poker Service account.
-    *   
-    * @return Whether the bet won or lost
-    * @param userId The ID of the user placing the bet
-    * @param amount The amount of the bet
-    * @throws IllegalArgumentException If either the user of the amount is not specified or
-    *   the amount is a negative number.
-    * @throws InsufficientBalanceException If the user does not have enough in his/her account
-    *       to cover the bet
-    */
-   boolean bet(long userId, BigDecimal amount) throws IllegalArgumentException, InsufficientBalanceException;
-
-}

Copied: projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/BlackjackGameBean.java (from rev 105147, projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerGameBean.java)
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/BlackjackGameBean.java	                        (rev 0)
+++ projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/BlackjackGameBean.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -0,0 +1,141 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.chxx.transactions.impl;
+
+import java.math.BigDecimal;
+
+import javax.ejb.EJB;
+import javax.ejb.Local;
+import javax.ejb.Stateless;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.jboss.ejb3.annotation.LocalBinding;
+import org.jboss.ejb3.examples.chxx.transactions.api.BankLocalBusiness;
+import org.jboss.ejb3.examples.chxx.transactions.api.InsufficientBalanceException;
+import org.jboss.ejb3.examples.chxx.transactions.api.BlackjackGameLocalBusiness;
+import org.jboss.ejb3.examples.chxx.transactions.entity.Account;
+import org.jboss.ejb3.examples.chxx.transactions.entity.User;
+
+/**
+ * Implementation of a service capable of placing single 
+ * bets upon a blackjack game.  Though the gameplay itself is not
+ * modeled, its inputs and outputs are done transactionally.
+ * Each game is to take place in its own Tx, suspending
+ * an existing Tx if one is in play.  This is to ensure
+ * that the output of each game is committed (you win or lose)
+ * regardless of if an error occurrs later within the caller's Tx.
+ * Once your money's on the table, there's no going back! :)
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+ at Stateless
+ at Local(BlackjackGameLocalBusiness.class)
+ at LocalBinding(jndiBinding = BlackjackGameLocalBusiness.JNDI_NAME)
+ at TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
+// Each game must be in a new Tx, suspending the existing enclosing Tx if necessary;
+// At the class-level, this annotation now applied to all methods
+public class BlackjackGameBean implements BlackjackGameLocalBusiness
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Zero value used for comparison
+    */
+   private static final BigDecimal ZERO = new BigDecimal(0);
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Hook to JPA
+    */
+   @PersistenceContext
+   private EntityManager em;
+
+   /**
+    * The bank service which will handle account transfers
+    * during win/lose
+    */
+   @EJB
+   private BankLocalBusiness bank;
+
+   //-------------------------------------------------------------------------------------||
+   // Required Implementations -----------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+   /**
+    * @see org.jboss.ejb3.examples.chxx.transactions.api.BlackjackGameLocalBusiness#bet(long, java.math.BigDecimal)
+    */
+   @Override
+   public boolean bet(final long userId, final BigDecimal amount) throws IllegalArgumentException,
+         InsufficientBalanceException
+   {
+      // Precondition checks
+      if (userId < 0)
+      {
+         throw new IllegalArgumentException("userId must be valid (>0)");
+      }
+      if (amount == null)
+      {
+         throw new IllegalArgumentException("amount must be specified");
+      }
+      if (amount.compareTo(ZERO) < 0)
+      {
+         throw new IllegalArgumentException("amount must be greater than 0");
+      }
+
+      // Check the balance of the user account
+      final Account userAccount = em.find(User.class, new Long(userId)).getAccount();
+      final BigDecimal currentBalanceUserAccount = userAccount.getBalance();
+      if (amount.compareTo(currentBalanceUserAccount) > 0)
+      {
+         throw new InsufficientBalanceException("Cannot place bet of " + amount + " when the user account has only "
+               + currentBalanceUserAccount);
+      }
+
+      // Fake the game logic and just determine if the user wins
+      final boolean win = Math.random() > 0.5;
+
+      // Get the Poker Service account (assume we always have enough to back our bet, these are just tests :))
+      final Account blackjackServiceAccount = em.find(Account.class, BlackjackServiceConstants.ACCOUNT_BLACKJACKGAME_ID);
+
+      // Transfer the money based upon the outcome
+      if (win)
+      {
+         bank.transfer(blackjackServiceAccount, userAccount, amount);
+      }
+      else
+      {
+         bank.transfer(userAccount, blackjackServiceAccount, amount);
+      }
+
+      // Return the outcome
+      return win;
+   }
+}

Copied: projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/BlackjackServiceConstants.java (from rev 105147, projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerServiceConstants.java)
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/BlackjackServiceConstants.java	                        (rev 0)
+++ projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/BlackjackServiceConstants.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.chxx.transactions.impl;
+
+import java.math.BigDecimal;
+
+/**
+ * Constants used by the implementation of the 
+ * {@link BlackjackGameBean}
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public interface BlackjackServiceConstants
+{
+   //-------------------------------------------------------------------------------------||
+   // Constants --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   long USER_BLACKJACKGAME_ID = 1L;
+
+   String USER_BLACKJACKGAME_NAME = "The Blackjack Game System";
+
+   long ACCOUNT_BLACKJACKGAME_ID = 1L;
+
+   BigDecimal INITIAL_ACCOUNT_BALANCE_BLACKJACKGAME = new BigDecimal(10000);
+}

Deleted: projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerGameBean.java
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerGameBean.java	2010-05-24 17:50:55 UTC (rev 105155)
+++ projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerGameBean.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -1,141 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
-  *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.examples.chxx.transactions.impl;
-
-import java.math.BigDecimal;
-
-import javax.ejb.EJB;
-import javax.ejb.Local;
-import javax.ejb.Stateless;
-import javax.ejb.TransactionAttribute;
-import javax.ejb.TransactionAttributeType;
-import javax.persistence.EntityManager;
-import javax.persistence.PersistenceContext;
-
-import org.jboss.ejb3.annotation.LocalBinding;
-import org.jboss.ejb3.examples.chxx.transactions.api.BankLocalBusiness;
-import org.jboss.ejb3.examples.chxx.transactions.api.InsufficientBalanceException;
-import org.jboss.ejb3.examples.chxx.transactions.api.PokerGameLocalBusiness;
-import org.jboss.ejb3.examples.chxx.transactions.entity.Account;
-import org.jboss.ejb3.examples.chxx.transactions.entity.User;
-
-/**
- * Implementation of a service capable of placing single 
- * bets upon a poker game.  Though the gameplay itself is not
- * modeled, its inputs and outputs are done transactionally.
- * Each game is to take place in its own Tx, suspending
- * an existing Tx if one is in play.  This is to ensure
- * that the output of each game is committed (you win or lose)
- * regardless of if an error occurrs later within the caller's Tx.
- * Once your money's on the table, there's no going back! :)
- *
- * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
- * @version $Revision: $
- */
- at Stateless
- at Local(PokerGameLocalBusiness.class)
- at LocalBinding(jndiBinding = PokerGameLocalBusiness.JNDI_NAME)
- at TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
-// Each game must be in a new Tx, suspending the existing enclosing Tx if necessary;
-// At the class-level, this annotation now applied to all methods
-public class PokerGameBean implements PokerGameLocalBusiness
-{
-
-   //-------------------------------------------------------------------------------------||
-   // Class Members ----------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Zero value used for comparison
-    */
-   private static final BigDecimal ZERO = new BigDecimal(0);
-
-   //-------------------------------------------------------------------------------------||
-   // Instance Members -------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Hook to JPA
-    */
-   @PersistenceContext
-   private EntityManager em;
-
-   /**
-    * The bank service which will handle account transfers
-    * during win/lose
-    */
-   @EJB
-   private BankLocalBusiness bank;
-
-   //-------------------------------------------------------------------------------------||
-   // Required Implementations -----------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-   /**
-    * @see org.jboss.ejb3.examples.chxx.transactions.api.PokerGameLocalBusiness#bet(long, java.math.BigDecimal)
-    */
-   @Override
-   public boolean bet(final long userId, final BigDecimal amount) throws IllegalArgumentException,
-         InsufficientBalanceException
-   {
-      // Precondition checks
-      if (userId < 0)
-      {
-         throw new IllegalArgumentException("userId must be valid (>0)");
-      }
-      if (amount == null)
-      {
-         throw new IllegalArgumentException("amount must be specified");
-      }
-      if (amount.compareTo(ZERO) < 0)
-      {
-         throw new IllegalArgumentException("amount must be greater than 0");
-      }
-
-      // Check the balance of the user account
-      final Account userAccount = em.find(User.class, new Long(userId)).getAccount();
-      final BigDecimal currentBalanceUserAccount = userAccount.getBalance();
-      if (amount.compareTo(currentBalanceUserAccount) > 0)
-      {
-         throw new InsufficientBalanceException("Cannot place bet of " + amount + " when the user account has only "
-               + currentBalanceUserAccount);
-      }
-
-      // Fake the game logic and just determine if the user wins
-      final boolean win = Math.random() > 0.5;
-
-      // Get the Poker Service account (assume we always have enough to back our bet, these are just tests :))
-      final Account pokerServiceAccount = em.find(Account.class, PokerServiceConstants.ACCOUNT_POKERGAME_ID);
-
-      // Transfer the money based upon the outcome
-      if (win)
-      {
-         bank.transfer(pokerServiceAccount, userAccount, amount);
-      }
-      else
-      {
-         bank.transfer(userAccount, pokerServiceAccount, amount);
-      }
-
-      // Return the outcome
-      return win;
-   }
-}

Deleted: projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerServiceConstants.java
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerServiceConstants.java	2010-05-24 17:50:55 UTC (rev 105155)
+++ projects/ejb-book/trunk/chxx-poker/src/main/java/org/jboss/ejb3/examples/chxx/transactions/impl/PokerServiceConstants.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
-  *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.examples.chxx.transactions.impl;
-
-import java.math.BigDecimal;
-
-/**
- * Constants used by the implementation of the 
- * {@link PokerGameBean}
- *
- * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
- * @version $Revision: $
- */
-public interface PokerServiceConstants
-{
-   //-------------------------------------------------------------------------------------||
-   // Constants --------------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   long USER_POKERGAME_ID = 1L;
-
-   String USER_POKERGAME_NAME = "The Poker Game System";
-
-   long ACCOUNT_POKERGAME_ID = 1L;
-
-   BigDecimal INITIAL_ACCOUNT_BALANCE_POKERGAME = new BigDecimal(10000);
-}

Copied: projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalBlackjackGameIntegrationTest.java (from rev 105149, projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalPokerGameIntegrationTest.java)
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalBlackjackGameIntegrationTest.java	                        (rev 0)
+++ projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalBlackjackGameIntegrationTest.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -0,0 +1,455 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2010, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+  *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ejb3.examples.chxx.transactions;
+
+import java.math.BigDecimal;
+import java.util.concurrent.Callable;
+import java.util.logging.Logger;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.persistence.EntityManager;
+
+import junit.framework.Assert;
+
+import org.jboss.arquillian.api.Deployment;
+import org.jboss.arquillian.api.Run;
+import org.jboss.arquillian.api.RunModeType;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.ejb3.examples.chxx.transactions.api.BankLocalBusiness;
+import org.jboss.ejb3.examples.chxx.transactions.api.BlackjackGameLocalBusiness;
+import org.jboss.ejb3.examples.chxx.transactions.ejb.DbInitializerBean;
+import org.jboss.ejb3.examples.chxx.transactions.ejb.ExampleUserData;
+import org.jboss.ejb3.examples.chxx.transactions.entity.Account;
+import org.jboss.ejb3.examples.chxx.transactions.entity.User;
+import org.jboss.ejb3.examples.chxx.transactions.impl.BankBean;
+import org.jboss.ejb3.examples.chxx.transactions.impl.BlackjackServiceConstants;
+import org.jboss.ejb3.examples.testsupport.dbinit.DbInitializerLocalBusiness;
+import org.jboss.ejb3.examples.testsupport.dbquery.EntityManagerExposingBean;
+import org.jboss.ejb3.examples.testsupport.dbquery.EntityManagerExposingLocalBusiness;
+import org.jboss.ejb3.examples.testsupport.entity.IdentityBase;
+import org.jboss.ejb3.examples.testsupport.txwrap.ForcedTestException;
+import org.jboss.ejb3.examples.testsupport.txwrap.TaskExecutionException;
+import org.jboss.ejb3.examples.testsupport.txwrap.TxWrappingBean;
+import org.jboss.ejb3.examples.testsupport.txwrap.TxWrappingLocalBusiness;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test cases to ensure that the Blackjack Game
+ * is respecting transactional boundaries at the appropriate
+ * granularity.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+ at RunWith(Arquillian.class)
+ at Run(RunModeType.AS_CLIENT)
+public class TransactionalBlackjackGameIntegrationTest
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Logger
+    */
+   private static final Logger log = Logger.getLogger(TransactionalBlackjackGameIntegrationTest.class.getName());
+
+   /**
+    * Naming Context
+    * @deprecated Remove when Arquillian will inject the EJB proxies
+    */
+   @Deprecated
+   private static Context jndiContext;
+
+   /**
+    * The Deployment into the EJB Container
+    */
+   @Deployment
+   public static JavaArchive getDeployment()
+   {
+      final JavaArchive archive = ShrinkWrap.create("test.jar", JavaArchive.class).addPackages(true,
+            BankLocalBusiness.class.getPackage(), User.class.getPackage()).addManifestResource("persistence.xml")
+            .addPackages(false, DbInitializerBean.class.getPackage(), TxWrappingLocalBusiness.class.getPackage(),
+                  BankBean.class.getPackage(), DbInitializerLocalBusiness.class.getPackage(),
+                  EntityManagerExposingBean.class.getPackage(), IdentityBase.class.getPackage());
+      log.info(archive.toString(true));
+      return archive;
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Instance Members -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Test-only DB initializer to sanitize and prepopulate the DB with each test run
+    */
+   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
+   private DbInitializerLocalBusiness dbInitializer;
+
+   /**
+    * EJB which wraps supplied {@link Callable} instances inside of a new Tx
+    */
+   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
+   private TxWrappingLocalBusiness txWrapper;
+
+   /**
+    * EJB which provides direct access to an {@link EntityManager}'s method for use in testing.
+    * Must be called inside an existing Tx so that returned entities are not detached.
+    */
+   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
+   private EntityManagerExposingLocalBusiness emHook;
+
+   /**
+    * Bank EJB Proxy
+    */
+   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
+   private BankLocalBusiness bank;
+
+   /**
+    * Blackjack Game EJB Proxy
+    */
+   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
+   private BlackjackGameLocalBusiness blackjackGame;
+
+   //-------------------------------------------------------------------------------------||
+   // Lifecycle --------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Performs suite-wide initialization
+    */
+   @BeforeClass
+   public static void init() throws Exception
+   {
+      // After the server is up, we don't need to pass any explicit properties
+      jndiContext = new InitialContext();
+   }
+
+   /**
+    * Manually looks up EJBs in JNDI and assigns them
+    * @deprecated Remove when Arquillian will handle the injection for us
+    */
+   @Deprecated
+   @Before
+   public void injectEjbs() throws Exception
+   {
+      // Fake injection by doing manual lookups for the time being
+      dbInitializer = (DbInitializerLocalBusiness) jndiContext.lookup(DbInitializerBean.class.getSimpleName()
+            + "/local");
+      txWrapper = (TxWrappingLocalBusiness) jndiContext.lookup(TxWrappingBean.class.getSimpleName() + "/local");
+      emHook = (EntityManagerExposingLocalBusiness) jndiContext.lookup(EntityManagerExposingBean.class.getSimpleName()
+            + "/local");
+      bank = (BankLocalBusiness) jndiContext.lookup(BankLocalBusiness.JNDI_NAME);
+      blackjackGame = (BlackjackGameLocalBusiness) jndiContext.lookup(BlackjackGameLocalBusiness.JNDI_NAME);
+   }
+
+   /**
+    * Clears and repopulates the database with test data 
+    * after each run
+    * @throws Exception
+    */
+   @After
+   public void refreshWithDefaultData() throws Exception
+   {
+      dbInitializer.refreshWithDefaultData();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Tests ------------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Ensures that Transfers between accounts obey the ACID properties of Transactions
+    */
+   @Test
+   public void transferRetainsIntegrity() throws Throwable
+   {
+
+      // Init
+      final long alrubingerAccountId = ExampleUserData.ACCOUNT_ALRUBINGER_ID;
+      final long blackjackAccountId = BlackjackServiceConstants.ACCOUNT_BLACKJACKGAME_ID;
+
+      // Ensure there's the expected amounts in both the ALR and Blackjack accounts
+      final BigDecimal expectedinitialALR = ExampleUserData.INITIAL_ACCOUNT_BALANCE_ALR;
+      final BigDecimal expectedinitialBlackjack = BlackjackServiceConstants.INITIAL_ACCOUNT_BALANCE_BLACKJACKGAME;
+      this.executeInTx(new CheckBalanceOfAccountTask(alrubingerAccountId, expectedinitialALR),
+            new CheckBalanceOfAccountTask(blackjackAccountId, expectedinitialBlackjack));
+
+      // Transfer $100 from ALR to Blackjack
+      final BigDecimal oneHundred = new BigDecimal(100);
+      bank.transfer(alrubingerAccountId, blackjackAccountId, oneHundred);
+
+      // Ensure there's $100 less in the ALR account, and $100 more in the blackjack account
+      this.executeInTx(new CheckBalanceOfAccountTask(alrubingerAccountId, expectedinitialALR.subtract(oneHundred)),
+            new CheckBalanceOfAccountTask(blackjackAccountId, expectedinitialBlackjack.add(oneHundred)));
+
+      // Now make a transfer, check it succeeded within the context of a Transaction, then 
+      // intentionally throw an exception.  The Tx should complete as rolled back, 
+      // and the state should be consistent (as if the xfer request never took place).
+      boolean gotExpectedException = false;
+      final Callable<Void> transferTask = new Callable<Void>()
+      {
+         @Override
+         public Void call() throws Exception
+         {
+            bank.transfer(alrubingerAccountId, blackjackAccountId, oneHundred);
+            return null;
+         }
+      };
+      try
+      {
+         this.executeInTx(transferTask, new CheckBalanceOfAccountTask(alrubingerAccountId, expectedinitialALR.subtract(
+               oneHundred).subtract(oneHundred)), new CheckBalanceOfAccountTask(blackjackAccountId, expectedinitialBlackjack
+               .add(oneHundred).add(oneHundred)), ForcedTestExceptionTask.INSTANCE);
+      }
+      // Expected
+      catch (final ForcedTestException fte)
+      {
+         gotExpectedException = true;
+      }
+      Assert.assertTrue("Did not receive expected exception as signaled from the test; was not rolled back",
+            gotExpectedException);
+
+      // Now that we've checked the transfer succeeded from within the Tx, then we threw an
+      // exception before committed, ensure the Tx rolled back and the transfer was reverted from the 
+      // perspective of everyone outside the Tx.
+      this.executeInTx(new CheckBalanceOfAccountTask(alrubingerAccountId, expectedinitialALR.subtract(oneHundred)),
+            new CheckBalanceOfAccountTask(blackjackAccountId, expectedinitialBlackjack.add(oneHundred)));
+   }
+
+   /**
+    * Ensures that when we make a sequence of bets enclosed in a single Tx,
+    * some exceptional condition at the end doesn't roll back the prior
+    * history.  Once we've won/lost a bet, that bet's done.  This tests that 
+    * each bet takes place in its own isolated Tx. 
+    */
+   @Test
+   public void sequenceOfBetsDoesntRollBackAll() throws Throwable
+   {
+      // Get the original balance for ALR; this is done outside a Tx
+      final BigDecimal originalBalance = bank.getBalance(ExampleUserData.ACCOUNT_ALRUBINGER_ID);
+      log.info("Starting balance before playing blackjack: " + originalBalance);
+
+      // Execute 11 bets enclosed in a new Tx, and ensure that the account transfers
+      // took place as expected.  Then throw an exception to rollback the parent Tx.
+      final BigDecimal betAmount = new BigDecimal(20);
+      final Place11BetsThenForceExceptionTask task = new Place11BetsThenForceExceptionTask(betAmount);
+      boolean gotForcedException = false;
+      try
+      {
+         this.executeInTx(task);
+      }
+      catch (final ForcedTestException tfe)
+      {
+         // Expected
+         gotForcedException = true;
+      }
+      Assert.assertTrue("Did not obtain the test exception as expected", gotForcedException);
+
+      // Now we've ensured that from inside the calling Tx we saw the account balances 
+      // were as expected.  But we rolled back that enclosing Tx, so ensure that the outcome
+      // of the games was not ignored
+      final BigDecimal afterBetsBalance = bank.getBalance(ExampleUserData.ACCOUNT_ALRUBINGER_ID);
+      final int gameOutcomeCount = task.gameOutcomeCount;
+      new AssertGameOutcome(originalBalance, afterBetsBalance, gameOutcomeCount, betAmount).call();
+   }
+
+   //-------------------------------------------------------------------------------------||
+   // Internal Helpers -------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * Task which asserts given an account original balance, 
+    * ending balance, game outcome count, and bet amount, that funds 
+    * remaining are as expected.
+    */
+   private static final class AssertGameOutcome implements Callable<Void>
+   {
+      private final BigDecimal originalBalance;
+
+      private final int gameOutcomeCount;
+
+      private final BigDecimal betAmount;
+
+      private final BigDecimal afterBetsBalance;
+
+      AssertGameOutcome(final BigDecimal originalBalance, final BigDecimal afterBetsBalance,
+            final int gameOutcomeCount, final BigDecimal betAmount)
+      {
+         this.originalBalance = originalBalance;
+         this.gameOutcomeCount = gameOutcomeCount;
+         this.betAmount = betAmount;
+         this.afterBetsBalance = afterBetsBalance;
+      }
+
+      @Override
+      public Void call() throws Exception
+      {
+         // Calculate expected
+         final BigDecimal expectedGains = betAmount.multiply(new BigDecimal(gameOutcomeCount));
+         final BigDecimal expectedBalance = originalBalance.add(expectedGains);
+
+         // Assert
+         Assert.assertTrue("Balance after all bets was not as expected " + expectedBalance + " but was "
+               + afterBetsBalance, expectedBalance.compareTo(afterBetsBalance) == 0);
+
+         // Return
+         return null;
+      }
+
+   }
+
+   /**
+    * A task that places 11 bets, then manually throws a {@link ForcedTestException}.
+    * This is so we may check that the balance transfers happened as 
+    * expected from within the context of the Tx in which this task will run, but
+    * also such that we can ensure that even if an exceptional case happens after bets have taken
+    * place, the completed bets do not roll back.  Once the money's on the table, you can't take
+    * it back. ;)
+    */
+   private final class Place11BetsThenForceExceptionTask implements Callable<Void>
+   {
+      /**
+       * Tracks how many games won/lost.  A negative 
+       * number indicates games lost; positive: won.
+       */
+      private int gameOutcomeCount = 0;
+
+      private final BigDecimal betAmount;
+
+      Place11BetsThenForceExceptionTask(final BigDecimal betAmount)
+      {
+         this.betAmount = betAmount;
+      }
+
+      @Override
+      public Void call() throws Exception
+      {
+
+         // Find the starting balance
+         final long alrubingerAccountId = ExampleUserData.ACCOUNT_ALRUBINGER_ID;
+         final BigDecimal startingBalance = bank.getBalance(alrubingerAccountId);
+
+         // Now run 11 bets
+         for (int i = 0; i < 11; i++)
+         {
+            // Track whether we win or lose
+            final boolean win = blackjackGame.bet(ExampleUserData.ACCOUNT_ALRUBINGER_ID, betAmount);
+            gameOutcomeCount += win ? 1 : -1;
+         }
+         log.info("Won " + gameOutcomeCount + " games at " + betAmount + "/game");
+
+         // Get the user's balance after the bets
+         final BigDecimal afterBetsBalance = bank.getBalance(alrubingerAccountId);
+
+         // Ensure that money's been allocated properly
+         new AssertGameOutcome(startingBalance, afterBetsBalance, gameOutcomeCount, betAmount).call();
+
+         // Now force an exception to get a Tx rollback.  This should *not* affect the 
+         // money already transferred during the bets, as they should have taken place
+         // in nested Txs and already committed.
+         throw new ForcedTestException();
+      }
+
+   }
+
+   /**
+    * A task that checks that the account balance of an {@link Account}
+    * with specified ID equals a specified expected value.  Typically to be run 
+    * inside of a Tx via {@link TransactionalBlackjackGameIntegrationTest#executeInTx(Callable...)}.
+    *
+    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+    * @version $Revision: $
+    */
+   private final class CheckBalanceOfAccountTask implements Callable<Void>
+   {
+
+      private long accountId;
+
+      private BigDecimal expectedBalance;
+
+      CheckBalanceOfAccountTask(final long accountId, final BigDecimal expectedBalance)
+      {
+         assert accountId > 0;
+         assert expectedBalance != null;
+         this.accountId = accountId;
+         this.expectedBalance = expectedBalance;
+      }
+
+      @Override
+      public Void call() throws Exception
+      {
+         final Account account = emHook.getEntityManager().find(Account.class, accountId);
+         Assert.assertTrue("Balance was not as expected", expectedBalance.compareTo(account.getBalance()) == 0);
+         return null;
+      }
+
+   }
+
+   /**
+    * Task which throws a {@link TaskExecutionException} for use in testing
+    * for instance to force a Tx Rollback
+    * 
+    *
+    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+    * @version $Revision: $
+    */
+   private enum ForcedTestExceptionTask implements Callable<Void> {
+      INSTANCE;
+
+      @Override
+      public Void call() throws Exception
+      {
+         throw new ForcedTestException();
+      }
+
+   }
+
+   /**
+    * Executes the specified tasks inside of a Tx, courtesy of the 
+    * {@link TxWrappingLocalBusiness} view.
+    */
+   private void executeInTx(final Callable<?>... tasks) throws Throwable
+   {
+      // Precondition checks
+      assert tasks != null : "Tasks must be specified";
+
+      // Execute in a single new Tx, courtesy of the TxWrapping EJB
+      try
+      {
+         txWrapper.wrapInTx(tasks);
+      }
+      catch (final TaskExecutionException tee)
+      {
+         // Unwrap the real cause
+         throw tee.getCause();
+      }
+   }
+}

Deleted: projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalPokerGameIntegrationTest.java
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalPokerGameIntegrationTest.java	2010-05-24 17:50:55 UTC (rev 105155)
+++ projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/TransactionalPokerGameIntegrationTest.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -1,455 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2010, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
-  *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ejb3.examples.chxx.transactions;
-
-import java.math.BigDecimal;
-import java.util.concurrent.Callable;
-import java.util.logging.Logger;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.persistence.EntityManager;
-
-import junit.framework.Assert;
-
-import org.jboss.arquillian.api.Deployment;
-import org.jboss.arquillian.api.Run;
-import org.jboss.arquillian.api.RunModeType;
-import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.ejb3.examples.chxx.transactions.api.BankLocalBusiness;
-import org.jboss.ejb3.examples.chxx.transactions.api.PokerGameLocalBusiness;
-import org.jboss.ejb3.examples.chxx.transactions.ejb.DbInitializerBean;
-import org.jboss.ejb3.examples.chxx.transactions.ejb.ExampleUserData;
-import org.jboss.ejb3.examples.chxx.transactions.entity.Account;
-import org.jboss.ejb3.examples.chxx.transactions.entity.User;
-import org.jboss.ejb3.examples.chxx.transactions.impl.BankBean;
-import org.jboss.ejb3.examples.chxx.transactions.impl.PokerServiceConstants;
-import org.jboss.ejb3.examples.testsupport.dbinit.DbInitializerLocalBusiness;
-import org.jboss.ejb3.examples.testsupport.dbquery.EntityManagerExposingBean;
-import org.jboss.ejb3.examples.testsupport.dbquery.EntityManagerExposingLocalBusiness;
-import org.jboss.ejb3.examples.testsupport.entity.IdentityBase;
-import org.jboss.ejb3.examples.testsupport.txwrap.ForcedTestException;
-import org.jboss.ejb3.examples.testsupport.txwrap.TaskExecutionException;
-import org.jboss.ejb3.examples.testsupport.txwrap.TxWrappingBean;
-import org.jboss.ejb3.examples.testsupport.txwrap.TxWrappingLocalBusiness;
-import org.jboss.shrinkwrap.api.ShrinkWrap;
-import org.jboss.shrinkwrap.api.spec.JavaArchive;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test cases to ensure that the Poker Game
- * is respecting transactional boundaries at the appropriate
- * granularity.
- *
- * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
- * @version $Revision: $
- */
- at RunWith(Arquillian.class)
- at Run(RunModeType.AS_CLIENT)
-public class TransactionalPokerGameIntegrationTest
-{
-
-   //-------------------------------------------------------------------------------------||
-   // Class Members ----------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Logger
-    */
-   private static final Logger log = Logger.getLogger(TransactionalPokerGameIntegrationTest.class.getName());
-
-   /**
-    * Naming Context
-    * @deprecated Remove when Arquillian will inject the EJB proxies
-    */
-   @Deprecated
-   private static Context jndiContext;
-
-   /**
-    * The Deployment into the EJB Container
-    */
-   @Deployment
-   public static JavaArchive getDeployment()
-   {
-      final JavaArchive archive = ShrinkWrap.create("test.jar", JavaArchive.class).addPackages(true,
-            BankLocalBusiness.class.getPackage(), User.class.getPackage()).addManifestResource("persistence.xml")
-            .addPackages(false, DbInitializerBean.class.getPackage(), TxWrappingLocalBusiness.class.getPackage(),
-                  BankBean.class.getPackage(), DbInitializerLocalBusiness.class.getPackage(),
-                  EntityManagerExposingBean.class.getPackage(), IdentityBase.class.getPackage());
-      log.info(archive.toString(true));
-      return archive;
-   }
-
-   //-------------------------------------------------------------------------------------||
-   // Instance Members -------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Test-only DB initializer to sanitize and prepopulate the DB with each test run
-    */
-   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
-   private DbInitializerLocalBusiness dbInitializer;
-
-   /**
-    * EJB which wraps supplied {@link Callable} instances inside of a new Tx
-    */
-   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
-   private TxWrappingLocalBusiness txWrapper;
-
-   /**
-    * EJB which provides direct access to an {@link EntityManager}'s method for use in testing.
-    * Must be called inside an existing Tx so that returned entities are not detached.
-    */
-   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
-   private EntityManagerExposingLocalBusiness emHook;
-
-   /**
-    * Bank EJB Proxy
-    */
-   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
-   private BankLocalBusiness bank;
-
-   /**
-    * Poker Game EJB Proxy
-    */
-   // TODO: Support Injection of @EJB here when Arquillian for Embedded JBossAS will support it
-   private PokerGameLocalBusiness pokerGame;
-
-   //-------------------------------------------------------------------------------------||
-   // Lifecycle --------------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Performs suite-wide initialization
-    */
-   @BeforeClass
-   public static void init() throws Exception
-   {
-      // After the server is up, we don't need to pass any explicit properties
-      jndiContext = new InitialContext();
-   }
-
-   /**
-    * Manually looks up EJBs in JNDI and assigns them
-    * @deprecated Remove when Arquillian will handle the injection for us
-    */
-   @Deprecated
-   @Before
-   public void injectEjbs() throws Exception
-   {
-      // Fake injection by doing manual lookups for the time being
-      dbInitializer = (DbInitializerLocalBusiness) jndiContext.lookup(DbInitializerBean.class.getSimpleName()
-            + "/local");
-      txWrapper = (TxWrappingLocalBusiness) jndiContext.lookup(TxWrappingBean.class.getSimpleName() + "/local");
-      emHook = (EntityManagerExposingLocalBusiness) jndiContext.lookup(EntityManagerExposingBean.class.getSimpleName()
-            + "/local");
-      bank = (BankLocalBusiness) jndiContext.lookup(BankLocalBusiness.JNDI_NAME);
-      pokerGame = (PokerGameLocalBusiness) jndiContext.lookup(PokerGameLocalBusiness.JNDI_NAME);
-   }
-
-   /**
-    * Clears and repopulates the database with test data 
-    * after each run
-    * @throws Exception
-    */
-   @After
-   public void refreshWithDefaultData() throws Exception
-   {
-      dbInitializer.refreshWithDefaultData();
-   }
-
-   //-------------------------------------------------------------------------------------||
-   // Tests ------------------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Ensures that Transfers between accounts obey the ACID properties of Transactions
-    */
-   @Test
-   public void transferRetainsIntegrity() throws Throwable
-   {
-
-      // Init
-      final long alrubingerAccountId = ExampleUserData.ACCOUNT_ALRUBINGER_ID;
-      final long pokerAccountId = PokerServiceConstants.ACCOUNT_POKERGAME_ID;
-
-      // Ensure there's the expected amounts in both the ALR and Poker accounts
-      final BigDecimal expectedinitialALR = ExampleUserData.INITIAL_ACCOUNT_BALANCE_ALR;
-      final BigDecimal expectedinitialPoker = PokerServiceConstants.INITIAL_ACCOUNT_BALANCE_POKERGAME;
-      this.executeInTx(new CheckBalanceOfAccountTask(alrubingerAccountId, expectedinitialALR),
-            new CheckBalanceOfAccountTask(pokerAccountId, expectedinitialPoker));
-
-      // Transfer $100 from ALR to Poker
-      final BigDecimal oneHundred = new BigDecimal(100);
-      bank.transfer(alrubingerAccountId, pokerAccountId, oneHundred);
-
-      // Ensure there's $100 less in the ALR account, and $100 more in the poker account
-      this.executeInTx(new CheckBalanceOfAccountTask(alrubingerAccountId, expectedinitialALR.subtract(oneHundred)),
-            new CheckBalanceOfAccountTask(pokerAccountId, expectedinitialPoker.add(oneHundred)));
-
-      // Now make a transfer, check it succeeded within the context of a Transaction, then 
-      // intentionally throw an exception.  The Tx should complete as rolled back, 
-      // and the state should be consistent (as if the xfer request never took place).
-      boolean gotExpectedException = false;
-      final Callable<Void> transferTask = new Callable<Void>()
-      {
-         @Override
-         public Void call() throws Exception
-         {
-            bank.transfer(alrubingerAccountId, pokerAccountId, oneHundred);
-            return null;
-         }
-      };
-      try
-      {
-         this.executeInTx(transferTask, new CheckBalanceOfAccountTask(alrubingerAccountId, expectedinitialALR.subtract(
-               oneHundred).subtract(oneHundred)), new CheckBalanceOfAccountTask(pokerAccountId, expectedinitialPoker
-               .add(oneHundred).add(oneHundred)), ForcedTestExceptionTask.INSTANCE);
-      }
-      // Expected
-      catch (final ForcedTestException fte)
-      {
-         gotExpectedException = true;
-      }
-      Assert.assertTrue("Did not receive expected exception as signaled from the test; was not rolled back",
-            gotExpectedException);
-
-      // Now that we've checked the transfer succeeded from within the Tx, then we threw an
-      // exception before committed, ensure the Tx rolled back and the transfer was reverted from the 
-      // perspective of everyone outside the Tx.
-      this.executeInTx(new CheckBalanceOfAccountTask(alrubingerAccountId, expectedinitialALR.subtract(oneHundred)),
-            new CheckBalanceOfAccountTask(pokerAccountId, expectedinitialPoker.add(oneHundred)));
-   }
-
-   /**
-    * Ensures that when we make a sequence of bets enclosed in a single Tx,
-    * some exceptional condition at the end doesn't roll back the prior
-    * history.  Once we've won/lost a bet, that bet's done.  This tests that 
-    * each bet takes place in its own isolated Tx. 
-    */
-   @Test
-   public void sequenceOfBetsDoesntRollBackAll() throws Throwable
-   {
-      // Get the original balance for ALR; this is done outside a Tx
-      final BigDecimal originalBalance = bank.getBalance(ExampleUserData.ACCOUNT_ALRUBINGER_ID);
-      log.info("Starting balance before playing poker: " + originalBalance);
-
-      // Execute 11 bets enclosed in a new Tx, and ensure that the account transfers
-      // took place as expected.  Then throw an exception to rollback the parent Tx.
-      final BigDecimal betAmount = new BigDecimal(20);
-      final Place11BetsThenForceExceptionTask task = new Place11BetsThenForceExceptionTask(betAmount);
-      boolean gotForcedException = false;
-      try
-      {
-         this.executeInTx(task);
-      }
-      catch (final ForcedTestException tfe)
-      {
-         // Expected
-         gotForcedException = true;
-      }
-      Assert.assertTrue("Did not obtain the test exception as expected", gotForcedException);
-
-      // Now we've ensured that from inside the calling Tx we saw the account balances 
-      // were as expected.  But we rolled back that enclosing Tx, so ensure that the outcome
-      // of the games was not ignored
-      final BigDecimal afterBetsBalance = bank.getBalance(ExampleUserData.ACCOUNT_ALRUBINGER_ID);
-      final int gameOutcomeCount = task.gameOutcomeCount;
-      new AssertGameOutcome(originalBalance, afterBetsBalance, gameOutcomeCount, betAmount).call();
-   }
-
-   //-------------------------------------------------------------------------------------||
-   // Internal Helpers -------------------------------------------------------------------||
-   //-------------------------------------------------------------------------------------||
-
-   /**
-    * Task which asserts given an account original balance, 
-    * ending balance, game outcome count, and bet amount, that funds 
-    * remaining are as expected.
-    */
-   private static final class AssertGameOutcome implements Callable<Void>
-   {
-      private final BigDecimal originalBalance;
-
-      private final int gameOutcomeCount;
-
-      private final BigDecimal betAmount;
-
-      private final BigDecimal afterBetsBalance;
-
-      AssertGameOutcome(final BigDecimal originalBalance, final BigDecimal afterBetsBalance,
-            final int gameOutcomeCount, final BigDecimal betAmount)
-      {
-         this.originalBalance = originalBalance;
-         this.gameOutcomeCount = gameOutcomeCount;
-         this.betAmount = betAmount;
-         this.afterBetsBalance = afterBetsBalance;
-      }
-
-      @Override
-      public Void call() throws Exception
-      {
-         // Calculate expected
-         final BigDecimal expectedGains = betAmount.multiply(new BigDecimal(gameOutcomeCount));
-         final BigDecimal expectedBalance = originalBalance.add(expectedGains);
-
-         // Assert
-         Assert.assertTrue("Balance after all bets was not as expected " + expectedBalance + " but was "
-               + afterBetsBalance, expectedBalance.compareTo(afterBetsBalance) == 0);
-
-         // Return
-         return null;
-      }
-
-   }
-
-   /**
-    * A task that places 11 bets, then manually throws a {@link ForcedTestException}.
-    * This is so we may check that the balance transfers happened as 
-    * expected from within the context of the Tx in which this task will run, but
-    * also such that we can ensure that even if an exceptional case happens after bets have taken
-    * place, the completed bets do not roll back.  Once the money's on the table, you can't take
-    * it back. ;)
-    */
-   private final class Place11BetsThenForceExceptionTask implements Callable<Void>
-   {
-      /**
-       * Tracks how many games won/lost.  A negative 
-       * number indicates games lost; positive: won.
-       */
-      private int gameOutcomeCount = 0;
-
-      private final BigDecimal betAmount;
-
-      Place11BetsThenForceExceptionTask(final BigDecimal betAmount)
-      {
-         this.betAmount = betAmount;
-      }
-
-      @Override
-      public Void call() throws Exception
-      {
-
-         // Find the starting balance
-         final long alrubingerAccountId = ExampleUserData.ACCOUNT_ALRUBINGER_ID;
-         final BigDecimal startingBalance = bank.getBalance(alrubingerAccountId);
-
-         // Now run 11 bets
-         for (int i = 0; i < 11; i++)
-         {
-            // Track whether we win or lose
-            final boolean win = pokerGame.bet(ExampleUserData.ACCOUNT_ALRUBINGER_ID, betAmount);
-            gameOutcomeCount += win ? 1 : -1;
-         }
-         log.info("Won " + gameOutcomeCount + " games at " + betAmount + "/game");
-
-         // Get the user's balance after the bets
-         final BigDecimal afterBetsBalance = bank.getBalance(alrubingerAccountId);
-
-         // Ensure that money's been allocated properly
-         new AssertGameOutcome(startingBalance, afterBetsBalance, gameOutcomeCount, betAmount).call();
-
-         // Now force an exception to get a Tx rollback.  This should *not* affect the 
-         // money already transferred during the bets, as they should have taken place
-         // in nested Txs and already committed.
-         throw new ForcedTestException();
-      }
-
-   }
-
-   /**
-    * A task that checks that the account balance of an {@link Account}
-    * with specified ID equals a specified expected value.  Typically to be run 
-    * inside of a Tx via {@link TransactionalPokerGameIntegrationTest#executeInTx(Callable...)}.
-    *
-    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
-    * @version $Revision: $
-    */
-   private final class CheckBalanceOfAccountTask implements Callable<Void>
-   {
-
-      private long accountId;
-
-      private BigDecimal expectedBalance;
-
-      CheckBalanceOfAccountTask(final long accountId, final BigDecimal expectedBalance)
-      {
-         assert accountId > 0;
-         assert expectedBalance != null;
-         this.accountId = accountId;
-         this.expectedBalance = expectedBalance;
-      }
-
-      @Override
-      public Void call() throws Exception
-      {
-         final Account account = emHook.getEntityManager().find(Account.class, accountId);
-         Assert.assertTrue("Balance was not as expected", expectedBalance.compareTo(account.getBalance()) == 0);
-         return null;
-      }
-
-   }
-
-   /**
-    * Task which throws a {@link TaskExecutionException} for use in testing
-    * for instance to force a Tx Rollback
-    * 
-    *
-    * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
-    * @version $Revision: $
-    */
-   private enum ForcedTestExceptionTask implements Callable<Void> {
-      INSTANCE;
-
-      @Override
-      public Void call() throws Exception
-      {
-         throw new ForcedTestException();
-      }
-
-   }
-
-   /**
-    * Executes the specified tasks inside of a Tx, courtesy of the 
-    * {@link TxWrappingLocalBusiness} view.
-    */
-   private void executeInTx(final Callable<?>... tasks) throws Throwable
-   {
-      // Precondition checks
-      assert tasks != null : "Tasks must be specified";
-
-      // Execute in a single new Tx, courtesy of the TxWrapping EJB
-      try
-      {
-         txWrapper.wrapInTx(tasks);
-      }
-      catch (final TaskExecutionException tee)
-      {
-         // Unwrap the real cause
-         throw tee.getCause();
-      }
-   }
-}

Modified: projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/ejb/DbInitializerBean.java
===================================================================
--- projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/ejb/DbInitializerBean.java	2010-05-24 17:50:55 UTC (rev 105155)
+++ projects/ejb-book/trunk/chxx-poker/src/test/java/org/jboss/ejb3/examples/chxx/transactions/ejb/DbInitializerBean.java	2010-05-24 18:06:22 UTC (rev 105156)
@@ -31,7 +31,7 @@
 
 import org.jboss.ejb3.examples.chxx.transactions.entity.Account;
 import org.jboss.ejb3.examples.chxx.transactions.entity.User;
-import org.jboss.ejb3.examples.chxx.transactions.impl.PokerServiceConstants;
+import org.jboss.ejb3.examples.chxx.transactions.impl.BlackjackServiceConstants;
 import org.jboss.ejb3.examples.testsupport.dbinit.DbInitializerBeanBase;
 import org.jboss.ejb3.examples.testsupport.dbinit.DbInitializerLocalBusiness;
 
@@ -106,20 +106,20 @@
       alrubinger.setAccount(alrubingerAccount);
 
       // Poker Game Service
-      final User pokerGameService = new User();
-      pokerGameService.setId(PokerServiceConstants.USER_POKERGAME_ID);
-      pokerGameService.setName(PokerServiceConstants.USER_POKERGAME_NAME);
+      final User blackjackGameService = new User();
+      blackjackGameService.setId(BlackjackServiceConstants.USER_BLACKJACKGAME_ID);
+      blackjackGameService.setName(BlackjackServiceConstants.USER_BLACKJACKGAME_NAME);
       final Account pokerGameAccount = new Account();
-      pokerGameAccount.deposit(PokerServiceConstants.INITIAL_ACCOUNT_BALANCE_POKERGAME);
-      pokerGameAccount.setOwner(pokerGameService);
-      pokerGameAccount.setId(PokerServiceConstants.ACCOUNT_POKERGAME_ID);
-      pokerGameService.setAccount(pokerGameAccount);
+      pokerGameAccount.deposit(BlackjackServiceConstants.INITIAL_ACCOUNT_BALANCE_BLACKJACKGAME);
+      pokerGameAccount.setOwner(blackjackGameService);
+      pokerGameAccount.setId(BlackjackServiceConstants.ACCOUNT_BLACKJACKGAME_ID);
+      blackjackGameService.setAccount(pokerGameAccount);
 
       // Persist
       em.persist(alrubinger);
       log.info("Created: " + alrubinger);
-      em.persist(pokerGameService);
-      log.info("Created: " + pokerGameService);
+      em.persist(blackjackGameService);
+      log.info("Created: " + blackjackGameService);
 
    }
 }




More information about the jboss-cvs-commits mailing list