diff --git a/symmetric/pom.xml b/symmetric/pom.xml index 76458cf72d..241746bb6a 100644 --- a/symmetric/pom.xml +++ b/symmetric/pom.xml @@ -497,6 +497,11 @@ net.sourceforge.jtds jtds 1.2.2 + + + hsqldb + hsqldb + 1.8.0.7 diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/SymmetricEngine.java b/symmetric/src/main/java/org/jumpmind/symmetric/SymmetricEngine.java index bfdac4a7be..80624a2f03 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/SymmetricEngine.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/SymmetricEngine.java @@ -72,10 +72,14 @@ public class SymmetricEngine { private IPurgeService purgeService; private boolean started = false; + + private IDbDialect dbDialect; private Properties properties; private static Map registeredEnginesByUrl = new HashMap(); + + private static Map registeredEnginesByName = new HashMap(); /** * @param overridePropertiesResource1 Provide a Spring resource path to a properties file to be used for configuration @@ -126,8 +130,8 @@ private void init(ApplicationContext applicationContext) { registrationService = (IRegistrationService) applicationContext .getBean(Constants.REGISTRATION_SERVICE); purgeService = (IPurgeService) applicationContext - .getBean(Constants.PURGE_SERVICE); - IDbDialect dbDialect = (IDbDialect)applicationContext.getBean(Constants.DB_DIALECT); + .getBean(Constants.PURGE_SERVICE); + dbDialect = (IDbDialect)applicationContext.getBean(Constants.DB_DIALECT); registerEngine(); logger.info("Initialized SymmetricDS externalId=" + runtimeConfig.getExternalId() + " version=" + Version.VERSION + " database="+dbDialect.getName()); } @@ -138,6 +142,7 @@ private void init(ApplicationContext applicationContext) { */ private void registerEngine() { registeredEnginesByUrl.put(runtimeConfig.getMyUrl(), this); + registeredEnginesByName.put(getEngineName(), this); } /** @@ -174,6 +179,18 @@ private void startJobs() { applicationContext.getBean(Constants.SYNC_TRIGGERS_JOB_TIMER); } } + + + /** + * Get a list of configured properties for Symmetric. Read-only. + */ + public Properties getProperties() { + return new Properties(properties); + } + + public String getEngineName() { + return dbDialect.getEngineName(); + } /** * Must be called to start symmetric. @@ -288,5 +305,9 @@ public ApplicationContext getApplicationContext() { public static SymmetricEngine findEngineByUrl(String url) { return registeredEnginesByUrl.get(url); } + + public static SymmetricEngine findEngineByName(String name) { + return registeredEnginesByName.get(name); + } } diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java b/symmetric/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java index 7c84103b1c..36bd8ef1fc 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java @@ -91,6 +91,8 @@ abstract public class AbstractDbDialect implements IDbDialect { private TransactionTemplate transactionTemplate; + private String engineName; + protected AbstractDbDialect() { _defaultSizes = new HashMap(); _defaultSizes.put(new Integer(1), "254"); @@ -740,4 +742,12 @@ public void setTransactionTemplate(TransactionTemplate transactionTemplate) { this.transactionTemplate = transactionTemplate; } + public String getEngineName() { + return engineName; + } + + public void setEngineName(String engineName) { + this.engineName = engineName; + } + } diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/db/DbDialectFactory.java b/symmetric/src/main/java/org/jumpmind/symmetric/db/DbDialectFactory.java index 9efb0662e2..4b717e99d7 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/db/DbDialectFactory.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/db/DbDialectFactory.java @@ -29,6 +29,7 @@ import org.apache.ddlutils.Platform; import org.apache.ddlutils.PlatformFactory; import org.apache.ddlutils.platform.derby.DerbyPlatform; +import org.apache.ddlutils.platform.hsqldb.HsqlDbPlatform; import org.apache.ddlutils.platform.mssql.MSSqlPlatform; import org.apache.ddlutils.platform.mysql.MySqlPlatform; import org.apache.ddlutils.platform.oracle.Oracle10Platform; @@ -79,6 +80,8 @@ public Object getObject() throws Exception { dialect = (AbstractDbDialect) beanFactory.getBean("postgresqlDialect"); } else if (pf instanceof DerbyPlatform) { dialect = (AbstractDbDialect) beanFactory.getBean("derbyDialect"); + } else if (pf instanceof HsqlDbPlatform) { + dialect = (AbstractDbDialect) beanFactory.getBean("hsqldbDialect"); } else { throw new DbNotSupportedException(); } diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/db/IDbDialect.java b/symmetric/src/main/java/org/jumpmind/symmetric/db/IDbDialect.java index d4a9368ef4..350214b420 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/db/IDbDialect.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/db/IDbDialect.java @@ -39,6 +39,11 @@ public void initTrigger(DataEventType dml, Trigger config, @Deprecated public void removeTrigger(String schemaName, String triggerName); + /** + * Get the name of this symmetric instance. This can be set in symmetric.properties using the symmetric.runtime.engine.name property. + */ + public String getEngineName(); + public void removeTrigger(String schemaName, String triggerName, String tableName); public void prepareTableForInserts(Table table); diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/db/SqlTemplate.java b/symmetric/src/main/java/org/jumpmind/symmetric/db/SqlTemplate.java index 3c4d708c89..8d72c95569 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/db/SqlTemplate.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/db/SqlTemplate.java @@ -164,6 +164,7 @@ private String replaceTemplateVariables(IDbDialect dialect, DataEventType dml, T ddl = replace("defaultSchema", defaultSchema != null && defaultSchema.length() > 0 ? defaultSchema + "." : "", ddl); ddl = replace("triggerName", trigger.getTriggerName(dml, triggerPrefix).toUpperCase(), ddl); + ddl = replace("engineName", dialect.getEngineName(), ddl); ddl = replace("prefixName", tablePrefix, ddl); ddl = replace("targetGroupId", trigger.getTargetGroupId(), ddl); ddl = replace("channelName", trigger.getChannelId(), ddl); diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/db/hsqldb/HsqlDbTrigger.java b/symmetric/src/main/java/org/jumpmind/symmetric/db/hsqldb/HsqlDbTrigger.java new file mode 100644 index 0000000000..b24d2a33d7 --- /dev/null +++ b/symmetric/src/main/java/org/jumpmind/symmetric/db/hsqldb/HsqlDbTrigger.java @@ -0,0 +1,36 @@ +/* + * SymmetricDS is an open source database synchronization solution. + * + * Copyright (C) Chris Henson + * + * This library 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 3 of the License, or (at your option) any later version. + * + * This library 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 library; if not, see + * . + */ +package org.jumpmind.symmetric.db.hsqldb; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hsqldb.Trigger; + +public class HsqlDbTrigger implements Trigger { + + static final Log logger = LogFactory.getLog(HsqlDbTrigger.class); + + public void fire(int type, String triggerName, String tableName, Object[] oldRow, + Object[] newRolw) { + logger.info("trigger " + triggerName + " fired for " + tableName); + + } + +} diff --git a/symmetric/src/main/resources/dialects/derby.xml b/symmetric/src/main/resources/dialects/derby.xml index 4e5ad2e25a..3900914720 100644 --- a/symmetric/src/main/resources/dialects/derby.xml +++ b/symmetric/src/main/resources/dialects/derby.xml @@ -8,7 +8,8 @@ - + + diff --git a/symmetric/src/main/resources/dialects/hsqldb.xml b/symmetric/src/main/resources/dialects/hsqldb.xml new file mode 100644 index 0000000000..0a7126698d --- /dev/null +++ b/symmetric/src/main/resources/dialects/hsqldb.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/symmetric/src/main/resources/dialects/mssql.xml b/symmetric/src/main/resources/dialects/mssql.xml index 903b231fd7..a03ddec620 100644 --- a/symmetric/src/main/resources/dialects/mssql.xml +++ b/symmetric/src/main/resources/dialects/mssql.xml @@ -17,7 +17,8 @@ - + + diff --git a/symmetric/src/main/resources/dialects/mysql.xml b/symmetric/src/main/resources/dialects/mysql.xml index a64686164a..7256ac9f8e 100644 --- a/symmetric/src/main/resources/dialects/mysql.xml +++ b/symmetric/src/main/resources/dialects/mysql.xml @@ -17,6 +17,7 @@ + @@ -74,7 +75,6 @@ - diff --git a/symmetric/src/main/resources/dialects/oracle.xml b/symmetric/src/main/resources/dialects/oracle.xml index d6ceeae2e3..2dcadbba92 100644 --- a/symmetric/src/main/resources/dialects/oracle.xml +++ b/symmetric/src/main/resources/dialects/oracle.xml @@ -9,6 +9,7 @@ + diff --git a/symmetric/src/main/resources/dialects/postgresql.xml b/symmetric/src/main/resources/dialects/postgresql.xml index b7151a99e1..2175acd4b0 100644 --- a/symmetric/src/main/resources/dialects/postgresql.xml +++ b/symmetric/src/main/resources/dialects/postgresql.xml @@ -9,6 +9,7 @@ + diff --git a/symmetric/src/main/resources/symmetric-default.properties b/symmetric/src/main/resources/symmetric-default.properties index 4409bbaa53..edf3cd7c58 100644 --- a/symmetric/src/main/resources/symmetric-default.properties +++ b/symmetric/src/main/resources/symmetric-default.properties @@ -68,7 +68,7 @@ symmetric.runtime.outgoing.batches.max.to.process=60 symmetric.runtime.incoming.batches.skip.duplicates=true # This is the engine name. This should be set if you have more than one engine running in the same JVM. -# It is used to name the JMX management bean. +# It is used to name the JMX management bean. Please do not use underscores in this name. symmetric.runtime.engine.name=Default # Set this if you want to give your server a unique name to be used to identify which server did what action. Typically useful when running in diff --git a/symmetric/src/main/resources/symmetric-dialects.xml b/symmetric/src/main/resources/symmetric-dialects.xml index d904100daf..7cf40ec8af 100644 --- a/symmetric/src/main/resources/symmetric-dialects.xml +++ b/symmetric/src/main/resources/symmetric-dialects.xml @@ -11,6 +11,7 @@ - + + \ No newline at end of file diff --git a/symmetric/src/test/java/org/jumpmind/symmetric/AbstractTest.java b/symmetric/src/test/java/org/jumpmind/symmetric/AbstractTest.java index 7d381ba3fd..0d2387f328 100644 --- a/symmetric/src/test/java/org/jumpmind/symmetric/AbstractTest.java +++ b/symmetric/src/test/java/org/jumpmind/symmetric/AbstractTest.java @@ -7,6 +7,8 @@ import javax.sql.DataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.ddlutils.Platform; import org.apache.ddlutils.io.DatabaseIO; import org.apache.ddlutils.model.Database; @@ -16,9 +18,20 @@ import org.jumpmind.symmetric.db.SqlScript; abstract public class AbstractTest { - + + static final Log logger = LogFactory.getLog(AbstractTest.class); + protected SymmetricEngine createEngine(File propertiesFile) { - return new SymmetricEngine("file:" + propertiesFile.getAbsolutePath(), null); + try { + return new SymmetricEngine("file:" + + propertiesFile.getAbsolutePath(), null); + } catch (RuntimeException ex) { + logger.error(ex, ex); + throw ex; + } catch (Exception ex) { + logger.error(ex, ex); + throw new RuntimeException(ex); + } } protected void dropAndCreateDatabaseTables(String databaseType, SymmetricEngine engine) { diff --git a/symmetric/src/test/java/org/jumpmind/symmetric/IntegrationTest.java b/symmetric/src/test/java/org/jumpmind/symmetric/IntegrationTest.java index 355737ca54..d2e09f2a67 100644 --- a/symmetric/src/test/java/org/jumpmind/symmetric/IntegrationTest.java +++ b/symmetric/src/test/java/org/jumpmind/symmetric/IntegrationTest.java @@ -45,36 +45,52 @@ public class IntegrationTest extends AbstractIntegrationTest implements ITest { static final byte[] BINARY_DATA = new byte[] { 0x01, 0x02, 0x03 }; public String getTestName() { - return "Test from " + getRootDatabaseName() + " to " + getClientDatabaseName(); + try { + return "Test from " + getRootDatabaseName() + " to " + + getClientDatabaseName(); + } catch (RuntimeException ex) { + logger.error(ex, ex); + throw ex; + } } @Test(testName = "Integration Test", groups = "continuous", timeOut = 60000) - public void testLifecycle() throws Exception { - init(); - register(); - testSyncToClient(); - testSyncToRootAutoGeneratedPrimaryKey(); - testSyncToRoot(); - testSyncInsertCondition(); - testSyncUpdateCondition(); - testIgnoreNodeChannel(); - testPurge(); - testHeartbeat(); + public void testLifecycle() { + try { + init(); + register(); + testSyncToClient(); + testSyncToRootAutoGeneratedPrimaryKey(); + testSyncToRoot(); + testSyncInsertCondition(); + testSyncUpdateCondition(); + testIgnoreNodeChannel(); + testPurge(); + testHeartbeat(); + } catch (Exception ex) { + logger.error(ex, ex); + Assert.fail(); + } } protected void init() { BeanFactory rootBeanFactory = getRootEngine().getApplicationContext(); - rootJdbcTemplate = new JdbcTemplate((DataSource) rootBeanFactory.getBean(Constants.DATA_SOURCE)); + rootJdbcTemplate = new JdbcTemplate((DataSource) rootBeanFactory + .getBean(Constants.DATA_SOURCE)); - BeanFactory clientBeanFactory = getClientEngine().getApplicationContext(); - clientJdbcTemplate = new JdbcTemplate((DataSource) clientBeanFactory.getBean(Constants.DATA_SOURCE)); + BeanFactory clientBeanFactory = getClientEngine() + .getApplicationContext(); + clientJdbcTemplate = new JdbcTemplate((DataSource) clientBeanFactory + .getBean(Constants.DATA_SOURCE)); } protected void register() { - getRootEngine().openRegistration(TestConstants.TEST_CLIENT_NODE_GROUP, TestConstants.TEST_CLIENT_EXTERNAL_ID); + getRootEngine().openRegistration(TestConstants.TEST_CLIENT_NODE_GROUP, + TestConstants.TEST_CLIENT_EXTERNAL_ID); getClientEngine().start(); - Assert.assertTrue(getClientEngine().isRegistered(), "The client did not register."); + Assert.assertTrue(getClientEngine().isRegistered(), + "The client did not register."); } protected void testSyncToClient() { @@ -82,95 +98,145 @@ protected void testSyncToClient() { getClientEngine().pull(); // now change some data that should be sync'd - rootJdbcTemplate.update(insertCustomerSql, new Object[] { 101, "Charlie Brown", "1", "300 Grub Street", - "New Yorl", "NY", 90009, new Date(), "This is a test", BINARY_DATA }); + rootJdbcTemplate.update(insertCustomerSql, new Object[] { 101, + "Charlie Brown", "1", "300 Grub Street", "New Yorl", "NY", + 90009, new Date(), "This is a test", BINARY_DATA }); getClientEngine().pull(); - Assert.assertEquals(clientJdbcTemplate.queryForInt("select count(*) from test_customer where customer_id=101"), - 1, "The customer was not sync'd to the client."); + Assert + .assertEquals( + clientJdbcTemplate + .queryForInt("select count(*) from test_customer where customer_id=101"), + 1, "The customer was not sync'd to the client."); if (getRootDbDialect().isClobSyncSupported()) { - Assert.assertEquals(clientJdbcTemplate.queryForObject( - "select notes from test_customer where customer_id=101", String.class), "This is a test", - "The CLOB notes field on customer was not sync'd to the client."); + Assert + .assertEquals( + clientJdbcTemplate + .queryForObject( + "select notes from test_customer where customer_id=101", + String.class), "This is a test", + "The CLOB notes field on customer was not sync'd to the client."); } if (getRootDbDialect().isBlobSyncSupported()) { - Assert.assertTrue(ArrayUtils.isEquals(clientJdbcTemplate.queryForObject( - "select icon from test_customer where customer_id=101", byte[].class), BINARY_DATA), - "The BLOB icon field on customer was not sync'd to the client."); + Assert + .assertTrue( + ArrayUtils + .isEquals( + clientJdbcTemplate + .queryForObject( + "select icon from test_customer where customer_id=101", + byte[].class), + BINARY_DATA), + "The BLOB icon field on customer was not sync'd to the client."); } } protected void testSyncToRootAutoGeneratedPrimaryKey() { final String NEW_VALUE = "unique new value one value"; - clientJdbcTemplate.update(insertTestTriggerTableSql, new Object[] { "value one", "value \" two" }); + clientJdbcTemplate.update(insertTestTriggerTableSql, new Object[] { + "value one", "value \" two" }); getClientEngine().push(); - clientJdbcTemplate.update(updateTestTriggerTableSql, new Object[] { NEW_VALUE }); + clientJdbcTemplate.update(updateTestTriggerTableSql, + new Object[] { NEW_VALUE }); getClientEngine().push(); - Assert.assertEquals(rootJdbcTemplate.queryForInt( - "select count(*) from test_triggers_table where string_one_value=?", new Object[] { NEW_VALUE }), 1, - "The update on test_triggers_table did not work."); + Assert + .assertEquals( + rootJdbcTemplate + .queryForInt( + "select count(*) from test_triggers_table where string_one_value=?", + new Object[] { NEW_VALUE }), 1, + "The update on test_triggers_table did not work."); } protected void testSyncToRoot() throws ParseException { - Date date = DateUtils.parseDate("2007-01-03", new String[] { "yyyy-MM-dd" }); - clientJdbcTemplate.update(insertOrderHeaderSql, new Object[] { "10", 100, null, date }, new int[] {Types.VARCHAR, Types.INTEGER, Types.CHAR, Types.DATE}); - clientJdbcTemplate.update(insertOrderDetailSql, new Object[] { "10", 1, "STK", "110000065", 3, 3.33 }); + Date date = DateUtils.parseDate("2007-01-03", + new String[] { "yyyy-MM-dd" }); + clientJdbcTemplate.update(insertOrderHeaderSql, new Object[] { "10", + 100, null, date }, new int[] { Types.VARCHAR, Types.INTEGER, + Types.CHAR, Types.DATE }); + clientJdbcTemplate.update(insertOrderDetailSql, new Object[] { "10", 1, + "STK", "110000065", 3, 3.33 }); getClientEngine().push(); } protected void testSyncInsertCondition() throws ParseException { // Should not sync when status = null - Date date = DateUtils.parseDate("2007-01-02", new String[] { "yyyy-MM-dd" }); - rootJdbcTemplate.update(insertOrderHeaderSql, new Object[] { "11", 100, null, date }, new int[] {Types.VARCHAR, Types.INTEGER, Types.CHAR, Types.DATE}); + Date date = DateUtils.parseDate("2007-01-02", + new String[] { "yyyy-MM-dd" }); + rootJdbcTemplate.update(insertOrderHeaderSql, new Object[] { "11", 100, + null, date }, new int[] { Types.VARCHAR, Types.INTEGER, + Types.CHAR, Types.DATE }); getClientEngine().pull(); - IOutgoingBatchService outgoingBatchService = (IOutgoingBatchService) getRootEngine().getApplicationContext() - .getBean(Constants.OUTGOING_BATCH_SERVICE); - List batches = outgoingBatchService.getOutgoingBatches(TestConstants.TEST_CLIENT_EXTERNAL_ID); - Assert.assertEquals(batches.size(), 0, "There should be no outgoing batches, yet I found some."); + IOutgoingBatchService outgoingBatchService = (IOutgoingBatchService) getRootEngine() + .getApplicationContext().getBean( + Constants.OUTGOING_BATCH_SERVICE); + List batches = outgoingBatchService + .getOutgoingBatches(TestConstants.TEST_CLIENT_EXTERNAL_ID); + Assert.assertEquals(batches.size(), 0, + "There should be no outgoing batches, yet I found some."); - Assert.assertEquals(clientJdbcTemplate.queryForList(selectOrderHeaderSql, new Object[] { "11" }).size(), 0, + Assert.assertEquals(clientJdbcTemplate.queryForList( + selectOrderHeaderSql, new Object[] { "11" }).size(), 0, "The order record was sync'd when it should not have been."); // Should sync when status = C - rootJdbcTemplate.update(insertOrderHeaderSql, new Object[] { "12", 100, "C", date }, new int[] {Types.VARCHAR, Types.INTEGER, Types.CHAR, Types.DATE}); + rootJdbcTemplate.update(insertOrderHeaderSql, new Object[] { "12", 100, + "C", date }, new int[] { Types.VARCHAR, Types.INTEGER, + Types.CHAR, Types.DATE }); getClientEngine().pull(); - Assert.assertEquals(clientJdbcTemplate.queryForList(selectOrderHeaderSql, new Object[] { "12" }).size(), 1, + Assert.assertEquals(clientJdbcTemplate.queryForList( + selectOrderHeaderSql, new Object[] { "12" }).size(), 1, "The order record was not sync'd when it should have been."); // TODO: make sure event did not fire } @SuppressWarnings("unchecked") protected void testSyncUpdateCondition() { - rootJdbcTemplate.update(updateOrderHeaderStatusSql, new Object[] { null, "1" }); + rootJdbcTemplate.update(updateOrderHeaderStatusSql, new Object[] { + null, "1" }); getClientEngine().pull(); - Assert.assertEquals(clientJdbcTemplate.queryForList(selectOrderHeaderSql, new Object[] { "1" }).size(), 0, + Assert.assertEquals(clientJdbcTemplate.queryForList( + selectOrderHeaderSql, new Object[] { "1" }).size(), 0, "The order record was sync'd when it should not have been."); - rootJdbcTemplate.update(updateOrderHeaderStatusSql, new Object[] { "C", "1" }); + rootJdbcTemplate.update(updateOrderHeaderStatusSql, new Object[] { "C", + "1" }); getClientEngine().pull(); - List list = clientJdbcTemplate.queryForList(selectOrderHeaderSql, new Object[] { "1" }); + List list = clientJdbcTemplate.queryForList(selectOrderHeaderSql, + new Object[] { "1" }); Assert.assertEquals(list.size(), 1, "The order record should exist."); Map map = (Map) list.get(0); - Assert.assertEquals(map.get("status"), "C", "Status should be complete"); + Assert + .assertEquals(map.get("status"), "C", + "Status should be complete"); // TODO: make sure event did not fire } @SuppressWarnings("unchecked") protected void testIgnoreNodeChannel() { - INodeService nodeService = (INodeService) getRootEngine().getApplicationContext().getBean("nodeService"); - nodeService.ignoreNodeChannelForExternalId(true, TestConstants.TEST_CHANNEL_ID, - TestConstants.TEST_ROOT_NODE_GROUP, TestConstants.TEST_ROOT_EXTERNAL_ID); - rootJdbcTemplate.update(insertCustomerSql, new Object[] { 201, "Charlie Dude", "1", "300 Grub Street", - "New Yorl", "NY", 90009, new Date(), "This is a test", BINARY_DATA }); + INodeService nodeService = (INodeService) getRootEngine() + .getApplicationContext().getBean("nodeService"); + nodeService.ignoreNodeChannelForExternalId(true, + TestConstants.TEST_CHANNEL_ID, + TestConstants.TEST_ROOT_NODE_GROUP, + TestConstants.TEST_ROOT_EXTERNAL_ID); + rootJdbcTemplate.update(insertCustomerSql, new Object[] { 201, + "Charlie Dude", "1", "300 Grub Street", "New Yorl", "NY", + 90009, new Date(), "This is a test", BINARY_DATA }); getClientEngine().pull(); - Assert.assertEquals(clientJdbcTemplate.queryForInt("select count(*) from test_customer where customer_id=201"), - 0, "The customer was sync'd to the client."); - nodeService.ignoreNodeChannelForExternalId(false, TestConstants.TEST_CHANNEL_ID, - TestConstants.TEST_ROOT_NODE_GROUP, TestConstants.TEST_ROOT_EXTERNAL_ID); + Assert + .assertEquals( + clientJdbcTemplate + .queryForInt("select count(*) from test_customer where customer_id=201"), + 0, "The customer was sync'd to the client."); + nodeService.ignoreNodeChannelForExternalId(false, + TestConstants.TEST_CHANNEL_ID, + TestConstants.TEST_ROOT_NODE_GROUP, + TestConstants.TEST_ROOT_EXTERNAL_ID); } @@ -178,10 +244,13 @@ protected void testPurge() throws Exception { Thread.sleep(1000); getRootEngine().purge(); getClientEngine().purge(); - Assert.assertEquals(rootJdbcTemplate.queryForInt("select count(*) from " + TestConstants.TEST_PREFIX + "data"), - 0, "Expected all data rows to have been purged."); + Assert.assertEquals(rootJdbcTemplate + .queryForInt("select count(*) from " + + TestConstants.TEST_PREFIX + "data"), 0, + "Expected all data rows to have been purged."); Assert.assertEquals(clientJdbcTemplate - .queryForInt("select count(*) from " + TestConstants.TEST_PREFIX + "data"), 0, + .queryForInt("select count(*) from " + + TestConstants.TEST_PREFIX + "data"), 0, "Expected all data rows to have been purged."); } @@ -191,8 +260,11 @@ protected void testHeartbeat() throws Exception { Thread.sleep(1000); getClientEngine().heartbeat(); getClientEngine().push(); - Date time = (Date) rootJdbcTemplate.queryForObject("select heartbeat_time from " + TestConstants.TEST_PREFIX - + "node where external_id='" + TestConstants.TEST_CLIENT_EXTERNAL_ID + "'", Timestamp.class); + Date time = (Date) rootJdbcTemplate.queryForObject( + "select heartbeat_time from " + TestConstants.TEST_PREFIX + + "node where external_id='" + + TestConstants.TEST_CLIENT_EXTERNAL_ID + "'", + Timestamp.class); Assert.assertTrue(time != null && time.getTime() > ts, "The client node was not sync'd to the root as expected."); } diff --git a/symmetric/src/test/java/org/jumpmind/symmetric/MultiDatabaseTestFactory.java b/symmetric/src/test/java/org/jumpmind/symmetric/MultiDatabaseTestFactory.java index c49905c273..2f88cae56d 100644 --- a/symmetric/src/test/java/org/jumpmind/symmetric/MultiDatabaseTestFactory.java +++ b/symmetric/src/test/java/org/jumpmind/symmetric/MultiDatabaseTestFactory.java @@ -168,6 +168,7 @@ protected static File writeTempPropertiesFileFor(String databaseType, DatabaseRo newProperties.setProperty("symmetric.runtime.registration.url", databaseRole == DatabaseRole.CLIENT ? ("internal://" + DatabaseRole.ROOT.name().toLowerCase()) : ""); + newProperties.setProperty("symmetric.runtime.engine.name", databaseRole.name().toLowerCase()); File propertiesFile = File.createTempFile("symmetric-test.", ".properties"); FileOutputStream os = new FileOutputStream(propertiesFile); diff --git a/symmetric/src/test/resources/symmetric-test.properties b/symmetric/src/test/resources/symmetric-test.properties index 1a0fd3ae34..600006a037 100644 --- a/symmetric/src/test/resources/symmetric-test.properties +++ b/symmetric/src/test/resources/symmetric-test.properties @@ -1,5 +1,5 @@ -test.root=mysql -test.client=mysql +test.root=hsqldb +test.client=hsqldb mysql.db.driver=com.mysql.jdbc.Driver mysql.db.user=root @@ -13,6 +13,13 @@ derby.db.driver=org.apache.derby.jdbc.EmbeddedDriver derby.db.user= derby.db.password= +hsqldb.db.driver=org.hsqldb.jdbcDriver +hsqldb.db.user=sa +hsqldb.db.password= + +hsqldb.client.db.url=jdbc:hsqldb:file:target/hsqldb/client;shutdown=true +hsqldb.root.db.url=jdbc:hsqldb:file:target/hsqldb/root;shutdown=true + derby.client.db.url=jdbc:derby:target/derby/client;create=true derby.root.db.url=jdbc:derby:target/derby/root;create=true