use of org.exist.storage.DBBroker 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.DBBroker in project exist by eXist-db.
the class RestXqServiceSerializerImpl method serializeNodeBody.
@Override
protected void serializeNodeBody(final Sequence result, final HttpResponse response, final Map<SerializationProperty, String> serializationProperties) throws RestXqServiceException {
try (final DBBroker broker = getBrokerPool().getBroker();
final Writer writer = new OutputStreamWriter(response.getOutputStream(), serializationProperties.get(SerializationProperty.ENCODING))) {
final Properties outputProperties = serializationPropertiesToProperties(serializationProperties);
final XQuerySerializer xqSerializer = new XQuerySerializer(broker, outputProperties, writer);
xqSerializer.serialize(((SequenceAdapter) result).getExistSequence());
writer.flush();
} catch (IOException | XPathException | SAXException | EXistException ioe) {
throw new RestXqServiceException("Error while serializing xml: " + ioe.toString(), ioe);
}
}
use of org.exist.storage.DBBroker in project exist by eXist-db.
the class RestXqServlet method service.
@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
// authenticate
final Subject user = authenticate(request, response);
if (user == null) {
// "Permission denied: unknown user or password");
return;
}
try (final DBBroker broker = getPool().get(Optional.of(user))) {
final Configuration configuration = broker.getConfiguration();
final HttpRequest requestAdapter = new HttpServletRequestAdapter(request, () -> (String) configuration.getProperty(Configuration.BINARY_CACHE_CLASS_PROPERTY));
final RestXqService service = getRegistry().findService(requestAdapter);
if (service != null) {
if (log.isTraceEnabled()) {
log.trace("Received {} request for \"{}\" and found Resource Function \"{}\" in module \"{}\"", requestAdapter.getMethod().name(), requestAdapter.getPath(), service.getResourceFunction().getFunctionSignature(), service.getResourceFunction().getXQueryLocation());
}
service.service(requestAdapter, new HttpServletResponseAdapter(response), new ResourceFunctionExecutorImpl(getPool(), request.getContextPath() + request.getServletPath(), request.getRequestURI()), new RestXqServiceSerializerImpl(getPool()));
} else {
if (log.isTraceEnabled()) {
log.trace("Received {} request for \"{}\" but no suitable Resource Function found!", requestAdapter.getMethod().name(), requestAdapter.getPath());
}
super.service(request, response);
}
} catch (final EXistException e) {
getLog().error(e.getMessage(), e);
throw new ServletException(e.getMessage(), e);
} catch (final RestXqServiceException e) {
if (e.getCause() instanceof PermissionDeniedException) {
getAuthenticator().sendChallenge(request, response);
} else {
// TODO should probably be caught higher up and returned as a HTTP Response? maybe need two different types of exception to differentiate critical vs processing exception
getLog().error(e.getMessage(), e);
throw new ServletException(e.getMessage(), e);
}
}
}
use of org.exist.storage.DBBroker in project exist by eXist-db.
the class SendEmailIT method sendEmailJavaMail.
@Test
public void sendEmailJavaMail() throws EXistException, XPathException, PermissionDeniedException, IOException, MessagingException {
final String from = "sender@place1.com";
final String to = "recipient@place2.com";
final String subject = "some email subject";
final String messageText = UUIDGenerator.getUUIDversion4();
final String query = "import module namespace mail = \"http://exist-db.org/xquery/mail\";\n" + "let $session := mail:get-mail-session(\n" + " <properties>\n" + " <property name=\"mail.transport.protocol\" value=\"smtp\"/>\n" + " <property name=\"mail.smtp.port\" value=\"" + smtpPort + "\"/>\n" + " <property name=\"mail.smtp.host\" value=\"127.0.0.1\"/>\n" + " </properties>\n" + ")\n" + "return\n" + " mail:send-email(\n" + " $session,\n" + " <mail><from>" + from + "</from><to>" + to + "</to><subject>" + subject + "</subject><message><text>" + messageText + "</text></message></mail>\n" + " )";
// send the email from XQuery via SMTP
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final Source source = new StringSource(query);
try (final DBBroker broker = pool.getBroker();
final Txn transaction = pool.getTransactionManager().beginTransaction()) {
// execute query
final Boolean sendResult = withCompiledQuery(broker, source, compiledXQuery -> {
executeQuery(broker, compiledXQuery);
return true;
});
transaction.commit();
assertTrue(sendResult.booleanValue());
}
// check the SMTP server received the email
final MimeMessage[] receivedMessages = greenMail.getReceivedMessages();
assertEquals(1, receivedMessages.length);
final MimeMessage receivedMessage = receivedMessages[0];
// final Address sender = receivedMessage.getSender();
// assertEquals(from, sender.toString());
final Address[] recipients = receivedMessage.getRecipients(Message.RecipientType.TO);
assertEquals(1, recipients.length);
assertEquals(to, recipients[0].toString());
assertEquals(subject, receivedMessage.getSubject());
assertEquals(messageText, GreenMailUtil.getBody(receivedMessage));
}
use of org.exist.storage.DBBroker in project exist by eXist-db.
the class SendEmailIT method sendEmailSmtpDirect.
@Test
public void sendEmailSmtpDirect() throws EXistException, XPathException, PermissionDeniedException, IOException, MessagingException {
final String from = "sender@place1.com";
final String to = "recipient@place2.com";
final String subject = "some email subject";
final String messageText = UUIDGenerator.getUUIDversion4();
final String query = "import module namespace mail = \"http://exist-db.org/xquery/mail\";\n" + "mail:send-email(\n" + " <mail><from>" + from + "</from><to>" + to + "</to><subject>" + subject + "</subject><message><text>" + messageText + "</text></message></mail>,\n" + " '127.0.0.1:" + smtpPort + "',\n" + " ()\n" + ")";
// send the email from XQuery via SMTP
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final Source source = new StringSource(query);
try (final DBBroker broker = pool.getBroker();
final Txn transaction = pool.getTransactionManager().beginTransaction()) {
// execute query
final Boolean sendResult = withCompiledQuery(broker, source, compiledXQuery -> {
final Sequence result = executeQuery(broker, compiledXQuery);
return result.itemAt(0).toJavaObject(boolean.class);
});
transaction.commit();
assertTrue(sendResult.booleanValue());
}
// check the SMTP server received the email
final MimeMessage[] receivedMessages = greenMail.getReceivedMessages();
assertEquals(1, receivedMessages.length);
final MimeMessage receivedMessage = receivedMessages[0];
// final Address sender = receivedMessage.getSender();
// assertEquals(from, sender.toString());
final Address[] recipients = receivedMessage.getRecipients(Message.RecipientType.TO);
assertEquals(1, recipients.length);
assertEquals(to, recipients[0].toString());
assertEquals(subject, receivedMessage.getSubject());
assertEquals(messageText, GreenMailUtil.getBody(receivedMessage));
}
Aggregations