Permalink
Browse files

Fixes to test HT across different databases

  • Loading branch information...
1 parent 18d562a commit 9798a443966e6e9fc251f0b3d7db5c78449669b5 @mrietveld mrietveld committed May 22, 2012
@@ -12,6 +12,8 @@
# Test data
/activemq-data
/data
+/settings-db.xml
+/lib-jdbc/
# modules present in master but not here
/jbpm-human-task-core
View
@@ -113,10 +113,56 @@
<artifactId>btm</artifactId>
<scope>test</scope>
</dependency>
+
</dependencies>
+ <properties>
+ <maven.btm.maxPoolSize>16</maven.btm.maxPoolSize>
+
+ <maven.tx.type>RESOURCE_LOCAL</maven.tx.type>
+ <maven.data.source/>
+ <!--
+ <maven.tx.type>JTA</maven.tx.type>
+ <maven.data.source>&lt;jta-data-source&gt;jdbc/taskDS&lt;/jta-data-source&gt;</maven.data.source>
+ -->
+
+ <!-- H2
+ -->
+ <maven.hibernate.dialect>org.hibernate.dialect.H2Dialect</maven.hibernate.dialect>
+ <maven.datasource.classname>bitronix.tm.resource.jdbc.lrc.LrcXADataSource</maven.datasource.classname>
+ <maven.jdbc.driver.class>org.h2.Driver</maven.jdbc.driver.class>
+ <maven.jdbc.db.name/>
+ <maven.jdbc.db.port/>
+ <maven.jdbc.db.server/>
+ <maven.jdbc.username>sa</maven.jdbc.username>
+ <maven.jdbc.password>sasa</maven.jdbc.password>
+ <maven.jdbc.url>jdbc:h2:mem:test;MVCC=true</maven.jdbc.url>
+ <maven.jdbc.schema/>
+ </properties>
+
<build>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <filtering>false</filtering>
+ </testResource>
+ <testResource>
+ <directory>src/test/filtered-resources</directory>
+ <filtering>true</filtering>
+ </testResource>
+ </testResources>
+
<plugins>
+ <!-- human-task requires JDK 6 to run (because of HornetQ dependencies) -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence version="1.0"
+ xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd">
+
+ <persistence-unit name="org.jbpm.task" transaction-type="${maven.tx.type}">
+ <provider>org.hibernate.ejb.HibernatePersistence</provider>
+ ${maven.data.source}
+ <mapping-file>META-INF/Taskorm.xml</mapping-file>
+
+ <class>org.jbpm.task.Attachment</class>
+ <class>org.jbpm.task.Content</class>
+ <class>org.jbpm.task.BooleanExpression</class>
+ <class>org.jbpm.task.Comment</class>
+ <class>org.jbpm.task.Deadline</class>
+ <class>org.jbpm.task.Comment</class>
+ <class>org.jbpm.task.Deadline</class>
+ <class>org.jbpm.task.Delegation</class>
+ <class>org.jbpm.task.Escalation</class>
+ <class>org.jbpm.task.Group</class>
+ <class>org.jbpm.task.I18NText</class>
+ <class>org.jbpm.task.Notification</class>
+ <class>org.jbpm.task.EmailNotification</class>
+ <class>org.jbpm.task.EmailNotificationHeader</class>
+ <class>org.jbpm.task.PeopleAssignments</class>
+ <class>org.jbpm.task.Reassignment</class>
+ <class>org.jbpm.task.Status</class>
+ <class>org.jbpm.task.Task</class>
+ <class>org.jbpm.task.TaskData</class>
+ <class>org.jbpm.task.SubTasksStrategy</class>
+ <class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class>
+ <class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class>
+ <class>org.jbpm.task.User</class>
+ <properties>
+ <property name="hibernate.dialect" value="${maven.hibernate.dialect}"/>
+ <property name="hibernate.connection.driver_class" value="${maven.jdbc.driver.class}"/>
+ <property name="hibernate.connection.url" value="${maven.jdbc.url}" />
+ <property name="hibernate.connection.username" value="${maven.jdbc.username}"/>
+ <property name="hibernate.connection.password" value="${maven.jdbc.password}"/>
+
+ <property name="hibernate.connection.autocommit" value="false" />
+
+ <property name="hibernate.max_fetch_depth" value="3"/>
+ <property name="hibernate.hbm2ddl.auto" value="create-drop" />
+ <property name="hibernate.show_sql" value="false" />
+
+ <!-- needed for JTA testing
+ <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
+ -->
+ </properties>
+ </persistence-unit>
+
+</persistence>
@@ -0,0 +1,20 @@
+maxPoolSize=${maven.btm.maxPoolSize}
+allowLocalTransactions=true
+# JDBC/Database properties that are set in the maven pom
+#
+# the below variable names (i.e. "${maven.datasource.classname}) are
+# automagically replaced with their values (defined in the pom.xml)
+# because of the fact that <filtering> is set to true in for the
+# src/test/resources directory in the pom.
+#
+className=${maven.datasource.classname}
+driverClassName=${maven.jdbc.driver.class}
+user=${maven.jdbc.username}
+password=${maven.jdbc.password}
+url=${maven.jdbc.url}
+serverName=${maven.jdbc.db.server}
+portNumber=${maven.jdbc.db.port}
+databaseName=${maven.jdbc.db.name}
+makeBaseDb=false
+testMarshalling=false
+txType=${maven.tx.type}
@@ -16,9 +16,13 @@
package org.jbpm.task;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.util.Calendar;
import java.util.Date;
+import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@@ -53,14 +57,11 @@
protected TaskServiceSession taskSession;
protected boolean useJTA = false;
- private PoolingDataSource ds;
+ protected static final String DATASOURCE_PROPERTIES = "/datasource.properties";
+ private PoolingDataSource pds;
protected EntityManagerFactory createEntityManagerFactory() {
- if( useJTA ) {
- return Persistence.createEntityManagerFactory("org.jbpm.task.jta");
- } else {
- return Persistence.createEntityManagerFactory("org.jbpm.task");
- }
+ return Persistence.createEntityManagerFactory("org.jbpm.task");
}
protected void setUp() throws Exception {
@@ -72,17 +73,27 @@ protected void setUp() throws Exception {
conf.setProperty("defaultLanguage", "en-UK");
SendIcal.initInstance(conf);
+ Properties dsProps = loadDataSourceProperties();
+ String txType = dsProps.getProperty("txType", "RESOURCE_LOCAL");
+ if( "RESOURCE_LOCAL".equals(txType) ) {
+ useJTA = false;
+ } else if( "JTA".equals(txType) ) {
+ useJTA = true;
+ }
+
if( useJTA ) {
- ds = new PoolingDataSource();
- ds.setUniqueName( "jdbc/taskDS" );
- ds.setClassName( "bitronix.tm.resource.jdbc.lrc.LrcXADataSource" );
- ds.setMaxPoolSize( 3 );
- ds.setAllowLocalTransactions( true );
- ds.getDriverProperties().put( "user", "sa" );
- ds.getDriverProperties().put( "password", "sasa" );
- ds.getDriverProperties().put( "url", "jdbc:h2:mem:test;MVCC=true" );
- ds.getDriverProperties().put( "driverClassName", "org.h2.Driver" );
- ds.init();
+ pds = new PoolingDataSource();
+ pds.setUniqueName( "jdbc/taskDS" );
+ pds.setClassName(dsProps.getProperty("className"));
+ pds.setMaxPoolSize(Integer.parseInt(dsProps.getProperty("maxPoolSize")));
+ pds.setAllowLocalTransactions(Boolean.parseBoolean(dsProps.getProperty("allowLocalTransactions")));
+ for (String propertyName : new String[] { "user", "password" }) {
+ pds.getDriverProperties().put(propertyName, dsProps.getProperty(propertyName));
+ }
+
+ setDatabaseSpecificDataSourceProperties(pds, dsProps);
+
+ pds.init();
}
// Use persistence.xml configuration
@@ -100,12 +111,31 @@ protected void setUp() throws Exception {
taskSession = taskService.createSession();
}
+
+ private Properties loadDataSourceProperties() {
+ String propertiesNotFoundMessage = "Unable to load datasource properties [" + DATASOURCE_PROPERTIES + "]";
+ InputStream propsInputStream = getClass().getResourceAsStream(DATASOURCE_PROPERTIES);
+ assertNotNull(propertiesNotFoundMessage, propsInputStream);
+ Properties dsProps = new Properties();
+ if (propsInputStream != null) {
+ try {
+ dsProps.load(propsInputStream);
+ } catch (IOException ioe) {
+ logger.warn("Unable to find properties, using default H2 properties: " + ioe.getMessage());
+ ioe.printStackTrace();
+ }
+ }
+ return dsProps;
+ }
+
protected void tearDown() throws Exception {
- taskSession.dispose();
+ if( taskSession != null ) {
+ taskSession.dispose();
+ }
emf.close();
if( useJTA ) {
- ds.close();
+ pds.close();
}
}
@@ -156,7 +186,7 @@ public Object eval(String str, Map vars) {
public static Map<String, Object> fillVariables(Map<String, User> users, Map<String, Group> groups ) {
Map <String, Object> vars = new HashMap<String, Object>();
vars.put( "users", users );
- vars.put( "groups", groups );
+ vars.put( "groups", groups );
vars.put( "now", new Date() );
return vars;
}
@@ -182,7 +212,7 @@ else if( deadlineTime == now + 6000 ) {
thirdDeadlineMet = true;
}
else {
- fail( deadlineTime + " is not an expected deadline time. Now is [" + now + "]." );
+ fail( deadlineTime + " is not an expected deadline time. Now is [" + now + " (" + (deadlineTime-now) + ")]." );
}
}
@@ -194,4 +224,47 @@ else if( deadlineTime == now + 6000 ) {
Thread.sleep(1000);
}
+ private void setDatabaseSpecificDataSourceProperties(PoolingDataSource pds, Properties dsProps) {
+ String driverClass = dsProps.getProperty("driverClassName");
+ if (driverClass.startsWith("org.h2")) {
+ for (String propertyName : new String[] { "url", "driverClassName" }) {
+ pds.getDriverProperties().put(propertyName, dsProps.getProperty(propertyName));
+ }
+ } else {
+
+ if (driverClass.startsWith("oracle")) {
+ pds.getDriverProperties().put("driverType", "thin");
+ pds.getDriverProperties().put("URL", dsProps.getProperty("url"));
+ } else if (driverClass.startsWith("com.ibm.db2")) {
+ for (String propertyName : new String[] { "databaseName", "portNumber", "serverName" }) {
+ pds.getDriverProperties().put(propertyName, dsProps.getProperty(propertyName));
+ }
+ pds.getDriverProperties().put("driverType", "4");
+ } else if (driverClass.startsWith("com.microsoft")) {
+ for (String propertyName : new String[] { "serverName", "portNumber", "databaseName" }) {
+ pds.getDriverProperties().put(propertyName, dsProps.getProperty(propertyName));
+ }
+ pds.getDriverProperties().put("URL", dsProps.getProperty("url"));
+ pds.getDriverProperties().put("selectMethod", "cursor");
+ pds.getDriverProperties().put("InstanceName", "MSSQL01");
+ } else if (driverClass.startsWith("com.mysql")) {
+ for (String propertyName : new String[] { "databaseName", "serverName", "portNumber", "url" }) {
+ pds.getDriverProperties().put(propertyName, dsProps.getProperty(propertyName));
+ }
+ } else if (driverClass.startsWith("com.sybase")) {
+ for (String propertyName : new String[] { "databaseName", "portNumber", "serverName" }) {
+ pds.getDriverProperties().put(propertyName, dsProps.getProperty(propertyName));
+ }
+ pds.getDriverProperties().put("REQUEST_HA_SESSION", "false");
+ pds.getDriverProperties().put("networkProtocol", "Tds");
+ } else if (driverClass.startsWith("org.postgresql")) {
+ for (String propertyName : new String[] { "databaseName", "portNumber", "serverName" }) {
+ pds.getDriverProperties().put(propertyName, dsProps.getProperty(propertyName));
+ }
+ } else {
+ throw new RuntimeException("Unknown driver class: " + driverClass);
+ }
+ }
+ }
+
}
@@ -55,6 +55,7 @@ public synchronized void wait(int totalSize, int totalWaitInMillis) throws Excep
long startInMillis = System.currentTimeMillis();
int size = 0;
+ int tries = 0;
while (true) {
synchronized (list) {
size = list.size();
@@ -64,10 +65,14 @@ public synchronized void wait(int totalSize, int totalWaitInMillis) throws Excep
}
long waitInMillis = (System.currentTimeMillis() - startInMillis);
- if (size >= totalSize || waitInMillis >= (totalWaitInMillis)) {
- break;
+ if (waitInMillis >= (totalWaitInMillis)) {
+ if( size >= totalSize ) {
+ break;
+ }
+ }
+ else {
+ Thread.sleep(totalWaitInMillis-waitInMillis);
}
-
}
}
@@ -42,7 +42,8 @@ public void testUnescalatedDeadlines() throws Exception {
taskService.setEscalatedDeadlineHandler( handler );
//Reader reader;
- Reader reader = new InputStreamReader( TaskServiceEscalationBaseUserGroupCallbackTest.class.getResourceAsStream( "../QueryData_UnescalatedDeadlines.mvel" ) );
+ Reader reader = new InputStreamReader(
+ TaskServiceEscalationBaseUserGroupCallbackTest.class.getResourceAsStream( MvelFilePath.UnescalatedDeadlines ));
List<Task> tasks = (List<Task>) eval( reader,
vars );
long now = ((Date)vars.get( "now" )).getTime();
@@ -66,7 +67,8 @@ public void testUnescalatedDeadlinesOnStartup() throws Exception {
Map<String, Object> vars = fillVariables();
//Reader reader;
- Reader reader = new InputStreamReader( TaskServiceEscalationBaseUserGroupCallbackTest.class.getResourceAsStream( "../QueryData_UnescalatedDeadlines.mvel" ) );
+ Reader reader = new InputStreamReader(
+ TaskServiceEscalationBaseUserGroupCallbackTest.class.getResourceAsStream( MvelFilePath.UnescalatedDeadlines ));
List<Task> tasks = (List<Task>) eval( reader,
vars );
long now = ((Date)vars.get( "now" )).getTime();
@@ -1270,7 +1270,20 @@ public void testFailWithContent() {
assertEquals("content", new String(content.getContent()));
}
- // TODO: FIX IT, looks like a persistence problem around persistent bags for local impl
+ /**
+ * The issue here has to do with the fact that hibernate uses lazy initialization.
+ * Actually, what's happening is that one of the collections retrieved isn't retrieved "for update",
+ * so that the proxy collection instance retrieved can't be updated.
+ * (The collection instance can't be updated because hibernate doesn't allowed that unless the collection
+ * has been retrieved "for update" -- which is actually logical.)
+ *
+ * This, of course, only happens when using the LocalTaskService. Why? Because the LocalTaskService
+ * "shares" a persistence context with the client. If I spent another half-hour, I could explain
+ * why that causes this particular problem.
+ * Regardless, I can't stress enough how much that complicates the situation here, and, especially,
+ * why that makes the LocalTaskService a significantly different variant of the TaskService
+ * than the HornetQ, Mina or other transport medium based instances.
+ */
public void FIXME_testRegisterRemove() throws Exception {
Map <String, Object> vars = fillVariables();
Oops, something went wrong.

0 comments on commit 9798a44

Please sign in to comment.