Search in sources :

Example 46 with Node

use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.

the class PullService method execute.

public void execute(NodeCommunication nodeCommunication, RemoteNodeStatus status) {
    Node node = nodeCommunication.getNode();
    if (StringUtils.isNotBlank(node.getSyncUrl()) || !parameterService.isRegistrationServer()) {
        int pullCount = 0;
        long batchesProcessedCount = 0;
        do {
            batchesProcessedCount = status.getBatchesProcessed();
            pullCount++;
            log.debug("Pull requested for {}", node.toString());
            if (pullCount > 1) {
                log.info("Immediate pull requested while in reload mode");
            }
            try {
                dataLoaderService.loadDataFromPull(node, status);
                fireOnline(node, status);
            } catch (Exception ex) {
                fireOffline(ex, node, status);
            }
            if (!status.failed() && (status.getDataProcessed() > 0 || status.getBatchesProcessed() > 0)) {
                log.info("Pull data received from {} {}.  {} rows and {} batches were processed", new Object[] { node.toString(), "on channel thread " + nodeCommunication.getQueue(), status.getDataProcessed(), status.getBatchesProcessed() });
            } else if (status.failed()) {
                log.debug("There was a failure while pulling data from {} {}.  {} rows and {} batches were processed", new Object[] { node.toString(), "on channel thread " + nodeCommunication.getQueue(), status.getDataProcessed(), status.getBatchesProcessed() });
            }
        /*
                 * Re-pull immediately if we are in the middle of an initial
                 * load so that the initial load completes as quickly as
                 * possible.
                 */
        } while (nodeService.isDataLoadStarted() && !status.failed() && status.getBatchesProcessed() > batchesProcessedCount);
    } else {
        log.warn("Cannot pull node '{}' in the group '{}'.  The sync url is blank", node.getNodeId(), node.getNodeGroupId());
    }
}
Also used : Node(org.jumpmind.symmetric.model.Node)

Example 47 with Node

use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.

the class PullService method pullData.

public synchronized RemoteNodeStatuses pullData(boolean force) {
    final RemoteNodeStatuses statuses = new RemoteNodeStatuses(configurationService.getChannels(false));
    Node identity = nodeService.findIdentity();
    if (identity == null || identity.isSyncEnabled()) {
        long minimumPeriodMs = parameterService.getLong(ParameterConstants.PULL_MINIMUM_PERIOD_MS, -1);
        if (force || !clusterService.isInfiniteLocked(ClusterConstants.PULL)) {
            // register if we haven't already been registered
            registrationService.registerWithServer();
            identity = nodeService.findIdentity();
            if (identity != null) {
                List<NodeCommunication> nodes = nodeCommunicationService.list(CommunicationType.PULL);
                int availableThreads = nodeCommunicationService.getAvailableThreads(CommunicationType.PULL);
                for (NodeCommunication nodeCommunication : nodes) {
                    boolean meetsMinimumTime = true;
                    if (minimumPeriodMs > 0 && nodeCommunication.getLastLockTime() != null && (System.currentTimeMillis() - nodeCommunication.getLastLockTime().getTime()) < minimumPeriodMs) {
                        meetsMinimumTime = false;
                    }
                    if (availableThreads > 0 && meetsMinimumTime) {
                        if (nodeCommunicationService.execute(nodeCommunication, statuses, this)) {
                            availableThreads--;
                        }
                    }
                }
            }
        } else {
            log.debug("Did not run the pull process because it has been stopped");
        }
    }
    return statuses;
}
Also used : RemoteNodeStatuses(org.jumpmind.symmetric.model.RemoteNodeStatuses) NodeCommunication(org.jumpmind.symmetric.model.NodeCommunication) Node(org.jumpmind.symmetric.model.Node)

Example 48 with Node

use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.

the class RegistrationService method reOpenRegistration.

protected synchronized void reOpenRegistration(String nodeId, String remoteHost, String remoteAddress) {
    Node node = nodeService.findNode(nodeId);
    NodeSecurity security = nodeService.findNodeSecurity(nodeId);
    String password = null;
    if (security != null && parameterService.is(ParameterConstants.REGISTRATION_REOPEN_USE_SAME_PASSWORD, true)) {
        password = security.getNodePassword();
    } else {
        password = extensionService.getExtensionPoint(INodeIdCreator.class).generatePassword(node);
        password = filterPasswordOnSaveIfNeeded(password);
    }
    if (node != null) {
        int updateCount = sqlTemplate.update(getSql("reopenRegistrationSql"), new Object[] { password, nodeId });
        if (updateCount == 0 && nodeService.findNodeSecurity(nodeId) == null) {
            // if the update count was 0, then we probably have a row in the
            // node table, but not in node security.
            // lets go ahead and try to insert into node security.
            sqlTemplate.update(getSql("openRegistrationNodeSecuritySql"), new Object[] { nodeId, password, nodeService.findNode(nodeId).getNodeId() });
            log.info("Registration was opened for {}", nodeId);
        } else if (updateCount == 0) {
            log.warn("Registration was already enabled for {}.  No need to reenable it", nodeId);
        } else {
            log.info("Registration was reopened for {}", nodeId);
        }
        if (isNotBlank(remoteHost)) {
            NodeHost nodeHost = new NodeHost(node.getNodeId());
            nodeHost.setHeartbeatTime(new Date());
            nodeHost.setIpAddress(remoteAddress);
            nodeHost.setHostName(remoteHost);
            nodeService.updateNodeHost(nodeHost);
        }
        nodeService.flushNodeAuthorizedCache();
    } else {
        log.warn("There was no row with a node id of {} to 'reopen' registration for", nodeId);
    }
}
Also used : NodeSecurity(org.jumpmind.symmetric.model.NodeSecurity) Node(org.jumpmind.symmetric.model.Node) Date(java.util.Date) NodeHost(org.jumpmind.symmetric.model.NodeHost)

Example 49 with Node

use of org.jumpmind.symmetric.model.Node 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 50 with Node

use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.

the class SymmetricAdmin method sendSchema.

private void sendSchema(CommandLine line, List<String> args) {
    String catalog = line.getOptionValue(OPTION_CATALOG);
    String schema = line.getOptionValue(OPTION_SCHEMA);
    Collection<Node> nodes = getNodes(line);
    if (args.size() == 0) {
        for (TriggerHistory hist : engine.getTriggerRouterService().getActiveTriggerHistories()) {
            for (Node node : nodes) {
                if ((catalog == null || catalog.equals(hist.getSourceCatalogName())) && (schema == null || schema.equals(hist.getSourceSchemaName()))) {
                    getSymmetricEngine().getDataService().sendSchema(node.getNodeId(), hist.getSourceCatalogName(), hist.getSourceSchemaName(), hist.getSourceTableName(), false);
                }
            }
        }
    } else {
        for (String tableName : args) {
            for (Node node : nodes) {
                getSymmetricEngine().getDataService().sendSchema(node.getNodeId(), catalog, schema, tableName, false);
            }
        }
    }
}
Also used : TriggerHistory(org.jumpmind.symmetric.model.TriggerHistory) Node(org.jumpmind.symmetric.model.Node)

Aggregations

Node (org.jumpmind.symmetric.model.Node)129 HashSet (java.util.HashSet)18 ProcessInfo (org.jumpmind.symmetric.model.ProcessInfo)18 Test (org.junit.Test)18 TriggerHistory (org.jumpmind.symmetric.model.TriggerHistory)17 ArrayList (java.util.ArrayList)14 NetworkedNode (org.jumpmind.symmetric.model.NetworkedNode)14 NodeChannel (org.jumpmind.symmetric.model.NodeChannel)14 NodeSecurity (org.jumpmind.symmetric.model.NodeSecurity)13 ProcessInfoKey (org.jumpmind.symmetric.model.ProcessInfoKey)13 Table (org.jumpmind.db.model.Table)12 Data (org.jumpmind.symmetric.model.Data)12 Router (org.jumpmind.symmetric.model.Router)12 Date (java.util.Date)11 NodeGroupLink (org.jumpmind.symmetric.model.NodeGroupLink)11 IOException (java.io.IOException)10 DataMetaData (org.jumpmind.symmetric.model.DataMetaData)10 HashMap (java.util.HashMap)9 OutgoingBatch (org.jumpmind.symmetric.model.OutgoingBatch)9 ISqlTransaction (org.jumpmind.db.sql.ISqlTransaction)8