From 95b49d46ef3dea518639e7eb3efd1835e34411d3 Mon Sep 17 00:00:00 2001 From: chenson42 Date: Sun, 30 Sep 2007 15:17:37 +0000 Subject: [PATCH] Added heartbeat unit test. --- .../jumpmind/symmetric/SymmetricEngine.java | 4 + .../symmetric/db/AbstractDbDialect.java | 6 +- .../symmetric/db/oracle/OracleDbDialect.java | 104 ++++++++++-------- .../service/impl/BootstrapService.java | 6 +- .../jumpmind/symmetric/IntegrationTest.java | 10 ++ 5 files changed, 75 insertions(+), 55 deletions(-) diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/SymmetricEngine.java b/symmetric/src/main/java/org/jumpmind/symmetric/SymmetricEngine.java index b1ed5215bf..3c05882698 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/SymmetricEngine.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/SymmetricEngine.java @@ -169,6 +169,10 @@ public void purge() { "Cannot actuate a purge if it is already scheduled."); } } + + public void heartbeat() { + bootstrapService.heartbeat(); + } public void openRegistration(String domainName, String domainId) { registrationService.openRegistration(domainName, domainId); 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 f28616c87a..d3f6f30686 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/db/AbstractDbDialect.java @@ -297,9 +297,11 @@ protected String readPrimaryKeyName(DatabaseMetaDataWrapper metaData, return (String) values.get("COLUMN_NAME"); } - public void initTrigger(DataEventType dml, Trigger config, + public void initTrigger(DataEventType dml, Trigger trigger, TriggerHistory audit, String tablePrefix, Table table) { - jdbcTemplate.update(createTriggerDDL(dml, config, audit, tablePrefix, + logger.info("Creating " + dml.toString() + " trigger for " + + trigger.getSourceTableName()); + jdbcTemplate.update(createTriggerDDL(dml, trigger, audit, tablePrefix, table)); } diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/db/oracle/OracleDbDialect.java b/symmetric/src/main/java/org/jumpmind/symmetric/db/oracle/OracleDbDialect.java index a3fd348d13..ecb3019454 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/db/oracle/OracleDbDialect.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/db/oracle/OracleDbDialect.java @@ -1,4 +1,3 @@ - package org.jumpmind.symmetric.db.oracle; import java.net.URL; @@ -7,12 +6,15 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.ddlutils.model.Table; import org.jumpmind.symmetric.db.AbstractDbDialect; import org.jumpmind.symmetric.db.IDbDialect; import org.jumpmind.symmetric.db.SqlScript; +import org.jumpmind.symmetric.model.DataEventType; +import org.jumpmind.symmetric.model.Trigger; +import org.jumpmind.symmetric.model.TriggerHistory; -public class OracleDbDialect extends AbstractDbDialect implements IDbDialect -{ +public class OracleDbDialect extends AbstractDbDialect implements IDbDialect { static final Log logger = LogFactory.getLog(OracleDbDialect.class); @@ -23,82 +25,87 @@ public class OracleDbDialect extends AbstractDbDialect implements IDbDialect static final String SYNC_TRIGGERS_DISABLED_USER_VARIABLE = "sync_triggers_disabled"; @Override - protected void initForSpecificDialect() - { - try - { - if (!isFunctionUpToDate(TRANSACTION_ID_FUNCTION_NAME)) - { - logger.info("Creating function " + TRANSACTION_ID_FUNCTION_NAME); - new SqlScript(getTransactionIdSqlUrl(), getPlatform().getDataSource(), '/').execute(); + protected void initForSpecificDialect() { + try { + if (!isFunctionUpToDate(TRANSACTION_ID_FUNCTION_NAME)) { + logger + .info("Creating function " + + TRANSACTION_ID_FUNCTION_NAME); + new SqlScript(getTransactionIdSqlUrl(), getPlatform() + .getDataSource(), '/').execute(); } - } - catch (Exception ex) - { + } catch (Exception ex) { logger.error("Error while initializing Oracle.", ex); } } - private URL getTransactionIdSqlUrl() - { + @Override + public void initTrigger(DataEventType dml, Trigger config, + TriggerHistory audit, String tablePrefix, Table table) { + // TODO: fix node table trigger which cannot select itself + if (!config.getSourceTableName().endsWith("node")) { + super.initTrigger(dml, config, audit, tablePrefix, table); + } else { + logger.warn("Not creating trigger for " + config.getSourceTableName() + " because of a current bug we have with the oracle triggers and a trigger not being able to select from the table it fired for."); + } + } + + private URL getTransactionIdSqlUrl() { return getClass().getResource("/oracle-transactionid.sql"); } - public boolean isFunctionUpToDate(String name) throws Exception - { - long lastModified = getTransactionIdSqlUrl().openConnection().getLastModified(); - - - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd':'HH:mm:ss"); - - return jdbcTemplate.queryForInt( - "select count(*) from all_objects where timestamp < ? and object_name= upper(?) ", new Object[] { - dateFormat.format( new Date(lastModified)), name}) > 0; + public boolean isFunctionUpToDate(String name) throws Exception { + long lastModified = getTransactionIdSqlUrl().openConnection() + .getLastModified(); + + SimpleDateFormat dateFormat = new SimpleDateFormat( + "yyyy-MM-dd':'HH:mm:ss"); + + return jdbcTemplate + .queryForInt( + "select count(*) from all_objects where timestamp < ? and object_name= upper(?) ", + new Object[] { + dateFormat.format(new Date(lastModified)), name }) > 0; } - public boolean isCharSpacePadded() - { + public boolean isCharSpacePadded() { return true; } - public boolean isCharSpaceTrimmed() - { + public boolean isCharSpaceTrimmed() { return false; } - public boolean isEmptyStringNulled() - { + public boolean isEmptyStringNulled() { return true; } public void removeTrigger(String schemaName, String triggerName) { - schemaName = schemaName == null ? "" : ( schemaName+"."); + schemaName = schemaName == null ? "" : (schemaName + "."); try { - jdbcTemplate - .update("drop trigger " + schemaName + triggerName); - } - catch (Exception e) { + jdbcTemplate.update("drop trigger " + schemaName + triggerName); + } catch (Exception e) { logger.warn("Trigger does not exist", e); } } - public String getTransactionTriggerExpression() - { + public String getTransactionTriggerExpression() { return TRANSACTION_ID_FUNCTION_NAME + "()"; } @Override - public boolean doesTriggerExist(String schema, String tableName, String triggerName) - { - return jdbcTemplate.queryForInt( - "select count(*) from ALL_TRIGGERS where trigger_name like upper(?) and table_name like upper(?)", - new Object[] {triggerName, tableName}) > 0; + public boolean doesTriggerExist(String schema, String tableName, + String triggerName) { + return jdbcTemplate + .queryForInt( + "select count(*) from ALL_TRIGGERS where trigger_name like upper(?) and table_name like upper(?)", + new Object[] { triggerName, tableName }) > 0; } public void purge() { jdbcTemplate.update("purge recyclebin"); - + } public void disableSyncTriggers() { @@ -108,10 +115,11 @@ public void disableSyncTriggers() { public void enableSyncTriggers() { jdbcTemplate.update("call pack_var.setValue(null)"); } - + public String getDefaultSchema() { - return (String)jdbcTemplate.queryForObject("SELECT sys_context('USERENV', 'CURRENT_SCHEMA') FROM dual", String.class); + return (String) jdbcTemplate.queryForObject( + "SELECT sys_context('USERENV', 'CURRENT_SCHEMA') FROM dual", + String.class); } - } diff --git a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/BootstrapService.java b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/BootstrapService.java index f535f0aa0d..73b7e56688 100644 --- a/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/BootstrapService.java +++ b/symmetric/src/main/java/org/jumpmind/symmetric/service/impl/BootstrapService.java @@ -291,13 +291,9 @@ private TriggerHistory rebuildTriggerIfNecessary(boolean forceRebuild, audit = configurationService.getLatestHistoryRecordFor(trigger .getTriggerId()); } - // TODO: fix node table trigger which cannot select itself - if (!trigger.getSourceTableName().endsWith("node")) { - logger.info("Creating " + dmlType.toString() + " trigger for " - + trigger.getSourceTableName()); + dbDialect.initTrigger(dmlType, trigger, audit, tablePrefix, table); - } } return audit; diff --git a/symmetric/src/test/java/org/jumpmind/symmetric/IntegrationTest.java b/symmetric/src/test/java/org/jumpmind/symmetric/IntegrationTest.java index 71ab55c85f..24e0a61649 100644 --- a/symmetric/src/test/java/org/jumpmind/symmetric/IntegrationTest.java +++ b/symmetric/src/test/java/org/jumpmind/symmetric/IntegrationTest.java @@ -159,6 +159,16 @@ public void testPurge() throws Exception { "Expected all data rows to have been purged."); } + + @Test(groups = "integration") + public void testHeartbeat() throws Exception { + long ts = System.currentTimeMillis(); + Thread.sleep(500); + clientEngine.heartbeat(); + clientEngine.push(); + Date time = (Date)rootJdbcTemplate.queryForObject("select heartbeat_time from " + TestConstants.TEST_PREFIX+"node where external_id='"+TestConstants.TEST_CLIENT_EXTERNAL_ID+"'", Date.class); + Assert.assertTrue(time.getTime() > ts, "The client node was not sync'd to the root as expected."); + } @Test(groups = "integration") public void testMultipleChannels() {