Search in sources :

Example 16 with Data

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

the class RouterService method selectDataAndRoute.

/**
     * Pre-read data and fill up a queue so we can peek ahead to see if we have
     * crossed a database transaction boundary. Then route each {@link Data}
     * while continuing to keep the queue filled until the result set is
     * entirely read.
     * 
     * @param conn
     *            The connection to use for selecting the data.
     * @param context
     *            The current context of the routing process
     */
protected int selectDataAndRoute(ProcessInfo processInfo, ChannelRouterContext context) throws InterruptedException {
    IDataToRouteReader reader = startReading(context);
    Data data = null;
    Data nextData = null;
    int totalDataCount = 0;
    int totalDataEventCount = 0;
    int statsDataCount = 0;
    int statsDataEventCount = 0;
    final int maxNumberOfEventsBeforeFlush = parameterService.getInt(ParameterConstants.ROUTING_FLUSH_JDBC_BATCH_SIZE);
    try {
        long ts = System.currentTimeMillis();
        long startTime = System.currentTimeMillis();
        nextData = reader.take();
        do {
            if (nextData != null) {
                data = nextData;
                nextData = reader.take();
                if (data != null) {
                    processInfo.setCurrentTableName(data.getTableName());
                    processInfo.incrementCurrentDataCount();
                    boolean atTransactionBoundary = false;
                    if (nextData != null) {
                        String nextTxId = nextData.getTransactionId();
                        atTransactionBoundary = nextTxId == null || !nextTxId.equals(data.getTransactionId());
                    }
                    context.setEncountedTransactionBoundary(atTransactionBoundary);
                    statsDataCount++;
                    totalDataCount++;
                    int dataEventsInserted = routeData(processInfo, data, context);
                    statsDataEventCount += dataEventsInserted;
                    totalDataEventCount += dataEventsInserted;
                    long insertTs = System.currentTimeMillis();
                    try {
                        if (maxNumberOfEventsBeforeFlush <= context.getDataEventList().size() || context.isNeedsCommitted()) {
                            engine.getDataService().insertDataEvents(context.getSqlTransaction(), context.getDataEventList());
                            context.clearDataEventsList();
                        }
                        if (context.isNeedsCommitted()) {
                            completeBatchesAndCommit(context);
                        }
                    } finally {
                        context.incrementStat(System.currentTimeMillis() - insertTs, ChannelRouterContext.STAT_INSERT_DATA_EVENTS_MS);
                        if (statsDataCount > StatisticConstants.FLUSH_SIZE_ROUTER_DATA) {
                            engine.getStatisticManager().incrementDataRouted(context.getChannel().getChannelId(), statsDataCount);
                            statsDataCount = 0;
                            engine.getStatisticManager().incrementDataEventInserted(context.getChannel().getChannelId(), statsDataEventCount);
                            statsDataEventCount = 0;
                        }
                    }
                    long routeTs = System.currentTimeMillis() - ts;
                    if (routeTs > 60000 && context != null) {
                        log.info("Routing for channel '{}' has been processing for {} seconds. The following stats have been gathered: " + "totalDataRoutedCount={}, totalDataEventCount={}, startDataId={}, endDataId={}, dataReadCount={}, peekAheadFillCount={}, transactions={}, dataGaps={}", new Object[] { context.getChannel().getChannelId(), ((System.currentTimeMillis() - startTime) / 1000), totalDataCount, totalDataEventCount, context.getStartDataId(), context.getEndDataId(), context.getDataReadCount(), context.getPeekAheadFillCount(), context.getTransactions().toString(), context.getDataGaps().toString() });
                        ts = System.currentTimeMillis();
                    }
                    context.setLastDataProcessed(data);
                }
            } else {
                data = null;
            }
        } while (data != null);
        long routeTime = System.currentTimeMillis() - startTime;
        if (routeTime > 60000 && context != null) {
            log.info("Done routing for channel '{}' which took {} seconds", new Object[] { context.getChannel().getChannelId(), ((System.currentTimeMillis() - startTime) / 1000) });
            ts = System.currentTimeMillis();
        }
    } finally {
        reader.setReading(false);
        if (statsDataCount > 0) {
            engine.getStatisticManager().incrementDataRouted(context.getChannel().getChannelId(), statsDataCount);
        }
        if (statsDataEventCount > 0) {
            engine.getStatisticManager().incrementDataEventInserted(context.getChannel().getChannelId(), statsDataEventCount);
        }
    }
    context.incrementStat(totalDataCount, ChannelRouterContext.STAT_DATA_ROUTED_COUNT);
    return totalDataEventCount;
}
Also used : IDataToRouteReader(org.jumpmind.symmetric.route.IDataToRouteReader) Data(org.jumpmind.symmetric.model.Data) DataMetaData(org.jumpmind.symmetric.model.DataMetaData)

Example 17 with Data

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

the class AbstractFileParsingRouter method deleteFileIfNecessary.

public void deleteFileIfNecessary(DataMetaData dataMetaData) {
    Data data = dataMetaData.getData();
    Table snapshotTable = dataMetaData.getTable();
    if (data.getDataEventType() == DataEventType.INSERT || data.getDataEventType() == DataEventType.UPDATE) {
        List<File> filesToDelete = new ArrayList<File>();
        Map<String, String> columnData = data.toColumnNameValuePairs(snapshotTable.getColumnNames(), CsvData.ROW_DATA);
        FileSnapshot fileSnapshot = new FileSnapshot();
        fileSnapshot.setTriggerId(columnData.get("TRIGGER_ID"));
        fileSnapshot.setRouterId(columnData.get("ROUTER_ID"));
        fileSnapshot.setFileModifiedTime(Long.parseLong(columnData.get("FILE_MODIFIED_TIME")));
        fileSnapshot.setFileName(columnData.get("FILE_NAME"));
        fileSnapshot.setRelativeDir(columnData.get("RELATIVE_DIR"));
        fileSnapshot.setLastEventType(LastEventType.fromCode(columnData.get("LAST_EVENT_TYPE")));
        FileTriggerRouter triggerRouter = getEngine().getFileSyncService().getFileTriggerRouter(fileSnapshot.getTriggerId(), fileSnapshot.getRouterId());
        if (triggerRouter != null) {
            FileTrigger fileTrigger = triggerRouter.getFileTrigger();
            if (fileTrigger.isDeleteAfterSync()) {
                File file = fileTrigger.createSourceFile(fileSnapshot);
                if (!file.isDirectory()) {
                    filesToDelete.add(file);
                    if (fileTrigger.isSyncOnCtlFile()) {
                        File ctlFile = getEngine().getFileSyncService().getControleFile(file);
                        filesToDelete.add(ctlFile);
                    }
                }
            } else if (getEngine().getParameterService().is(ParameterConstants.FILE_SYNC_DELETE_CTL_FILE_AFTER_SYNC, false)) {
                File file = fileTrigger.createSourceFile(fileSnapshot);
                if (!file.isDirectory()) {
                    if (fileTrigger.isSyncOnCtlFile()) {
                        File ctlFile = getEngine().getFileSyncService().getControleFile(file);
                        filesToDelete.add(ctlFile);
                    }
                }
            }
        }
        if (filesToDelete != null && filesToDelete.size() > 0) {
            for (File file : filesToDelete) {
                if (file != null && file.exists()) {
                    log.debug("Deleting the '{}' file", file.getAbsolutePath());
                    boolean deleted = FileUtils.deleteQuietly(file);
                    if (!deleted) {
                        log.warn("Failed to 'delete on sync' the {} file", file.getAbsolutePath());
                    }
                }
                file = null;
            }
            filesToDelete = null;
        }
    }
}
Also used : FileSnapshot(org.jumpmind.symmetric.model.FileSnapshot) Table(org.jumpmind.db.model.Table) FileTriggerRouter(org.jumpmind.symmetric.model.FileTriggerRouter) FileTrigger(org.jumpmind.symmetric.model.FileTrigger) ArrayList(java.util.ArrayList) Data(org.jumpmind.symmetric.model.Data) CsvData(org.jumpmind.symmetric.io.data.CsvData) DataMetaData(org.jumpmind.symmetric.model.DataMetaData) File(java.io.File)

Example 18 with Data

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

the class AbstractFileParsingRouter method routeToNodes.

@Override
public Set<String> routeToNodes(SimpleRouterContext context, DataMetaData dataMetaData, Set<Node> nodes, boolean initialLoad, boolean initialLoadSelectUsed, TriggerRouter triggerRouter) {
    Map<String, String> newData = getNewDataAsString(null, dataMetaData, getEngine().getSymmetricDialect());
    String targetTableName = dataMetaData.getRouter().getTargetTableName();
    String fileName = newData.get("FILE_NAME");
    String relativeDir = newData.get("RELATIVE_DIR");
    String triggerId = newData.get("TRIGGER_ID");
    String lastEventType = newData.get("LAST_EVENT_TYPE");
    String routerExpression = dataMetaData.getRouter().getRouterExpression();
    String channelId = "default";
    String filePath = relativeDir + "/" + fileName;
    IContextService contextService = getEngine().getContextService();
    if (lastEventType.equals(DataEventType.DELETE.toString())) {
        log.debug("File deleted (" + filePath + "), cleaning up context value.");
        contextService.delete(filePath);
    } else {
        if (routerExpression != null) {
            String[] keyValues = routerExpression.split(",");
            if (keyValues.length > 0) {
                for (int i = 0; i < keyValues.length; i++) {
                    String[] keyValue = keyValues[i].split("=");
                    if (keyValue.length > 1) {
                        if (ROUTER_EXPRESSION_CHANNEL_KEY.equals(keyValue[0])) {
                            channelId = keyValue[1];
                        }
                    }
                }
            }
        }
        if (triggerId != null) {
            String baseDir = getEngine().getFileSyncService().getFileTrigger(triggerId).getBaseDir();
            File file = createSourceFile(baseDir, relativeDir, fileName);
            Integer lineNumber = contextService.getString(filePath) == null ? 0 : new Integer(contextService.getString(filePath));
            List<String> dataRows = parse(file, lineNumber);
            String columnNames = getColumnNames();
            String nodeList = buildNodeList(nodes);
            String externalData = new StringBuilder(EXTERNAL_DATA_TRIGGER_KEY).append("=").append(triggerId).append(",").append(EXTERNAL_DATA_ROUTER_KEY).append("=").append(dataMetaData.getRouter().getRouterId()).append(",").append(EXTERNAL_DATA_FILE_DATA_ID).append("=").append(dataMetaData.getData().getDataId()).toString();
            for (String row : dataRows) {
                Data data = new Data();
                data.setChannelId(channelId);
                data.setDataEventType(DataEventType.INSERT);
                data.setRowData(row);
                data.setTableName(targetTableName);
                data.setNodeList(nodeList);
                data.setTriggerHistory(getTriggerHistory(targetTableName, columnNames));
                data.setExternalData(externalData);
                data.setDataId(getEngine().getDataService().insertData(data));
                lineNumber++;
            }
            if (!dataRows.isEmpty()) {
                try {
                    contextService.save(filePath, lineNumber.toString());
                    deleteFileIfNecessary(dataMetaData);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    return new HashSet<String>();
}
Also used : IContextService(org.jumpmind.symmetric.service.IContextService) Data(org.jumpmind.symmetric.model.Data) CsvData(org.jumpmind.symmetric.io.data.CsvData) DataMetaData(org.jumpmind.symmetric.model.DataMetaData) File(java.io.File) HashSet(java.util.HashSet)

Example 19 with Data

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

the class ColumnMatchDataRouterTest method testExpressionExternalData.

@Test
public void testExpressionExternalData() {
    ColumnMatchDataRouter router = new ColumnMatchDataRouter();
    SimpleRouterContext routingContext = new SimpleRouterContext();
    HashSet<Node> nodes = new HashSet<Node>();
    nodes.add(new Node("100", "client"));
    nodes.add(new Node("200", "client"));
    nodes.add(new Node("300", "client"));
    TriggerHistory triggerHist = new TriggerHistory("mytable", "ID", "ID,NODE_ID,COLUMN2");
    Data data = new Data();
    data.setDataId(1);
    data.setDataEventType(DataEventType.INSERT);
    data.setRowData("1,100,Super Dooper");
    data.setExternalData("100");
    data.setTriggerHistory(triggerHist);
    Table table = new Table();
    NodeChannel nodeChannel = new NodeChannel();
    Router route = new Router();
    route.setRouterExpression("EXTERNAL_DATA = :NODE_ID");
    route.setRouterId("route1");
    DataMetaData dataMetaData = new DataMetaData(data, table, route, nodeChannel);
    Set<String> result = router.routeToNodes(routingContext, dataMetaData, nodes, false, false, null);
    assertEquals(1, result.size());
    assertEquals(true, result.contains("100"));
}
Also used : Table(org.jumpmind.db.model.Table) Node(org.jumpmind.symmetric.model.Node) Router(org.jumpmind.symmetric.model.Router) Data(org.jumpmind.symmetric.model.Data) DataMetaData(org.jumpmind.symmetric.model.DataMetaData) TriggerHistory(org.jumpmind.symmetric.model.TriggerHistory) NodeChannel(org.jumpmind.symmetric.model.NodeChannel) HashSet(java.util.HashSet) DataMetaData(org.jumpmind.symmetric.model.DataMetaData) Test(org.junit.Test)

Example 20 with Data

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

the class ColumnMatchDataRouterTest method testExpressionNotEqualsNull.

@Test
public void testExpressionNotEqualsNull() {
    ColumnMatchDataRouter router = new ColumnMatchDataRouter();
    SimpleRouterContext routingContext = new SimpleRouterContext();
    HashSet<Node> nodes = new HashSet<Node>();
    nodes.add(new Node("100", "client"));
    nodes.add(new Node("200", "client"));
    TriggerHistory triggerHist = new TriggerHistory("mytable", "ID", "ID,NODE_ID,COLUMN2");
    Data data = new Data();
    data.setDataId(1);
    data.setDataEventType(DataEventType.INSERT);
    data.setRowData("1,100,");
    data.setTriggerHistory(triggerHist);
    Table table = new Table();
    NodeChannel nodeChannel = new NodeChannel();
    Router route = new Router();
    route.setRouterExpression("COLUMN2 != NULL");
    route.setRouterId("route1");
    DataMetaData dataMetaData = new DataMetaData(data, table, route, nodeChannel);
    Set<String> result = router.routeToNodes(routingContext, dataMetaData, nodes, false, false, null);
    assertEquals(0, result.size());
}
Also used : Table(org.jumpmind.db.model.Table) Node(org.jumpmind.symmetric.model.Node) Router(org.jumpmind.symmetric.model.Router) Data(org.jumpmind.symmetric.model.Data) DataMetaData(org.jumpmind.symmetric.model.DataMetaData) TriggerHistory(org.jumpmind.symmetric.model.TriggerHistory) NodeChannel(org.jumpmind.symmetric.model.NodeChannel) HashSet(java.util.HashSet) DataMetaData(org.jumpmind.symmetric.model.DataMetaData) Test(org.junit.Test)

Aggregations

Data (org.jumpmind.symmetric.model.Data)42 TriggerHistory (org.jumpmind.symmetric.model.TriggerHistory)19 DataMetaData (org.jumpmind.symmetric.model.DataMetaData)18 Test (org.junit.Test)18 CsvData (org.jumpmind.symmetric.io.data.CsvData)16 Table (org.jumpmind.db.model.Table)14 ArrayList (java.util.ArrayList)12 Node (org.jumpmind.symmetric.model.Node)12 HashSet (java.util.HashSet)11 NodeChannel (org.jumpmind.symmetric.model.NodeChannel)10 Router (org.jumpmind.symmetric.model.Router)9 DataGap (org.jumpmind.symmetric.model.DataGap)7 TransformedData (org.jumpmind.symmetric.io.data.transform.TransformedData)6 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)6 Trigger (org.jumpmind.symmetric.model.Trigger)5 TriggerRouter (org.jumpmind.symmetric.model.TriggerRouter)5 File (java.io.File)3 ISqlTransaction (org.jumpmind.db.sql.ISqlTransaction)3 TransformTableNodeGroupLink (org.jumpmind.symmetric.service.impl.TransformService.TransformTableNodeGroupLink)3 Row (org.jumpmind.db.sql.Row)2