Search in sources :

Example 46 with DBBroker

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());
        }
    }
}
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 47 with DBBroker

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);
    }
}
Also used : DBBroker(org.exist.storage.DBBroker) RestXqServiceException(org.exquery.restxq.RestXqServiceException) XQuerySerializer(org.exist.util.serializer.XQuerySerializer) XPathException(org.exist.xquery.XPathException) OutputStreamWriter(java.io.OutputStreamWriter) IOException(java.io.IOException) EXistException(org.exist.EXistException) Properties(java.util.Properties) Writer(java.io.Writer) OutputStreamWriter(java.io.OutputStreamWriter) SAXException(org.xml.sax.SAXException)

Example 48 with DBBroker

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);
        }
    }
}
Also used : HttpRequest(org.exquery.http.HttpRequest) HttpServletResponseAdapter(org.exist.extensions.exquery.restxq.impl.adapters.HttpServletResponseAdapter) RestXqServiceException(org.exquery.restxq.RestXqServiceException) Configuration(org.exist.util.Configuration) EXistException(org.exist.EXistException) Subject(org.exist.security.Subject) ServletException(javax.servlet.ServletException) RestXqService(org.exquery.restxq.RestXqService) DBBroker(org.exist.storage.DBBroker) HttpServletRequestAdapter(org.exist.extensions.exquery.restxq.impl.adapters.HttpServletRequestAdapter) PermissionDeniedException(org.exist.security.PermissionDeniedException)

Example 49 with DBBroker

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));
}
Also used : DBBroker(org.exist.storage.DBBroker) Address(jakarta.mail.Address) MimeMessage(jakarta.mail.internet.MimeMessage) StringSource(org.exist.source.StringSource) Txn(org.exist.storage.txn.Txn) BrokerPool(org.exist.storage.BrokerPool) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) Test(org.junit.Test)

Example 50 with DBBroker

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));
}
Also used : DBBroker(org.exist.storage.DBBroker) Address(jakarta.mail.Address) MimeMessage(jakarta.mail.internet.MimeMessage) StringSource(org.exist.source.StringSource) Txn(org.exist.storage.txn.Txn) Sequence(org.exist.xquery.value.Sequence) BrokerPool(org.exist.storage.BrokerPool) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) Test(org.junit.Test)

Aggregations

DBBroker (org.exist.storage.DBBroker)468 BrokerPool (org.exist.storage.BrokerPool)304 Txn (org.exist.storage.txn.Txn)219 Sequence (org.exist.xquery.value.Sequence)185 Test (org.junit.Test)170 XQuery (org.exist.xquery.XQuery)108 Collection (org.exist.collections.Collection)93 TransactionManager (org.exist.storage.txn.TransactionManager)70 EXistException (org.exist.EXistException)66 StringInputSource (org.exist.util.StringInputSource)66 PermissionDeniedException (org.exist.security.PermissionDeniedException)44 Source (org.exist.source.Source)42 StringSource (org.exist.source.StringSource)41 XmldbURI (org.exist.xmldb.XmldbURI)41 CompiledXQuery (org.exist.xquery.CompiledXQuery)39 IOException (java.io.IOException)38 QName (org.exist.dom.QName)37 LockedDocument (org.exist.dom.persistent.LockedDocument)36 Database (org.exist.Database)35 XPathException (org.exist.xquery.XPathException)30