use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.
the class DataService method insertPurgeEvent.
protected void insertPurgeEvent(ISqlTransaction transaction, Node targetNode, TriggerRouter triggerRouter, TriggerHistory triggerHistory, boolean isLoad, String overrideDeleteStatement, long loadId, String createBy) {
Node sourceNode = engine.getNodeService().findIdentity();
List<TransformTableNodeGroupLink> transforms = this.engine.getTransformService().findTransformsFor(sourceNode.getNodeGroupId(), targetNode.getNodeGroupId(), triggerRouter.getTargetTable(triggerHistory));
String sql = StringUtils.isNotBlank(overrideDeleteStatement) ? overrideDeleteStatement : symmetricDialect.createPurgeSqlFor(targetNode, triggerRouter, triggerHistory, transforms);
sql = FormatUtils.replace("groupId", targetNode.getNodeGroupId(), sql);
sql = FormatUtils.replace("externalId", targetNode.getExternalId(), sql);
sql = FormatUtils.replace("nodeId", targetNode.getNodeId(), sql);
sql = FormatUtils.replace("targetGroupId", targetNode.getNodeGroupId(), sql);
sql = FormatUtils.replace("targetExternalId", targetNode.getExternalId(), sql);
sql = FormatUtils.replace("targetNodeId", targetNode.getNodeId(), sql);
sql = FormatUtils.replace("sourceGroupId", sourceNode.getNodeGroupId(), sql);
sql = FormatUtils.replace("sourceExternalId", sourceNode.getExternalId(), sql);
sql = FormatUtils.replace("sourceNodeId", sourceNode.getNodeId(), sql);
String channelId = getReloadChannelIdForTrigger(triggerRouter.getTrigger(), engine.getConfigurationService().getChannels(false));
Data data = new Data(triggerHistory.getSourceTableName(), DataEventType.SQL, CsvUtils.escapeCsvData(sql), null, triggerHistory, channelId, null, null);
if (isLoad) {
insertDataAndDataEventAndOutgoingBatch(transaction, data, targetNode.getNodeId(), triggerRouter.getRouter().getRouterId(), isLoad, loadId, createBy, Status.NE);
} else {
data.setNodeList(targetNode.getNodeId());
insertData(transaction, data);
}
}
use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.
the class NodeManagementService method setSyncEnabledForNode.
@ManagedOperation(description = "Enable or disable synchronization completely for a node")
@ManagedOperationParameters({ @ManagedOperationParameter(name = "nodeId", description = "The node to enable or disable"), @ManagedOperationParameter(name = "syncEnabled", description = "true is enabled, false is disabled") })
public boolean setSyncEnabledForNode(String nodeId, boolean syncEnabled) {
Node node = engine.getNodeService().findNode(nodeId);
if (node != null) {
node.setSyncEnabled(syncEnabled);
engine.getNodeService().save(node);
return true;
} else {
return false;
}
}
use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.
the class ReportStatusJob method doJob.
@Override
void doJob(boolean force) throws Exception {
NetworkedNode remote = engine.getNodeService().getRootNetworkedNode();
Node identity = engine.getNodeService().findIdentity();
if (remote.getNode().getNodeId().equals(identity.getNodeId())) {
log.debug("Skipping report status job because this node is the root node. identity={}, remote={}", identity, remote);
return;
}
Map<String, Integer> batchCountPerChannel = engine.getOutgoingBatchService().countOutgoingBatchesPendingByChannel(remote.getNode().getNodeId());
log.debug("identity={} batchCountPerChannel='{}', lastBatchCountPerChannel='{}'", identity, batchCountPerChannel, lastBatchCountPerChannel);
if (force || shouldSendStatus(batchCountPerChannel)) {
Map<String, String> requestParams = new HashMap<String, String>();
requestParams.put(WebConstants.BATCH_TO_SEND_COUNT, TransportUtils.toCSV(batchCountPerChannel));
engine.getTransportManager().sendStatusRequest(identity, requestParams);
updateLastSentStatus(batchCountPerChannel);
}
}
use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.
the class DataExtractorService method extract.
protected List<OutgoingBatch> extract(final ProcessInfo processInfo, final Node targetNode, final List<OutgoingBatch> activeBatches, final IDataWriter dataWriter, final BufferedWriter writer, final ExtractMode mode) {
if (activeBatches.size() > 0) {
final List<OutgoingBatch> processedBatches = new ArrayList<OutgoingBatch>(activeBatches.size());
Set<String> channelsProcessed = new HashSet<String>();
long batchesSelectedAtMs = System.currentTimeMillis();
OutgoingBatch currentBatch = null;
ExecutorService executor = null;
try {
final boolean streamToFileEnabled = parameterService.is(ParameterConstants.STREAM_TO_FILE_ENABLED);
long keepAliveMillis = parameterService.getLong(ParameterConstants.DATA_LOADER_SEND_ACK_KEEPALIVE);
Node sourceNode = nodeService.findIdentity();
final FutureExtractStatus status = new FutureExtractStatus();
executor = Executors.newFixedThreadPool(1, new CustomizableThreadFactory(String.format("dataextractor-%s-%s", targetNode.getNodeGroupId(), targetNode.getNodeGroupId())));
List<Future<FutureOutgoingBatch>> futures = new ArrayList<Future<FutureOutgoingBatch>>();
processInfo.setBatchCount(activeBatches.size());
for (int i = 0; i < activeBatches.size(); i++) {
currentBatch = activeBatches.get(i);
processInfo.setCurrentLoadId(currentBatch.getLoadId());
processInfo.setDataCount(currentBatch.getDataEventCount());
processInfo.setCurrentBatchId(currentBatch.getBatchId());
channelsProcessed.add(currentBatch.getChannelId());
currentBatch = requeryIfEnoughTimeHasPassed(batchesSelectedAtMs, currentBatch);
processInfo.setStatus(ProcessInfo.Status.EXTRACTING);
final OutgoingBatch extractBatch = currentBatch;
Callable<FutureOutgoingBatch> callable = new Callable<FutureOutgoingBatch>() {
public FutureOutgoingBatch call() throws Exception {
return extractBatch(extractBatch, status, processInfo, targetNode, dataWriter, mode, activeBatches);
}
};
if (status.shouldExtractSkip) {
break;
}
futures.add(executor.submit(callable));
}
if (parameterService.is(ParameterConstants.SYNCHRONIZE_ALL_JOBS)) {
executor.shutdown();
boolean isProcessed = false;
while (!isProcessed) {
try {
isProcessed = executor.awaitTermination(keepAliveMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!isProcessed) {
writeKeepAliveAck(writer, sourceNode, streamToFileEnabled);
}
}
}
Iterator<OutgoingBatch> activeBatchIter = activeBatches.iterator();
for (Future<FutureOutgoingBatch> future : futures) {
currentBatch = activeBatchIter.next();
boolean isProcessed = false;
while (!isProcessed) {
try {
FutureOutgoingBatch extractBatch = future.get(keepAliveMillis, TimeUnit.MILLISECONDS);
currentBatch = extractBatch.getOutgoingBatch();
if (extractBatch.isExtractSkipped) {
break;
}
if (streamToFileEnabled || mode == ExtractMode.FOR_PAYLOAD_CLIENT) {
processInfo.setStatus(ProcessInfo.Status.TRANSFERRING);
processInfo.setCurrentLoadId(currentBatch.getLoadId());
boolean isRetry = extractBatch.isRetry() && extractBatch.getOutgoingBatch().getStatus() != OutgoingBatch.Status.IG;
currentBatch = sendOutgoingBatch(processInfo, targetNode, currentBatch, isRetry, dataWriter, writer, mode);
}
processedBatches.add(currentBatch);
isProcessed = true;
if (currentBatch.getStatus() != Status.OK) {
currentBatch.setLoadCount(currentBatch.getLoadCount() + 1);
changeBatchStatus(Status.LD, currentBatch, mode);
}
} catch (ExecutionException e) {
if (isNotBlank(e.getMessage()) && e.getMessage().contains("string truncation")) {
throw new RuntimeException("There is a good chance that the truncation error you are receiving is because contains_big_lobs on the '" + currentBatch.getChannelId() + "' channel needs to be turned on.", e.getCause() != null ? e.getCause() : e);
}
throw new RuntimeException(e.getCause() != null ? e.getCause() : e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
writeKeepAliveAck(writer, sourceNode, streamToFileEnabled);
}
}
}
} catch (RuntimeException e) {
SQLException se = unwrapSqlException(e);
if (currentBatch != null) {
try {
/* Reread batch in case the ignore flag has been set */
currentBatch = outgoingBatchService.findOutgoingBatch(currentBatch.getBatchId(), currentBatch.getNodeId());
statisticManager.incrementDataExtractedErrors(currentBatch.getChannelId(), 1);
if (se != null) {
currentBatch.setSqlState(se.getSQLState());
currentBatch.setSqlCode(se.getErrorCode());
currentBatch.setSqlMessage(se.getMessage());
} else {
currentBatch.setSqlMessage(getRootMessage(e));
}
currentBatch.revertStatsOnError();
if (currentBatch.getStatus() != Status.IG && currentBatch.getStatus() != Status.OK) {
currentBatch.setStatus(Status.ER);
currentBatch.setErrorFlag(true);
}
outgoingBatchService.updateOutgoingBatch(currentBatch);
} catch (Exception ex) {
log.error("Failed to update the outgoing batch status for failed batch {}", currentBatch, ex);
} finally {
if (!isStreamClosedByClient(e)) {
if (e instanceof ProtocolException) {
IStagedResource resource = getStagedResource(currentBatch);
if (resource != null) {
resource.delete();
}
}
if (e.getCause() instanceof InterruptedException) {
log.info("Extract of batch {} was interrupted", currentBatch);
} else {
log.error("Failed to extract batch {}", currentBatch, e);
}
}
processInfo.setStatus(ProcessInfo.Status.ERROR);
}
} else {
log.error("Could not log the outgoing batch status because the batch was null", e);
}
} finally {
if (executor != null) {
executor.shutdown();
}
}
// Next, we update the node channel controls to the
// current timestamp
Calendar now = Calendar.getInstance();
for (String channelProcessed : channelsProcessed) {
NodeChannel nodeChannel = configurationService.getNodeChannel(channelProcessed, targetNode.getNodeId(), false);
if (nodeChannel != null && nodeChannel.getExtractPeriodMillis() > 0) {
nodeChannel.setLastExtractTime(now.getTime());
configurationService.updateLastExtractTime(nodeChannel);
}
}
return processedBatches;
} else {
return Collections.emptyList();
}
}
use of org.jumpmind.symmetric.model.Node in project symmetric-ds by JumpMind.
the class DataExtractorService method extractBatchRange.
public boolean extractBatchRange(Writer writer, String nodeId, Date startBatchTime, Date endBatchTime, String... channelIds) {
boolean foundBatch = false;
Node sourceNode = nodeService.findIdentity();
OutgoingBatches batches = outgoingBatchService.getOutgoingBatchRange(nodeId, startBatchTime, endBatchTime, channelIds);
List<OutgoingBatch> list = batches.getBatches();
for (OutgoingBatch outgoingBatch : list) {
Node targetNode = nodeService.findNode(nodeId);
if (targetNode == null && Constants.UNROUTED_NODE_ID.equals(nodeId)) {
targetNode = new Node();
targetNode.setNodeId("-1");
}
if (targetNode != null) {
IDataReader dataReader = new ExtractDataReader(symmetricDialect.getPlatform(), new SelectFromSymDataSource(outgoingBatch, sourceNode, targetNode, new ProcessInfo()));
DataContext ctx = new DataContext();
ctx.put(Constants.DATA_CONTEXT_TARGET_NODE, targetNode);
ctx.put(Constants.DATA_CONTEXT_SOURCE_NODE, nodeService.findIdentity());
new DataProcessor(dataReader, createTransformDataWriter(nodeService.findIdentity(), targetNode, new ProtocolDataWriter(nodeService.findIdentityNodeId(), writer, targetNode.requires13Compatiblity())), "extract range").process(ctx);
foundBatch = true;
}
}
return foundBatch;
}
Aggregations