use of org.jumpmind.symmetric.model.Channel in project symmetric-ds by JumpMind.
the class RestServiceTest method testRestPullApi.
protected void testRestPullApi() throws Exception {
loadConfigAtRegistrationServer();
RestService restService = getRegServer().getRestService();
ISymmetricEngine engine = getRegServer().getEngine();
IParameterService parameterService = engine.getParameterService();
INodeService nodeService = engine.getNodeService();
parameterService.saveParameter(ParameterConstants.REST_API_ENABLED, Boolean.TRUE, "unit_test");
assertNotNull("Could not find the rest service in the application context", restService);
List<Node> nodes = nodeService.findAllNodes();
assertEquals("Expected there to only be one node registered", 1, nodes.size());
assertEquals("The only node we expected to be registered is a server node", "server", nodes.get(0).getNodeGroupId());
RegistrationInfo registrationInfo = restService.postRegisterNode("client", "client", DatabaseNamesConstants.SQLITE, "3.0", "hostName");
assertNotNull("Registration should have returned a result object", registrationInfo);
assertFalse("Registration should not have been open", registrationInfo.isRegistered());
assertEquals("Expected there to only be one node registered", 1, nodes.size());
engine.openRegistration("client", "client");
registrationInfo = restService.postRegisterNode("client", "client", DatabaseNamesConstants.SQLITE, "3.0", "hostName");
assertNotNull("Registration should have returned a result object", registrationInfo);
assertTrue("Registration should have been open", registrationInfo.isRegistered());
assertEquals("client", registrationInfo.getNodeId());
try {
restService.getPullData(registrationInfo.getNodeId(), "wrong password", false, false, true, null);
fail("We should have received an exception");
} catch (NotAllowedException ex) {
}
PullDataResults results = null;
assertPullReturnsNoData(restService, registrationInfo);
engine.getSqlTemplate().update("insert into a values(?, ?, ?)", 1, "this is a test", FormatUtils.parseDate("2013-06-08 00:00:00.000", FormatUtils.TIMESTAMP_PATTERNS));
engine.route();
results = restService.getPullData("server", registrationInfo.getNodeId(), registrationInfo.getNodePassword(), false, false, true, null);
assertNotNull("Should have a non null results object", results);
assertEquals(1, results.getNbrBatches());
assertEquals(4, results.getBatches().get(0).getBatchId());
log.info(results.getBatches().get(0).getSqlStatements().get(0));
// pull a second time without acking. should get the same results
results = restService.getPullData("server", registrationInfo.getNodeId(), registrationInfo.getNodePassword(), false, false, false, null);
assertNotNull("Should have a non null results object", results);
assertEquals(1, results.getNbrBatches());
// test that when we don't request jdbc timestamp format sql statements come back in that format
assertFalse(results.getBatches().get(0).getSqlStatements().get(0).contains("{ts '"));
// make sure we have no delimited identifiers
assertFalse(results.getBatches().get(0).getSqlStatements().get(0).contains("\""));
engine.getSqlTemplate().update("update a set notes=? where id=?", "changed", 1);
engine.getSqlTemplate().update("update a set notes=? where id=?", "changed again", 1);
engine.route();
results = restService.getPullData("server", registrationInfo.getNodeId(), registrationInfo.getNodePassword(), true, false, true, null);
assertNotNull("Should have a non null results object", results);
assertEquals(2, results.getNbrBatches());
assertNotSame(results.getBatches().get(1).getBatchId(), results.getBatches().get(0).getBatchId());
assertEquals(2, results.getBatches().get(1).getSqlStatements().size());
// test that when we request jdbc timestamp format sql statements come back in that format
String testSql = results.getBatches().get(1).getSqlStatements().get(0);
assertTrue("The following sql was supposed to contain '{ts '" + testSql, testSql.contains("{ts '"));
// make sure we have delimited identifiers
assertTrue(results.getBatches().get(1).getSqlStatements().get(0).contains("\""));
log.info(results.getBatches().get(1).getSqlStatements().get(0));
log.info(results.getBatches().get(1).getSqlStatements().get(1));
ackBatches(restService, registrationInfo, results, buildBatchResults(registrationInfo, results));
engine.getSqlTemplate().update("insert into a values(?, ?, ?)", 2, "this is a test", FormatUtils.parseDate("2073-06-08 00:00:00.000", FormatUtils.TIMESTAMP_PATTERNS));
engine.getSqlTemplate().update("insert into a values(?, ?, ?)", 3, "this is a test", FormatUtils.parseDate("2073-06-08 00:00:00.000", FormatUtils.TIMESTAMP_PATTERNS));
engine.getSqlTemplate().update("update a set notes=? where id=?", "update to 2", 2);
engine.getSqlTemplate().update("update a set notes=? where id=?", "update to 3", 3);
engine.getSqlTemplate().update("update a set notes=? where id=?", "update 2 again", 2);
engine.route();
results = restService.getPullData("server", registrationInfo.getNodeId(), registrationInfo.getNodePassword(), false, true, true, null);
assertNotNull("Should have a non null results object", results);
assertEquals(1, results.getNbrBatches());
List<String> sqls = results.getBatches().get(0).getSqlStatements();
assertEquals(5, sqls.size());
for (String sql : sqls) {
log.info(sql);
assertTrue(sql, sql.toLowerCase().startsWith("insert or replace"));
}
ackBatches(restService, registrationInfo, results, buildBatchResults(registrationInfo, results));
Channel channel = engine.getConfigurationService().getChannel("default");
channel.setBatchAlgorithm("nontransactional");
channel.setMaxBatchSize(1);
engine.getConfigurationService().saveChannel(channel, true);
engine.getSqlTemplate().update("delete from a");
engine.route();
results = restService.getPullData("server", registrationInfo.getNodeId(), registrationInfo.getNodePassword(), false, false, true, null);
assertNotNull("Should have a non null results object", results);
assertEquals(3, results.getNbrBatches());
List<Batch> batches = results.getBatches();
for (Batch batch : batches) {
assertEquals(1, batch.getSqlStatements().size());
assertTrue(batch.getSqlStatements().get(0).toLowerCase().startsWith("delete from"));
}
ackBatches(restService, registrationInfo, results, buildBatchResults(registrationInfo, results));
}
use of org.jumpmind.symmetric.model.Channel in project symmetric-ds by JumpMind.
the class AcknowledgeService method ack.
public BatchAckResult ack(final BatchAck batch) {
IRegistrationService registrationService = engine.getRegistrationService();
IOutgoingBatchService outgoingBatchService = engine.getOutgoingBatchService();
BatchAckResult result = new BatchAckResult(batch);
for (IAcknowledgeEventListener listener : engine.getExtensionService().getExtensionPointList(IAcknowledgeEventListener.class)) {
listener.onAcknowledgeEvent(batch);
}
if (batch.getBatchId() == Constants.VIRTUAL_BATCH_FOR_REGISTRATION) {
if (batch.isOk()) {
registrationService.markNodeAsRegistered(batch.getNodeId());
}
} else {
OutgoingBatch outgoingBatch = outgoingBatchService.findOutgoingBatch(batch.getBatchId(), batch.getNodeId());
Status status = batch.isOk() ? Status.OK : batch.isResend() ? Status.RS : Status.ER;
if (outgoingBatch != null) {
// is OK.
if (outgoingBatch.getStatus() != Status.OK && outgoingBatch.getStatus() != Status.IG) {
outgoingBatch.setStatus(status);
outgoingBatch.setErrorFlag(!batch.isOk());
} else {
// clearing the error flag in case the user set the batch
// status to OK
Status oldStatus = outgoingBatch.getStatus();
outgoingBatch.setStatus(Status.OK);
outgoingBatch.setErrorFlag(false);
log.info("Batch {} for {} was set to {}. Updating the status to OK", new Object[] { batch.getBatchId(), batch.getNodeId(), oldStatus.name() });
}
if (batch.isIgnored()) {
outgoingBatch.incrementIgnoreCount();
}
outgoingBatch.setNetworkMillis(batch.getNetworkMillis());
outgoingBatch.setFilterMillis(batch.getFilterMillis());
outgoingBatch.setLoadMillis(batch.getDatabaseMillis());
outgoingBatch.setSqlCode(batch.getSqlCode());
outgoingBatch.setSqlState(batch.getSqlState());
outgoingBatch.setSqlMessage(batch.getSqlMessage());
boolean isNewError = false;
if (!batch.isOk() && batch.getErrorLine() != 0) {
List<Number> ids = sqlTemplateDirty.query(getSql("selectDataIdSql"), new NumberMapper(), outgoingBatch.getBatchId());
if (ids.size() >= batch.getErrorLine()) {
long failedDataId = ids.get((int) batch.getErrorLine() - 1).longValue();
if (outgoingBatch.getFailedDataId() == 0 || outgoingBatch.getFailedDataId() != failedDataId) {
isNewError = true;
}
outgoingBatch.setFailedDataId(failedDataId);
}
}
if (status == Status.ER) {
log.error("The outgoing batch {} failed: {}{}", outgoingBatch.getNodeBatchId(), (batch.getSqlCode() != 0 ? "[" + batch.getSqlState() + "," + batch.getSqlCode() + "] " : ""), batch.getSqlMessage());
RouterStats routerStats = engine.getStatisticManager().getRouterStatsByBatch(batch.getBatchId());
if (routerStats != null) {
log.info("Router stats for batch " + outgoingBatch.getBatchId() + ": " + routerStats.toString());
}
if (isNewError && outgoingBatch.getSqlCode() == ErrorConstants.FK_VIOLATION_CODE && parameterService.is(ParameterConstants.AUTO_RESOLVE_FOREIGN_KEY_VIOLATION)) {
Channel channel = engine.getConfigurationService().getChannel(outgoingBatch.getChannelId());
if (channel != null && !channel.isReloadFlag()) {
engine.getDataService().reloadMissingForeignKeyRows(outgoingBatch.getNodeId(), outgoingBatch.getFailedDataId());
}
}
} else if (status == Status.RS) {
log.info("The outgoing batch {} received resend request", outgoingBatch.getNodeBatchId());
}
outgoingBatchService.updateOutgoingBatch(outgoingBatch);
if (status == Status.OK) {
Channel channel = engine.getConfigurationService().getChannel(outgoingBatch.getChannelId());
if (channel != null && channel.isFileSyncFlag()) {
/* Acknowledge the file_sync in case the file needs deleted. */
engine.getFileSyncService().acknowledgeFiles(outgoingBatch);
}
engine.getStatisticManager().removeRouterStatsByBatch(batch.getBatchId());
}
} else {
log.error("Could not find batch {}-{} to acknowledge as {}", new Object[] { batch.getNodeId(), batch.getBatchId(), status.name() });
result.setOk(false);
}
}
return result;
}
use of org.jumpmind.symmetric.model.Channel in project symmetric-ds by JumpMind.
the class ConfigurationService method getFileSyncChannels.
public List<Channel> getFileSyncChannels() {
List<Channel> list = new ArrayList<Channel>(getChannels(false).values());
Iterator<Channel> it = list.iterator();
while (it.hasNext()) {
Channel channel = it.next();
if (!channel.isFileSyncFlag()) {
it.remove();
}
}
return list;
}
use of org.jumpmind.symmetric.model.Channel in project symmetric-ds by JumpMind.
the class ConfigurationService method getChannels.
public Map<String, Channel> getChannels(boolean refreshCache) {
long channelCacheTimeoutInMs = parameterService.getLong(ParameterConstants.CACHE_TIMEOUT_CHANNEL_IN_MS, 60000);
Map<String, Channel> channels = channelsCache;
if (System.currentTimeMillis() - channelCacheTime >= channelCacheTimeoutInMs || channels == null || refreshCache) {
synchronized (this) {
channels = channelsCache;
if (System.currentTimeMillis() - channelCacheTime >= channelCacheTimeoutInMs || channels == null || refreshCache) {
channels = new HashMap<String, Channel>();
List<Channel> list = sqlTemplate.query(getSql("selectChannelsSql"), new ISqlRowMapper<Channel>() {
public Channel mapRow(Row row) {
Channel channel = new Channel();
channel.setChannelId(row.getString("channel_id"));
channel.setProcessingOrder(row.getInt("processing_order"));
channel.setMaxBatchSize(row.getInt("max_batch_size"));
channel.setEnabled(row.getBoolean("enabled"));
channel.setMaxBatchToSend(row.getInt("max_batch_to_send"));
channel.setMaxDataToRoute(row.getInt("max_data_to_route"));
channel.setUseOldDataToRoute(row.getBoolean("use_old_data_to_route"));
channel.setUseRowDataToRoute(row.getBoolean("use_row_data_to_route"));
channel.setUsePkDataToRoute(row.getBoolean("use_pk_data_to_route"));
channel.setContainsBigLob(row.getBoolean("contains_big_lob"));
channel.setBatchAlgorithm(row.getString("batch_algorithm"));
channel.setExtractPeriodMillis(row.getLong("extract_period_millis"));
channel.setDataLoaderType(row.getString("data_loader_type"));
channel.setCreateTime(row.getDateTime("create_time"));
channel.setLastUpdateBy(row.getString("last_update_by"));
channel.setLastUpdateTime(row.getDateTime("last_update_time"));
channel.setReloadFlag(row.getBoolean("reload_flag"));
channel.setFileSyncFlag(row.getBoolean("file_sync_flag"));
channel.setQueue(row.getString("queue"));
channel.setMaxKBytesPerSecond(row.getBigDecimal("max_network_kbps"));
channel.setDataEventAction(NodeGroupLinkAction.fromCode(row.getString("data_event_action")));
return channel;
}
});
for (Channel channel : list) {
channels.put(channel.getChannelId(), channel);
}
channelsCache = channels;
channelCacheTime = System.currentTimeMillis();
}
}
}
return channels;
}
use of org.jumpmind.symmetric.model.Channel in project symmetric-ds by JumpMind.
the class DataLoaderService method getFactory.
protected IDataLoaderFactory getFactory(String channelId) {
Channel channel = configurationService.getChannel(channelId);
String dataLoaderType = "default";
IDataLoaderFactory factory = null;
if (channel != null) {
dataLoaderType = filterDataLoaderType(channel.getDataLoaderType());
}
Map<String, IDataLoaderFactory> dataLoaderFactories = getDataLoaderFactories();
factory = dataLoaderFactories.get(dataLoaderType);
if (factory == null) {
log.warn("Could not find a data loader factory of type '{}'. Using the 'default' data loader.", dataLoaderType);
factory = dataLoaderFactories.get("default");
}
if (!factory.isPlatformSupported(platform)) {
log.warn("The current platform does not support a data loader type of '{}'. Using the 'default' data loader.", dataLoaderType);
factory = dataLoaderFactories.get("default");
}
return factory;
}
Aggregations