package org.jboss.jca.adapters.sap.integration; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.logging.Logger; import javax.annotation.Resource; import javax.resource.cci.Interaction; import javax.resource.cci.MappedRecord; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.jca.adapters.sap.cci.CciFactory; import org.jboss.jca.adapters.sap.cci.Connection; import org.jboss.jca.adapters.sap.cci.InteractionSpec; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.ResourceAdapterArchive; import org.junit.Test; import org.junit.runner.RunWith; /** * StatefulCallTests - Tests stateful calls of RFC Function Modules through JBoss SAP JCA Connector * * @author William Collins * */ @RunWith(Arquillian.class) public class ITestStatefulCall { private static Logger log = Logger.getLogger("StatefulCollTests"); private static String deploymentName = "StatfullCallTests"; private static int threadCount = 5; private static int incrementNum = 3; /** * Define the deployment * * @return The deployment archive */ @Deployment public static ResourceAdapterArchive createDeployment() { log.info("Creating deployment for StatefulCallTests"); ResourceAdapterArchive raa = ShrinkWrap.create(ResourceAdapterArchive.class, deploymentName + ".rar"); // JavaArchive ja = ShrinkWrap.create(JavaArchive.class, UUID.randomUUID().toString() + ".jar"); // ja.addClasses(CLASSES_TO_TEST); // raa.addAsLibrary(ja); raa.addAsManifestResource("META-INF/ra.xml", "ra.xml"); raa.addAsManifestResource("META-INF/DefaultTests-ironjacamar.xml", "ironjacamar.xml"); return raa; } @Resource(mappedName = "java:/eis/DefaultTestsFactory") private javax.resource.cci.ConnectionFactory connectionFactory; /** * A Callable Task that makes stateful calls to SAP to increment the global variable of a function module. */ private Callable<Integer> incrementTestTask = new Callable<Integer>() { /** * Makes sequence of stateful calls to <code>ZJBOSS_INCREMENT_COUNTER</code> and returns the value returned by * <code>ZJBOSS_GET_COUNTER</code> at end of call sequence. */ @Override public Integer call() throws Exception { Connection connection = null; try { log.info("Testing Stateful Call Sequence"); assertNotNull("Failed to access connection factory 'CciTestsFactory'", connectionFactory); connection = (Connection) connectionFactory.getConnection(); assertNotNull("Failed to create connection", connection); connection.ping(); // // Create interaction to invoke ZJBOSS_INCREMENT_COUNTER function module. // Interaction interaction = connection.createInteraction(); InteractionSpec incrementCounter = CciFactory.INSTANCE.createInteractionSpec(); incrementCounter.setFunctionName("ZJBOSS_INCREMENT_COUNTER"); InteractionSpec getCounter = CciFactory.INSTANCE.createInteractionSpec(); getCounter.setFunctionName("ZJBOSS_GET_COUNTER"); // // Create input record to pass parameters to function module. // MappedRecord input = connectionFactory.getRecordFactory().createMappedRecord("ZJBOSS_INCREMENT_COUNTER.INPUT_RECORD"); MappedRecord output = connectionFactory.getRecordFactory().createMappedRecord("ZJBOSS_INCREMENT_COUNTER.OUTPUT_RECORD"); // Start stateful sequence and execute interaction multiple times. connection.begin(); for (int i = 0; i < incrementNum; i++) { assertTrue("ZJBOSS_INCREMENT_COUNTER failed", interaction.execute(incrementCounter, input, output)); } input = connectionFactory.getRecordFactory().createMappedRecord("ZJBOSS_GET_COUNTER.INPUT_RECORD"); output = connectionFactory.getRecordFactory().createMappedRecord("ZJBOSS_GET_COUNTER.OUTPUT_RECORD"); assertTrue("ZJBOSS_GET_COUNTER failed", interaction.execute(getCounter, input, output)); return (Integer) output.get("GET_VALUE"); } finally { if (connection != null) { connection.end(); connection.close(); } } } }; /** * Tests Stateful Call sequence in concurrent threads. * * @throws Throwable * Thrown in case of a test error. */ @Test public void testStatefulCallSequences() throws Throwable { List<Callable<Integer>> tasks = Collections.nCopies(threadCount, incrementTestTask); ExecutorService executorService = Executors.newFixedThreadPool(threadCount); List<Future<Integer>> futures = executorService.invokeAll(tasks); for (Future<Integer> future : futures) { int incrementedValue = future.get().intValue(); assertEquals("Incremented value '" + incrementedValue + "' does not match expected value '" + incrementNum + "'", incrementedValue, incrementNum); } } }