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());
}
}
}
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();
}
}
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();
}
}
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'");
}
}
Aggregations