Search in sources :

Example 1 with TargetError

use of bsh.TargetError 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)

Example 2 with TargetError

use of bsh.TargetError in project symmetric-ds by JumpMind.

the class BshDatabaseWriterFilter method executeScripts.

@Override
protected void executeScripts(DataContext context, String key, Set<String> scripts, boolean isFailOnError) {
    Interpreter interpreter = getInterpreter(context);
    String currentScript = null;
    try {
        bind(interpreter, context, null, null, null);
        if (scripts != null) {
            for (String script : scripts) {
                currentScript = script;
                interpreter.eval(script);
            }
        }
    } catch (EvalError e) {
        if (e instanceof ParseException) {
            String errorMsg = String.format("Evaluation error while parsing the following beanshell script:\n\n%s\n\nThe error was on line %d and the error message was: %s", currentScript, e.getErrorLineNumber(), e.getMessage());
            log.error(errorMsg, e);
            if (isFailOnError) {
                throw new SymmetricException(errorMsg);
            }
        } else if (e instanceof TargetError) {
            Throwable target = ((TargetError) e).getTarget();
            String errorMsg = String.format("Evaluation error occured in the following beanshell script:\n\n%s\n\nThe error was on line %d", currentScript, e.getErrorLineNumber());
            log.error(errorMsg, target);
            if (isFailOnError) {
                if (target instanceof RuntimeException) {
                    throw (RuntimeException) target;
                } else {
                    throw new SymmetricException(target);
                }
            } else {
                log.error("Failed while evaluating script", target);
            }
        }
    }
}
Also used : Interpreter(bsh.Interpreter) SymmetricException(org.jumpmind.symmetric.SymmetricException) EvalError(bsh.EvalError) ParseException(bsh.ParseException) TargetError(bsh.TargetError)

Example 3 with TargetError

use of bsh.TargetError in project symmetric-ds by JumpMind.

the class BshColumnTransform method transform.

public NewAndOldValue transform(IDatabasePlatform platform, DataContext context, TransformColumn column, TransformedData data, Map<String, String> sourceValues, String newValue, String oldValue) throws IgnoreColumnException, IgnoreRowException {
    try {
        Interpreter interpreter = getInterpreter(context);
        interpreter.set("currentValue", newValue);
        interpreter.set("oldValue", oldValue);
        interpreter.set("channelId", context.getBatch().getChannelId());
        interpreter.set("includeOn", column.getIncludeOn());
        interpreter.set("sourceDmlType", data.getSourceDmlType());
        interpreter.set("sourceDmlTypeString", data.getSourceDmlType().toString());
        interpreter.set("transformedData", data);
        interpreter.set("transformColumn", column);
        Data csvData = (Data) context.get(Constants.DATA_CONTEXT_CURRENT_CSV_DATA);
        if (csvData != null && csvData.getTriggerHistory() != null) {
            interpreter.set("sourceSchemaName", csvData.getTriggerHistory().getSourceSchemaName());
            interpreter.set("sourceCatalogName", csvData.getTriggerHistory().getSourceCatalogName());
            interpreter.set("sourceTableName", csvData.getTriggerHistory().getSourceTableName());
        }
        for (String columnName : sourceValues.keySet()) {
            interpreter.set(columnName.toUpperCase(), sourceValues.get(columnName));
            interpreter.set(columnName, sourceValues.get(columnName));
        }
        String transformExpression = column.getTransformExpression();
        String globalScript = parameterService.getString(ParameterConstants.BSH_TRANSFORM_GLOBAL_SCRIPT);
        String methodName = String.format("transform_%d()", Math.abs(transformExpression.hashCode() + (globalScript == null ? 0 : globalScript.hashCode())));
        if (context.get(methodName) == null) {
            interpreter.set("log", log);
            interpreter.set("sqlTemplate", platform.getSqlTemplate());
            interpreter.set("context", context);
            interpreter.set("bshContext", bshContext);
            interpreter.set(DATA_CONTEXT_ENGINE, context.get(DATA_CONTEXT_ENGINE));
            interpreter.set(DATA_CONTEXT_TARGET_NODE, context.get(DATA_CONTEXT_TARGET_NODE));
            interpreter.set(DATA_CONTEXT_TARGET_NODE_ID, context.get(DATA_CONTEXT_TARGET_NODE_ID));
            interpreter.set(DATA_CONTEXT_TARGET_NODE_GROUP_ID, context.get(DATA_CONTEXT_TARGET_NODE_GROUP_ID));
            interpreter.set(DATA_CONTEXT_TARGET_NODE_EXTERNAL_ID, context.get(DATA_CONTEXT_TARGET_NODE_EXTERNAL_ID));
            interpreter.set(DATA_CONTEXT_SOURCE_NODE, context.get(DATA_CONTEXT_SOURCE_NODE));
            interpreter.set(DATA_CONTEXT_SOURCE_NODE_ID, context.get(DATA_CONTEXT_SOURCE_NODE_ID));
            interpreter.set(DATA_CONTEXT_SOURCE_NODE_GROUP_ID, context.get(DATA_CONTEXT_SOURCE_NODE_GROUP_ID));
            interpreter.set(DATA_CONTEXT_SOURCE_NODE_EXTERNAL_ID, context.get(DATA_CONTEXT_SOURCE_NODE_EXTERNAL_ID));
            if (StringUtils.isNotBlank(globalScript)) {
                interpreter.eval(globalScript);
            }
            interpreter.eval(String.format("%s {\n%s\n}", methodName, transformExpression));
            context.put(methodName, Boolean.TRUE);
        }
        Object result = interpreter.eval(methodName);
        if (csvData != null && csvData.getTriggerHistory() != null) {
            interpreter.unset("sourceSchemaName");
            interpreter.unset("sourceCatalogName");
            interpreter.unset("sourceTableName");
        }
        for (String columnName : sourceValues.keySet()) {
            interpreter.unset(columnName.toUpperCase());
            interpreter.unset(columnName);
        }
        if (result instanceof String) {
            return new NewAndOldValue((String) result, null);
        } else if (result instanceof NewAndOldValue) {
            return (NewAndOldValue) result;
        } else if (result != null) {
            return new NewAndOldValue(result.toString(), null);
        } else {
            return null;
        }
    } catch (TargetError evalEx) {
        Throwable ex = evalEx.getTarget();
        if (ex instanceof IgnoreColumnException) {
            throw (IgnoreColumnException) ex;
        } else if (ex instanceof IgnoreRowException) {
            throw (IgnoreRowException) ex;
        } else {
            throw new TransformColumnException(String.format("Beanshell script error on line %d for target column %s on transform %s", evalEx.getErrorLineNumber(), column.getTargetColumnName(), column.getTransformId()), ex);
        }
    } catch (Exception ex) {
        if (ex instanceof IgnoreColumnException) {
            throw (IgnoreColumnException) ex;
        } else if (ex instanceof IgnoreRowException) {
            throw (IgnoreRowException) ex;
        } else {
            log.error(String.format("Beanshell script error for target column %s on transform %s", column.getTargetColumnName(), column.getTransformId()), ex);
            throw new TransformColumnException(ex);
        }
    }
}
Also used : Interpreter(bsh.Interpreter) Data(org.jumpmind.symmetric.model.Data) TargetError(bsh.TargetError)

Example 4 with TargetError

use of bsh.TargetError in project symmetric-ds by JumpMind.

the class BshDataRouter method routeToNodes.

public Set<String> routeToNodes(SimpleRouterContext context, DataMetaData dataMetaData, Set<Node> nodes, boolean initialLoad, boolean initialLoadSelectUsed, TriggerRouter triggerRouter) {
    Set<String> boundVariableNames = new LinkedHashSet<String>();
    try {
        long ts = System.currentTimeMillis();
        Interpreter interpreter = getInterpreter(context);
        context.incrementStat(System.currentTimeMillis() - ts, "bsh.init.ms");
        HashSet<String> targetNodes = new HashSet<String>();
        ts = System.currentTimeMillis();
        bind(interpreter, dataMetaData, nodes, targetNodes, boundVariableNames, initialLoad);
        context.incrementStat(System.currentTimeMillis() - ts, "bsh.bind.ms");
        ts = System.currentTimeMillis();
        Object returnValue = interpreter.eval(dataMetaData.getRouter().getRouterExpression());
        context.incrementStat(System.currentTimeMillis() - ts, "bsh.eval.ms");
        return eval(returnValue, nodes, targetNodes);
    } catch (EvalError e) {
        if (e instanceof TargetError) {
            Throwable t = ((TargetError) e).getTarget();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new RuntimeException("Routing script failed at line " + ((TargetError) e).getErrorLineNumber(), t);
            }
        } else {
            throw new RuntimeException("Failed to evaluate bsh router script.  Bound variables were: " + boundVariableNames, e);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Interpreter(bsh.Interpreter) EvalError(bsh.EvalError) TargetError(bsh.TargetError) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 5 with TargetError

use of bsh.TargetError in project symmetric-ds by JumpMind.

the class DefaultNodeIdCreator method evaluateScript.

protected String evaluateScript(Node node, String remoteHost, String remoteAddress) {
    String script = parameterService.getString(ParameterConstants.NODE_ID_CREATOR_SCRIPT);
    if (StringUtils.isNotBlank(script)) {
        try {
            Interpreter interpreter = new Interpreter();
            interpreter.set("node", node);
            interpreter.set("hostname", remoteHost);
            interpreter.set("remoteHost", remoteHost);
            interpreter.set("remoteAddress", remoteAddress);
            interpreter.set("log", log);
            Object retValue = interpreter.eval(script);
            if (retValue != null) {
                return retValue.toString();
            }
        } catch (TargetError e) {
            if (e.getTarget() instanceof RuntimeException) {
                throw (RuntimeException) e.getTarget();
            } else {
                throw new RuntimeException(e.getTarget() != null ? e.getTarget() : e);
            }
        } catch (EvalError e) {
            log.error("Failed to evalute node id generator script.  The default node id generation mechanism will be used.", e);
        }
    }
    return null;
}
Also used : Interpreter(bsh.Interpreter) EvalError(bsh.EvalError) TargetError(bsh.TargetError)

Aggregations

Interpreter (bsh.Interpreter)5 TargetError (bsh.TargetError)5 EvalError (bsh.EvalError)4 ParseException (bsh.ParseException)1 File (java.io.File)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1 TreeSet (java.util.TreeSet)1 IoException (org.jumpmind.exception.IoException)1 SymmetricException (org.jumpmind.symmetric.SymmetricException)1 FileConflictException (org.jumpmind.symmetric.file.FileConflictException)1 Data (org.jumpmind.symmetric.model.Data)1 IncomingBatch (org.jumpmind.symmetric.model.IncomingBatch)1 IIncomingBatchService (org.jumpmind.symmetric.service.IIncomingBatchService)1