Search in sources :

Example 1 with ProcessMonitor

use of org.exist.storage.ProcessMonitor in project exist by eXist-db.

the class ResourceFunctionExecutorImpl method execute.

@Override
public Sequence execute(final ResourceFunction resourceFunction, final Iterable<TypedArgumentValue> arguments, final HttpRequest request) throws RestXqServiceException {
    final RestXqServiceCompiledXQueryCache cache = RestXqServiceCompiledXQueryCacheImpl.getInstance();
    CompiledXQuery xquery = null;
    ProcessMonitor processMonitor = null;
    try (final DBBroker broker = getBrokerPool().getBroker()) {
        // ensure we can execute the function before going any further
        checkSecurity(broker, resourceFunction.getXQueryLocation());
        // get a compiled query service from the cache
        xquery = cache.getCompiledQuery(broker, resourceFunction.getXQueryLocation());
        // find the function that we will execute
        final UserDefinedFunction fn = findFunction(xquery, resourceFunction.getFunctionSignature());
        final XQueryContext xqueryContext = xquery.getContext();
        // set the request object - can later be used by the EXQuery Request Module
        xqueryContext.setAttribute(EXQ_REQUEST_ATTR, request);
        // TODO this is a workaround?
        declareVariables(xqueryContext);
        // START workaround: evaluate global variables in modules, as they are reset by XQueryContext.reset()
        final Expression rootExpr = xqueryContext.getRootExpression();
        for (int i = 0; i < rootExpr.getSubExpressionCount(); i++) {
            final Expression subExpr = rootExpr.getSubExpression(i);
            if (subExpr instanceof VariableDeclaration) {
                subExpr.eval(null);
            }
        }
        // END workaround
        // setup monitoring
        processMonitor = broker.getBrokerPool().getProcessMonitor();
        xqueryContext.getProfiler().traceQueryStart();
        processMonitor.queryStarted(xqueryContext.getWatchDog());
        // create a function call
        try (final FunctionReference fnRef = new FunctionReference(new FunctionCall(xqueryContext, fn))) {
            // convert the arguments
            final org.exist.xquery.value.Sequence[] fnArgs = convertToExistFunctionArguments(xqueryContext, fn, arguments);
            // execute the function call
            fnRef.analyze(new AnalyzeContextInfo());
            // if setUid/setGid, determine the effectiveSubject to use for execution
            final Optional<EffectiveSubject> effectiveSubject = getEffectiveSubject(xquery);
            try {
                // switch to effective user if setUid/setGid
                effectiveSubject.ifPresent(broker::pushSubject);
                final org.exist.xquery.value.Sequence result = fnRef.evalFunction(null, null, fnArgs);
                // copy for closure
                final CompiledXQuery xquery1 = xquery;
                // return a sequence adapter which returns the query when it is finished with the results
                return new SequenceAdapter(result, () -> {
                    if (xquery1 != null) {
                        // return the compiled query to the pool
                        cache.returnCompiledQuery(resourceFunction.getXQueryLocation(), xquery1);
                    }
                });
            } finally {
                // switch back from effective user if setUid/setGid
                if (effectiveSubject.isPresent()) {
                    broker.popSubject();
                }
            }
        }
    } catch (final URISyntaxException | EXistException | XPathException | PermissionDeniedException use) {
        // if an error occurred we should return the compiled query
        if (xquery != null) {
            // return the compiled query to the pool
            cache.returnCompiledQuery(resourceFunction.getXQueryLocation(), xquery);
        }
        throw new RestXqServiceException(use.getMessage(), use);
    } finally {
        // clear down monitoring
        if (processMonitor != null) {
            xquery.getContext().getProfiler().traceQueryEnd(xquery.getContext());
            processMonitor.queryCompleted(xquery.getContext().getWatchDog());
        }
    }
}
Also used : RestXqServiceCompiledXQueryCache(org.exist.extensions.exquery.restxq.RestXqServiceCompiledXQueryCache) RestXqServiceException(org.exquery.restxq.RestXqServiceException) SequenceAdapter(org.exist.extensions.exquery.restxq.impl.adapters.SequenceAdapter) URISyntaxException(java.net.URISyntaxException) FunctionReference(org.exist.xquery.value.FunctionReference) EffectiveSubject(org.exist.security.EffectiveSubject) org.exist.xquery(org.exist.xquery) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exquery.xquery.Sequence) EXistException(org.exist.EXistException) ProcessMonitor(org.exist.storage.ProcessMonitor) DBBroker(org.exist.storage.DBBroker) PermissionDeniedException(org.exist.security.PermissionDeniedException)

Example 2 with ProcessMonitor

use of org.exist.storage.ProcessMonitor in project exist by eXist-db.

the class GetRunningJobs method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    if (!context.getSubject().hasDbaRole()) {
        throw (new XPathException(this, "Permission denied, calling user '" + context.getSubject().getName() + "' must be a DBA to get the list of running jobs"));
    }
    context.pushDocumentContext();
    try {
        final MemTreeBuilder builder = context.getDocumentBuilder();
        builder.startDocument();
        builder.startElement(new QName("jobs", NAMESPACE_URI, PREFIX), null);
        final BrokerPool brokerPool = context.getBroker().getBrokerPool();
        final ProcessMonitor monitor = brokerPool.getProcessMonitor();
        final ProcessMonitor.JobInfo[] jobs = monitor.runningJobs();
        for (ProcessMonitor.JobInfo job : jobs) {
            final Thread process = job.getThread();
            final Date startDate = new Date(job.getStartTime());
            builder.startElement(new QName("job", NAMESPACE_URI, PREFIX), null);
            builder.addAttribute(new QName("id", null, null), process.getName());
            builder.addAttribute(new QName("action", null, null), job.getAction());
            builder.addAttribute(new QName("start", null, null), new DateTimeValue(startDate).getStringValue());
            builder.addAttribute(new QName("info", null, null), job.getAddInfo().toString());
            builder.endElement();
        }
        builder.endElement();
        builder.endDocument();
        return (NodeValue) builder.getDocument().getDocumentElement();
    } finally {
        context.popDocumentContext();
    }
}
Also used : NodeValue(org.exist.xquery.value.NodeValue) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder) DateTimeValue(org.exist.xquery.value.DateTimeValue) XPathException(org.exist.xquery.XPathException) QName(org.exist.dom.QName) ProcessMonitor(org.exist.storage.ProcessMonitor) BrokerPool(org.exist.storage.BrokerPool) Date(java.util.Date)

Example 3 with ProcessMonitor

use of org.exist.storage.ProcessMonitor in project exist by eXist-db.

the class SMEvents method runScript.

protected void runScript(Subject subject, String scriptURI, String script, QName functionName, List<Expression> args) {
    final Database db = getDatabase();
    try (final DBBroker broker = db.get(Optional.ofNullable(subject))) {
        final Source source = getQuerySource(broker, scriptURI, script);
        if (source == null) {
            return;
        }
        final XQuery xquery = broker.getBrokerPool().getXQueryService();
        final XQueryContext context = new XQueryContext(broker.getBrokerPool());
        final CompiledXQuery compiled = xquery.compile(context, source);
        // Sequence result = xquery.execute(compiled, subject.getName());
        final ProcessMonitor pm = db.getProcessMonitor();
        // execute the XQuery
        try {
            final UserDefinedFunction function = context.resolveFunction(functionName, 0);
            if (function != null) {
                context.getProfiler().traceQueryStart();
                pm.queryStarted(context.getWatchDog());
                final FunctionCall call = new FunctionCall(context, function);
                if (args != null) {
                    call.setArguments(args);
                }
                final Sequence contextSequence;
                final ContextItemDeclaration cid = context.getContextItemDeclartion();
                if (cid != null) {
                    contextSequence = cid.eval(null);
                } else {
                    contextSequence = NodeSet.EMPTY_SET;
                }
                call.analyze(new AnalyzeContextInfo());
                call.eval(contextSequence);
            }
        } catch (final XPathException e) {
            // XXX: log
            e.printStackTrace();
        } finally {
            if (pm != null) {
                context.getProfiler().traceQueryEnd(context);
                pm.queryCompleted(context.getWatchDog());
            }
            compiled.reset();
            context.reset();
        }
    } catch (final Exception e) {
        // XXX: log
        e.printStackTrace();
    }
}
Also used : Sequence(org.exist.xquery.value.Sequence) ProcessMonitor(org.exist.storage.ProcessMonitor) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) DBSource(org.exist.source.DBSource) PermissionDeniedException(org.exist.security.PermissionDeniedException) DBBroker(org.exist.storage.DBBroker) Database(org.exist.Database)

Example 4 with ProcessMonitor

use of org.exist.storage.ProcessMonitor in project exist by eXist-db.

the class XQueryTrigger method execute.

private void execute(boolean isBefore, DBBroker broker, Txn transaction, QName functionName, XmldbURI src, XmldbURI dst) throws TriggerException {
    final CompiledXQuery compiledQuery = getScript(isBefore, broker, transaction, src);
    if (compiledQuery == null) {
        return;
    }
    ProcessMonitor pm = null;
    final XQueryContext context = compiledQuery.getContext();
    // execute the XQuery
    try {
        int nParams = 1;
        if (dst != null)
            nParams = 2;
        final UserDefinedFunction function = context.resolveFunction(functionName, nParams);
        if (function != null) {
            final List<Expression> args = new ArrayList<>(nParams);
            if (isBefore) {
                args.add(new LiteralValue(context, new AnyURIValue(src)));
                if (dst != null)
                    args.add(new LiteralValue(context, new AnyURIValue(dst)));
            } else {
                if (dst != null)
                    args.add(new LiteralValue(context, new AnyURIValue(dst)));
                args.add(new LiteralValue(context, new AnyURIValue(src)));
            }
            pm = broker.getBrokerPool().getProcessMonitor();
            context.getProfiler().traceQueryStart();
            pm.queryStarted(context.getWatchDog());
            final FunctionCall call = new FunctionCall(context, function);
            call.setArguments(args);
            call.analyze(new AnalyzeContextInfo());
            final Sequence contextSequence;
            final ContextItemDeclaration cid = call.getContext().getContextItemDeclartion();
            if (cid != null) {
                contextSequence = cid.eval(null);
            } else {
                contextSequence = NodeSet.EMPTY_SET;
            }
            call.eval(contextSequence);
        }
    } catch (final XPathException e) {
        TriggerStatePerThread.setTriggerRunningState(TriggerStatePerThread.NO_TRIGGER_RUNNING, this, null);
        TriggerStatePerThread.setTransaction(null);
        throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
    } finally {
        if (pm != null) {
            context.getProfiler().traceQueryEnd(context);
            pm.queryCompleted(context.getWatchDog());
        }
        compiledQuery.reset();
        context.reset();
    }
    if (!isBefore) {
        TriggerStatePerThread.setTriggerRunningState(TriggerStatePerThread.NO_TRIGGER_RUNNING, this, null);
        TriggerStatePerThread.setTransaction(null);
        LOG.debug("Trigger fired 'after'");
    } else {
        LOG.debug("Trigger fired 'before'");
    }
}
Also used : AnyURIValue(org.exist.xquery.value.AnyURIValue) ArrayList(java.util.ArrayList) Sequence(org.exist.xquery.value.Sequence) ProcessMonitor(org.exist.storage.ProcessMonitor)

Aggregations

ProcessMonitor (org.exist.storage.ProcessMonitor)4 PermissionDeniedException (org.exist.security.PermissionDeniedException)2 DBBroker (org.exist.storage.DBBroker)2 Sequence (org.exist.xquery.value.Sequence)2 URISyntaxException (java.net.URISyntaxException)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 Database (org.exist.Database)1 EXistException (org.exist.EXistException)1 QName (org.exist.dom.QName)1 MemTreeBuilder (org.exist.dom.memtree.MemTreeBuilder)1 RestXqServiceCompiledXQueryCache (org.exist.extensions.exquery.restxq.RestXqServiceCompiledXQueryCache)1 SequenceAdapter (org.exist.extensions.exquery.restxq.impl.adapters.SequenceAdapter)1 EffectiveSubject (org.exist.security.EffectiveSubject)1 DBSource (org.exist.source.DBSource)1 Source (org.exist.source.Source)1 StringSource (org.exist.source.StringSource)1 BrokerPool (org.exist.storage.BrokerPool)1 org.exist.xquery (org.exist.xquery)1 XPathException (org.exist.xquery.XPathException)1