use of org.exist.storage.txn.Txn 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));
}
use of org.exist.storage.txn.Txn in project exist by eXist-db.
the class ConnectionIT method getConnectionCanBeExplicitlyClosed.
@Test
public void getConnectionCanBeExplicitlyClosed() throws EXistException, XPathException, PermissionDeniedException, IOException {
final String query = "import module namespace sql = \"http://exist-db.org/xquery/sql\";\n" + "let $conn := sql:get-connection(\"" + h2Database.getDriverClass().getName() + "\", \"" + h2Database.getUrl() + "\", \"" + h2Database.getUser() + "\", \"" + h2Database.getPassword() + "\")\n" + "return sql:close-connection($conn)";
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 Tuple2<XQueryContext, Boolean> contextAndResult = withCompiledQuery(broker, source, compiledXQuery -> {
final Sequence result = executeQuery(broker, compiledXQuery);
return Tuple(compiledXQuery.getContext(), result.itemAt(0).toJavaObject(boolean.class));
});
// check that the handle for the sql connection was closed
assertTrue(contextAndResult._2);
// check the connections were closed
final int connectionsCount = ModuleUtils.readContextMap(contextAndResult._1, SQLModule.CONNECTIONS_CONTEXTVAR, Map::size);
assertEquals(0, connectionsCount);
transaction.commit();
}
}
use of org.exist.storage.txn.Txn in project exist by eXist-db.
the class ImplicitConnectionCloseIT method getJndiConnectionIsAutomaticallyClosed.
@Test
public void getJndiConnectionIsAutomaticallyClosed() throws EXistException, XPathException, PermissionDeniedException, IOException {
final String mainQuery = "import module namespace sql = \"http://exist-db.org/xquery/sql\";\n" + "sql:get-jndi-connection(\"" + JNDI_DS_NAME + "\", \"" + STUB_JDBC_USER + "\", \"" + STUB_JDBC_PASSWORD + "\")";
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final Source mainQuerySource = new StringSource(mainQuery);
try (final DBBroker broker = pool.getBroker();
final Txn transaction = pool.getTransactionManager().beginTransaction()) {
final XQueryContext escapedMainQueryContext = withCompiledQuery(broker, mainQuerySource, mainCompiledQuery -> {
final XQueryContext mainQueryContext = mainCompiledQuery.getContext();
// execute the query
final Sequence result = executeQuery(broker, mainCompiledQuery);
// check that the handle for the sql connection that was created was valid
assertEquals(1, result.getItemCount());
assertTrue(result.itemAt(0) instanceof IntegerValue);
assertEquals(Type.LONG, result.itemAt(0).getType());
final long connectionHandle = result.itemAt(0).toJavaObject(long.class);
assertFalse(connectionHandle == 0);
return mainQueryContext;
});
// check the connections map is empty
final int connectionsCount = ModuleUtils.readContextMap(escapedMainQueryContext, SQLModule.CONNECTIONS_CONTEXTVAR, Map::size);
assertEquals(0, connectionsCount);
// check the connections from our StubDataSource, they should all be closed
final Deque<StubDataSource> createdDataSources = StubDataSourceFactory.CREATED_DATA_SOURCES;
assertEquals(1, createdDataSources.size());
final StubDataSource stubDataSource = createdDataSources.peek();
final Deque<StubConnection> createdConnections = stubDataSource.createdConnections;
assertEquals(1, createdConnections.size());
final StubConnection stubConnection = createdConnections.peek();
assertTrue(stubConnection.isClosed());
transaction.commit();
}
}
use of org.exist.storage.txn.Txn in project exist by eXist-db.
the class BrokerPool method _initialize.
private void _initialize() throws EXistException, DatabaseConfigurationException {
this.lockManager = new LockManager(conf, concurrencyLevel);
// Flag to indicate that we are initializing
status.process(Event.INITIALIZE);
if (LOG.isDebugEnabled()) {
LOG.debug("initializing database instance '{}'...", instanceName);
}
// register core broker pool services
this.scheduler = servicesManager.register(new QuartzSchedulerImpl(this));
// NOTE: this must occur after the scheduler, and before any other service which requires access to the data directory
this.dataLock = servicesManager.register(new FileLockService("dbx_dir.lck", BrokerPool.PROPERTY_DATA_DIR, NativeBroker.DEFAULT_DATA_DIR));
this.securityManager = servicesManager.register(new SecurityManagerImpl(this));
this.cacheManager = servicesManager.register(new DefaultCacheManager(this));
this.xQueryPool = servicesManager.register(new XQueryPool());
this.processMonitor = servicesManager.register(new ProcessMonitor());
this.xqueryStats = servicesManager.register(new PerformanceStats(this));
final XMLReaderObjectFactory xmlReaderObjectFactory = servicesManager.register(new XMLReaderObjectFactory());
this.xmlReaderPool = servicesManager.register(new XMLReaderPool(xmlReaderObjectFactory, maxBrokers, 0));
final int bufferSize = Optional.of(conf.getInteger(PROPERTY_COLLECTION_CACHE_SIZE)).filter(size -> size != -1).orElse(DEFAULT_COLLECTION_BUFFER_SIZE);
this.collectionCache = servicesManager.register(new CollectionCache());
this.notificationService = servicesManager.register(new NotificationService());
this.journalManager = recoveryEnabled ? Optional.of(new JournalManager()) : Optional.empty();
journalManager.ifPresent(servicesManager::register);
final SystemTaskManager systemTaskManager = servicesManager.register(new SystemTaskManager(this));
this.transactionManager = servicesManager.register(new TransactionManager(this, journalManager, systemTaskManager));
this.blobStoreService = servicesManager.register(new BlobStoreImplService());
this.symbols = servicesManager.register(new SymbolTable());
this.expathRepo = Optional.ofNullable(new ExistRepository());
expathRepo.ifPresent(servicesManager::register);
servicesManager.register(new ClasspathHelper());
this.indexManager = servicesManager.register(new IndexManager(this));
// prepare those services that require system (single-user) mode
this.pluginManager = servicesManager.register(new PluginsManagerImpl());
// Get a manager to handle further collections configuration
this.collectionConfigurationManager = servicesManager.register(new CollectionConfigurationManager(this));
this.startupTriggersManager = servicesManager.register(new StartupTriggersManager());
// this is just used for unit tests
final BrokerPoolService testBrokerPoolService = (BrokerPoolService) conf.getProperty("exist.testBrokerPoolService");
if (testBrokerPoolService != null) {
servicesManager.register(testBrokerPoolService);
}
// configure the registered services
try {
servicesManager.configureServices(conf);
} catch (final BrokerPoolServiceException e) {
throw new EXistException(e);
}
// calculate how much memory is reserved for caches to grow
final Runtime rt = Runtime.getRuntime();
final long maxMem = rt.maxMemory();
final long minFree = maxMem / 5;
reservedMem = cacheManager.getTotalMem() + collectionCache.getMaxCacheSize() + minFree;
LOG.debug("Reserved memory: {}; max: {}; min: {}", reservedMem, maxMem, minFree);
// prepare the registered services, before entering system (single-user) mode
try {
servicesManager.prepareServices(this);
} catch (final BrokerPoolServiceException e) {
throw new EXistException(e);
}
// setup database synchronization job
if (majorSyncPeriod > 0) {
final SyncTask syncTask = new SyncTask();
syncTask.configure(conf, null);
scheduler.createPeriodicJob(2500, new SystemTaskJobImpl(SyncTask.getJobName(), syncTask), 2500);
}
try {
statusReporter = new StatusReporter(SIGNAL_STARTUP);
statusObservers.forEach(statusReporter::addObserver);
final Thread statusThread = newInstanceThread(this, "startup-status-reporter", statusReporter);
statusThread.start();
// statusReporter may have to be terminated or the thread can/will hang.
try {
final boolean exportOnly = conf.getProperty(PROPERTY_EXPORT_ONLY, false);
// or the FileSyncThread for the journal can/will hang.
try {
// Enter System Mode
try (final DBBroker systemBroker = get(Optional.of(securityManager.getSystemSubject()))) {
status.process(Event.INITIALIZE_SYSTEM_MODE);
if (isReadOnly()) {
journalManager.ifPresent(JournalManager::disableJournalling);
}
try (final Txn transaction = transactionManager.beginTransaction()) {
servicesManager.startPreSystemServices(systemBroker, transaction);
transaction.commit();
} catch (final BrokerPoolServiceException e) {
throw new EXistException(e);
}
// Run the recovery process
boolean recovered = false;
if (isRecoveryEnabled()) {
recovered = runRecovery(systemBroker);
// TODO : extract the following from this block ? What if we are not transactional ? -pb
if (!recovered) {
try {
if (systemBroker.getCollection(XmldbURI.ROOT_COLLECTION_URI) == null) {
final Txn txn = transactionManager.beginTransaction();
try {
systemBroker.getOrCreateCollection(txn, XmldbURI.ROOT_COLLECTION_URI);
transactionManager.commit(txn);
} catch (final IOException | TriggerException | PermissionDeniedException e) {
transactionManager.abort(txn);
} finally {
transactionManager.close(txn);
}
}
} catch (final PermissionDeniedException pde) {
LOG.fatal(pde.getMessage(), pde);
}
}
}
/* initialise required collections if they don't exist yet */
if (!exportOnly) {
try {
initialiseSystemCollections(systemBroker);
} catch (final PermissionDeniedException pde) {
LOG.error(pde.getMessage(), pde);
throw new EXistException(pde.getMessage(), pde);
}
}
statusReporter.setStatus(SIGNAL_READINESS);
try (final Txn transaction = transactionManager.beginTransaction()) {
servicesManager.startSystemServices(systemBroker, transaction);
transaction.commit();
} catch (final BrokerPoolServiceException e) {
throw new EXistException(e);
}
// TODO : merge this with the recovery process ?
if (isRecoveryEnabled() && recovered) {
if (!exportOnly) {
reportStatus("Reindexing database files...");
try {
systemBroker.repair();
} catch (final PermissionDeniedException e) {
LOG.warn("Error during recovery: {}", e.getMessage(), e);
}
}
if ((Boolean) conf.getProperty(PROPERTY_RECOVERY_CHECK)) {
final ConsistencyCheckTask task = new ConsistencyCheckTask();
final Properties props = new Properties();
props.setProperty("backup", "no");
props.setProperty("output", "sanity");
task.configure(conf, props);
try (final Txn transaction = transactionManager.beginTransaction()) {
task.execute(systemBroker, transaction);
transaction.commit();
}
}
}
// OK : the DB is repaired; let's make a few RW operations
statusReporter.setStatus(SIGNAL_WRITABLE);
// initialize configurations watcher trigger
if (!exportOnly) {
try {
initialiseTriggersForCollections(systemBroker, XmldbURI.SYSTEM_COLLECTION_URI);
} catch (final PermissionDeniedException pde) {
// XXX: do not catch exception!
LOG.error(pde.getMessage(), pde);
}
}
// remove temporary docs
try {
systemBroker.cleanUpTempResources(true);
} catch (final PermissionDeniedException pde) {
LOG.error(pde.getMessage(), pde);
}
sync(systemBroker, Sync.MAJOR);
// system mode before entering multi-user mode
try (final Txn transaction = transactionManager.beginTransaction()) {
servicesManager.startPreMultiUserSystemServices(systemBroker, transaction);
transaction.commit();
} catch (final BrokerPoolServiceException e) {
throw new EXistException(e);
}
}
// Create the minimal number of brokers required by the configuration
for (int i = 1; i < minBrokers; i++) {
createBroker();
}
status.process(Event.INITIALIZE_MULTI_USER_MODE);
// register some MBeans to provide access to this instance
AgentFactory.getInstance().initDBInstance(this);
if (LOG.isDebugEnabled()) {
LOG.debug("database instance '{}' initialized", instanceName);
}
servicesManager.startMultiUserServices(this);
status.process(Event.READY);
statusReporter.setStatus(SIGNAL_STARTED);
} catch (final Throwable t) {
transactionManager.shutdown();
throw t;
}
} catch (final EXistException e) {
throw e;
} catch (final Throwable t) {
throw new EXistException(t.getMessage(), t);
}
} finally {
if (statusReporter != null) {
statusReporter.terminate();
statusReporter = null;
}
}
}
use of org.exist.storage.txn.Txn in project exist by eXist-db.
the class NativeBroker method getBinaryResource.
@Override
public InputStream getBinaryResource(final BinaryDocument blob) throws IOException {
// TODO(AR) how best to get the transaction?
try (final Txn transaction = continueOrBeginTransaction()) {
final InputStream is = getBinaryResource(transaction, blob);
transaction.commit();
return is;
} catch (final TransactionException e) {
throw new IOException(e.getMessage(), e);
}
}
Aggregations