/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat Middleware LLC, and individual contributors as indicated
* by the @authors tag. See the copyright.txt 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.as.test.integration.jpa.epcpropagation;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* For managed debugging:
* -Djboss.options="-Djava.compiler=NONE -agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=y"
* <p/>
* For embedded debugging:
* start AS standalone and attach debugger
* mvn install -Premote
*
* @author <a href="mailto:bdecoste@jboss.com">William DeCoste</a>
* @author Scott Marlow
*/
@RunWith(Arquillian.class)
public class EPCPropagationTestCase {
@Deployment
public static Archive<?> deploy() {
JavaArchive jar = ShrinkWrap.create(JavaArchive.class);
jar.addClasses(
CMTEPCStatefulBean.class, CMTStatefulBean.class, EPCStatefulBean.class,
InitEPCStatefulBean.class, IntermediateStatefulBean.class, IntermediateStatefulInterface.class,
MyEntity.class, NoTxEPCStatefulBean.class, NoTxStatefulBean.class,
StatefulBean.class, StatefulInterface.class, StatelessBean.class,
StatelessInterface.class, AbstractStatefulInterface.class, EPCPropagationTestCase.class
);
jar.addAsManifestResource(EPCPropagationTestCase.class.getPackage(), "persistence.xml", "persistence.xml");
return jar;
}
@ArquillianResource
private InitialContext iniCtx;
protected <T> T lookup(String beanName, Class<T> interfaceType) throws NamingException {
return interfaceType.cast(iniCtx.lookup("java:module/" + beanName + "!" + interfaceType.getName()));
}
@Test
public void testBMTPropagation() throws Exception {
StatelessInterface stateless = lookup("StatelessBean", StatelessInterface.class);
stateless.createEntity(1, "EntityName");
StatefulInterface stateful = lookup("StatefulBean", StatefulInterface.class);
boolean equal = stateful.execute(1, "EntityName");
assertTrue("Name changes should propagate", equal);
}
@Test
public void testBMTEPCPropagation() throws Exception {
StatelessInterface stateless = lookup("StatelessBean", StatelessInterface.class);
stateless.createEntity(2, "EntityName");
StatefulInterface stateful = lookup("EPCStatefulBean", StatefulInterface.class);
boolean equal = stateful.execute(2, "EntityName");
assertTrue("Name changes should propagate", equal);
}
@Test
public void testCMTPropagation() throws Exception {
StatelessInterface stateless = lookup("StatelessBean", StatelessInterface.class);
stateless.createEntity(3, "EntityName");
StatefulInterface stateful = lookup("CMTStatefulBean", StatefulInterface.class);
boolean equal = stateful.execute(3, "EntityName");
assertTrue("Name changes should propagate", equal);
}
@Test
public void testCMTEPCPropagation() throws Exception {
StatelessInterface stateless = lookup("StatelessBean", StatelessInterface.class);
stateless.createEntity(4, "EntityName");
StatefulInterface stateful = lookup("CMTEPCStatefulBean", StatefulInterface.class);
boolean equal = stateful.execute(4, "EntityName");
assertTrue("Name changes should propagate", equal);
}
@Test
public void testNoTxPropagation() throws Exception {
StatelessInterface stateless = lookup("StatelessBean", StatelessInterface.class);
stateless.createEntity(5, "EntityName");
StatefulInterface stateful = lookup("NoTxStatefulBean", StatefulInterface.class);
boolean equal = stateful.execute(5, "EntityName");
assertFalse("Name changes should not propagate", equal);
}
/**
* Ensure that AS7-1663 is fixed, extended persistence context should not be propagated if there is no JTA transaction.
*
* @throws Exception
*/
@Test
public void testNoTxEPCPropagation() throws Exception {
StatelessInterface stateless = lookup("StatelessBean", StatelessInterface.class);
stateless.createEntity(6, "EntityName");
StatefulInterface stateful = lookup("NoTxEPCStatefulBean", StatefulInterface.class);
boolean equal = stateful.execute(6, "EntityName");
assertFalse("Name changes should not propagate (non-tx SFSB XPC shouldn't see SLSB PC changes)", equal);
}
@Test
public void testIntermediateEPCPropagation() throws Exception {
StatelessInterface stateless = lookup("StatelessBean", StatelessInterface.class);
stateless.createEntity(7, "EntityName");
StatefulInterface stateful = lookup("InitEPCStatefulBean", StatefulInterface.class);
boolean equal = stateful.execute(7, "EntityName");
assertTrue("Name changes should propagate", equal);
}
@Test
public void testXPCPostConstruct() throws Exception {
StatefulInterface stateful = lookup("EPCStatefulBean", StatefulInterface.class);
assertNull("stateful postConstruct operation should success: " + stateful.getPostConstructErrorMessage(), stateful.getPostConstructErrorMessage());
}
/**
* JPA 7.6.2 XPC is closed when dependent session bean(s) are closed/destroyed.
* <p>
* During this test, an entity (X) will be created in the XPC but not persisted to the database.
* When the last SFSB referencing the XPC is closed, the entity (X) will no longer be found.
*
* @throws Exception
*/
@Test
public void testNoTxEPCRemoveOperation() throws Exception {
StatefulInterface stateful = lookup("NoTxEPCStatefulBean", StatefulInterface.class);
boolean equal = stateful.createEntity(8, "EntityName Master X");
assertTrue("XPC inheritance should copy entity to other SFSB created on SFSB invocation call", equal);
// stateful should be the only SFSB left
// create another sfsb on the invocation to stateful (should inherit the same XPC used above.
StatefulInterface anotherStateful = stateful.createSFSBOnInvocation();
stateful.finishUp(); // destroy SFSB
stateful = null; // clear reference to avoid using it by accident
// both entities (8,9) should still be in XPC
equal = anotherStateful.createEntity(9, "John Steed");
assertTrue("again, XPC inheritance should copy entity to other SFSB created on SFSB invocation call", equal);
EntityManager xpc = anotherStateful.getExtendedPersistenceContext();
assertTrue("extended persistence context is still open", xpc.isOpen());
anotherStateful.finishUp();
assertFalse("extended persistence context is closed after last referencing SFSB is destroyed", xpc.isOpen());
}
}