Search in sources :

Example 1 with FileConflictException

use of org.jumpmind.symmetric.file.FileConflictException in project symmetric-ds by JumpMind.

the class FileSyncService method processZip.

protected List<IncomingBatch> processZip(InputStream is, String sourceNodeId, ProcessInfo processInfo) throws IOException {
    File unzipDir = new File(parameterService.getTempDirectory(), String.format("filesync_incoming/%s/%s", engine.getNodeService().findIdentityNodeId(), sourceNodeId));
    FileUtils.deleteDirectory(unzipDir);
    unzipDir.mkdirs();
    try {
        AppUtils.unzip(is, unzipDir);
    } catch (IoException ex) {
        if (ex.toString().contains("EOFException")) {
        // This happens on Android, when there is an empty zip.
        //log.debug("Caught exception while unzipping.", ex);
        } else {
            throw ex;
        }
    }
    Set<Long> batchIds = new TreeSet<Long>();
    String[] files = unzipDir.list(DirectoryFileFilter.INSTANCE);
    if (files != null) {
        for (int i = 0; i < files.length; i++) {
            try {
                batchIds.add(Long.parseLong(files[i]));
            } catch (NumberFormatException e) {
                log.error("Unexpected directory name.  Expected a number representing a batch id.  Instead the directory was named '{}'", files[i]);
            }
        }
    }
    List<IncomingBatch> batchesProcessed = new ArrayList<IncomingBatch>();
    IIncomingBatchService incomingBatchService = engine.getIncomingBatchService();
    processInfo.setStatus(ProcessInfo.Status.LOADING);
    for (Long batchId : batchIds) {
        processInfo.setCurrentBatchId(batchId);
        processInfo.incrementBatchCount();
        File batchDir = new File(unzipDir, Long.toString(batchId));
        IncomingBatch incomingBatch = new IncomingBatch();
        File batchInfo = new File(batchDir, "batch-info.txt");
        if (batchInfo.exists()) {
            List<String> info = FileUtils.readLines(batchInfo);
            if (info != null && info.size() > 0) {
                incomingBatch.setChannelId(info.get(0).trim());
            } else {
                incomingBatch.setChannelId(Constants.CHANNEL_FILESYNC);
            }
        } else {
            incomingBatch.setChannelId(Constants.CHANNEL_FILESYNC);
        }
        incomingBatch.setBatchId(batchId);
        incomingBatch.setStatus(IncomingBatch.Status.LD);
        incomingBatch.setNodeId(sourceNodeId);
        incomingBatch.setByteCount(FileUtils.sizeOfDirectory(batchDir));
        batchesProcessed.add(incomingBatch);
        if (incomingBatchService.acquireIncomingBatch(incomingBatch)) {
            File syncScript = new File(batchDir, "sync.bsh");
            if (syncScript.exists()) {
                String script = FileUtils.readFileToString(syncScript);
                Interpreter interpreter = new Interpreter();
                boolean isLocked = false;
                try {
                    setInterpreterVariables(engine, sourceNodeId, batchDir, interpreter);
                    long waitMillis = getParameterService().getLong(ParameterConstants.FILE_SYNC_LOCK_WAIT_MS);
                    log.debug("The {} node is attempting to get shared lock for to update incoming status", sourceNodeId);
                    isLocked = engine.getClusterService().lock(ClusterConstants.FILE_SYNC_SHARED, ClusterConstants.TYPE_SHARED, waitMillis);
                    if (isLocked) {
                        log.debug("The {} node got a shared file sync lock", sourceNodeId);
                        @SuppressWarnings("unchecked") Map<String, String> filesToEventType = (Map<String, String>) interpreter.eval(script);
                        if (engine.getParameterService().is(ParameterConstants.FILE_SYNC_PREVENT_PING_BACK)) {
                            updateFileIncoming(sourceNodeId, filesToEventType);
                        }
                        incomingBatch.setStatementCount(filesToEventType != null ? filesToEventType.size() : 0);
                    } else {
                        throw new RuntimeException("Could not obtain file sync shared lock within " + waitMillis + " millis");
                    }
                    incomingBatch.setStatus(IncomingBatch.Status.OK);
                    if (incomingBatchService.isRecordOkBatchesEnabled()) {
                        incomingBatchService.updateIncomingBatch(incomingBatch);
                    } else if (incomingBatch.isRetry()) {
                        incomingBatchService.deleteIncomingBatch(incomingBatch);
                    }
                } catch (Throwable ex) {
                    if (ex instanceof TargetError) {
                        Throwable target = ((TargetError) ex).getTarget();
                        if (target != null) {
                            ex = target;
                        }
                    } else if (ex instanceof EvalError) {
                        log.error("Failed to evalulate the script:\n{}", script);
                    }
                    if (ex instanceof FileConflictException) {
                        log.error(ex.getMessage() + ".  Failed to process file sync batch " + batchId);
                    } else {
                        log.error("Failed to process file sync batch " + batchId, ex);
                    }
                    incomingBatch.setErrorFlag(true);
                    incomingBatch.setStatus(IncomingBatch.Status.ER);
                    incomingBatch.setSqlMessage(ex.getMessage());
                    if (incomingBatchService.isRecordOkBatchesEnabled() || incomingBatch.isRetry()) {
                        incomingBatchService.updateIncomingBatch(incomingBatch);
                    } else {
                        incomingBatchService.insertIncomingBatch(incomingBatch);
                    }
                    processInfo.setStatus(ProcessInfo.Status.ERROR);
                    break;
                } finally {
                    log.debug("The {} node is done processing file sync files", sourceNodeId);
                    if (isLocked) {
                        engine.getClusterService().unlock(ClusterConstants.FILE_SYNC_SHARED, ClusterConstants.TYPE_SHARED);
                    }
                }
            } else {
                log.error("Could not find the sync.bsh script for batch {}", batchId);
            }
        }
    }
    return batchesProcessed;
}
Also used : ArrayList(java.util.ArrayList) TreeSet(java.util.TreeSet) IIncomingBatchService(org.jumpmind.symmetric.service.IIncomingBatchService) Interpreter(bsh.Interpreter) EvalError(bsh.EvalError) TargetError(bsh.TargetError) IncomingBatch(org.jumpmind.symmetric.model.IncomingBatch) IoException(org.jumpmind.exception.IoException) FileConflictException(org.jumpmind.symmetric.file.FileConflictException) File(java.io.File) Map(java.util.Map)

Aggregations

EvalError (bsh.EvalError)1 Interpreter (bsh.Interpreter)1 TargetError (bsh.TargetError)1 File (java.io.File)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 TreeSet (java.util.TreeSet)1 IoException (org.jumpmind.exception.IoException)1 FileConflictException (org.jumpmind.symmetric.file.FileConflictException)1 IncomingBatch (org.jumpmind.symmetric.model.IncomingBatch)1 IIncomingBatchService (org.jumpmind.symmetric.service.IIncomingBatchService)1