Search in sources :

Example 6 with Channel

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));
}
Also used : RegistrationInfo(org.jumpmind.symmetric.web.rest.model.RegistrationInfo) NotAllowedException(org.jumpmind.symmetric.web.rest.NotAllowedException) Node(org.jumpmind.symmetric.model.Node) Channel(org.jumpmind.symmetric.model.Channel) ISymmetricEngine(org.jumpmind.symmetric.ISymmetricEngine) IParameterService(org.jumpmind.symmetric.service.IParameterService) PullDataResults(org.jumpmind.symmetric.web.rest.model.PullDataResults) Batch(org.jumpmind.symmetric.web.rest.model.Batch) INodeService(org.jumpmind.symmetric.service.INodeService) RestService(org.jumpmind.symmetric.web.rest.RestService)

Example 7 with Channel

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;
}
Also used : Status(org.jumpmind.symmetric.model.OutgoingBatch.Status) NumberMapper(org.jumpmind.db.sql.mapper.NumberMapper) IAcknowledgeEventListener(org.jumpmind.symmetric.transport.IAcknowledgeEventListener) IRegistrationService(org.jumpmind.symmetric.service.IRegistrationService) Channel(org.jumpmind.symmetric.model.Channel) BatchAckResult(org.jumpmind.symmetric.model.BatchAckResult) RouterStats(org.jumpmind.symmetric.statistic.RouterStats) IOutgoingBatchService(org.jumpmind.symmetric.service.IOutgoingBatchService) OutgoingBatch(org.jumpmind.symmetric.model.OutgoingBatch)

Example 8 with Channel

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;
}
Also used : NodeChannel(org.jumpmind.symmetric.model.NodeChannel) Channel(org.jumpmind.symmetric.model.Channel) ArrayList(java.util.ArrayList)

Example 9 with Channel

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;
}
Also used : NodeChannel(org.jumpmind.symmetric.model.NodeChannel) Channel(org.jumpmind.symmetric.model.Channel) Row(org.jumpmind.db.sql.Row)

Example 10 with Channel

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;
}
Also used : IDataLoaderFactory(org.jumpmind.symmetric.load.IDataLoaderFactory) Channel(org.jumpmind.symmetric.model.Channel)

Aggregations

Channel (org.jumpmind.symmetric.model.Channel)19 NodeChannel (org.jumpmind.symmetric.model.NodeChannel)8 ArrayList (java.util.ArrayList)4 Node (org.jumpmind.symmetric.model.Node)4 OutgoingBatch (org.jumpmind.symmetric.model.OutgoingBatch)4 TriggerHistory (org.jumpmind.symmetric.model.TriggerHistory)3 HashMap (java.util.HashMap)2 CancellationException (java.util.concurrent.CancellationException)2 ExecutionException (java.util.concurrent.ExecutionException)2 ISymmetricEngine (org.jumpmind.symmetric.ISymmetricEngine)2 SymmetricException (org.jumpmind.symmetric.SymmetricException)2 TransformPoint (org.jumpmind.symmetric.io.data.transform.TransformPoint)2 IStagedResource (org.jumpmind.symmetric.io.stage.IStagedResource)2 TriggerRouter (org.jumpmind.symmetric.model.TriggerRouter)2 IOException (java.io.IOException)1 SQLException (java.sql.SQLException)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1