/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-2015 The eXist Project
* http://exist-db.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.exist.storage.md;
import static org.junit.Assert.*;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import org.exist.EXistException;
import org.exist.collections.Collection;
import org.exist.collections.CollectionConfigurationManager;
import org.exist.collections.IndexInfo;
import org.exist.dom.persistent.DocumentImpl;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.lock.Lock.LockMode;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.test.TestConstants;
import org.exist.util.Configuration;
import org.exist.util.ConfigurationHelper;
import org.exist.util.DatabaseConfigurationException;
import org.exist.xmldb.XmldbURI;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
/**
* @author <a href="mailto:shabanovd@gmail.com">Dmitriy Shabanov</a>
*
*/
public class MatchDocumentsTest {
private static String COLLECTION_CONFIG =
"<collection xmlns=\"http://exist-db.org/collection-config/1.0\">" +
" <index>" +
" </index>" +
"</collection>";
/** /db/test **/
private static XmldbURI col1uri = TestConstants.TEST_COLLECTION_URI;
/** /db/moved **/
private static XmldbURI col2uri = XmldbURI.ROOT_COLLECTION_URI.append("moved");
/** /db/test/test_string1.xml **/
private static XmldbURI doc1uri = col1uri.append("test_string1.xml");
/** /db/test/test_string2.xml **/
private static XmldbURI doc2uri = col1uri.append("test_string2.xml");
/** /db/test/test.binary **/
private static XmldbURI doc3uri = col1uri.append("test.binary");
private static XmldbURI doc4uri = col2uri.append("test_string1.xml");
private static XmldbURI doc5uri = col2uri.append("test.binary");
private static XmldbURI doc6uri = col1uri.append("test1.binary");
private static String XML1 = "<test1/>";
private static String XML2 = "<test2/>";
private static String BINARY = "test";
private static String KEY1 = "key1";
private static String KEY2 = "key2";
private static String VALUE1 = "value1";
private static String VALUE2 = "value2";
private static BrokerPool pool;
@Test
public void deleteCollection() throws Exception {
final MetaData md = MetaData.get();
assertNotNull(md);
final Metas doc1Metadata = md.getMetas(doc1uri);
assertNotNull(doc1Metadata);
final Metas doc3Metadata = md.getMetas(doc3uri);
assertNotNull(doc3Metadata);
Collection col1 = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
final DocumentImpl doc2 = col1.getDocument(broker, doc2uri.lastSegment());
//add metas for XML document
doc1Metadata.put(KEY1, doc2);
doc1Metadata.put(KEY2, VALUE1);
//add metas for binaty document
doc3Metadata.put(KEY1, VALUE2);
doc3Metadata.put(KEY2, doc2);
List<DocumentImpl> matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc1uri, matching.get(0).getURI());
matching = md.matchDocuments(KEY1, VALUE2);
assertEquals(1, matching.size());
assertEquals(doc3uri, matching.get(0).getURI());
final TransactionManager txnManager = pool.getTransactionManager();
try(final Txn txn = txnManager.beginTransaction()) {
broker.removeCollection(txn, col1);
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(0, matching.size());
matching = md.matchDocuments(KEY1, VALUE2);
assertEquals(0, matching.size());
} finally {
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
@Test
public void moveCollection() throws Exception {
final MetaData md = MetaData.get();
assertNotNull(md);
final Metas doc1Metadata = md.getMetas(doc1uri);
assertNotNull(doc1Metadata);
final Metas doc3metadata = md.getMetas(doc3uri);
assertNotNull(doc3metadata);
Collection col1 = null;
Collection parentCol = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
parentCol = broker.openCollection(col2uri.removeLastSegment(), LockMode.WRITE_LOCK);
final DocumentImpl doc2 = col1.getDocument(broker, doc2uri.lastSegment());
//add metas for XML document
doc1Metadata.put(KEY1, doc2);
doc1Metadata.put(KEY2, VALUE1);
//add metas for binaty document
doc3metadata.put(KEY1, VALUE2);
doc3metadata.put(KEY2, doc2);
List<DocumentImpl> matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc1uri, matching.get(0).getURI());
matching = md.matchDocuments(KEY1, VALUE2);
assertEquals(1, matching.size());
assertEquals(doc3uri, matching.get(0).getURI());
final TransactionManager txnManager = pool.getTransactionManager();
try(final Txn txn = txnManager.beginTransaction()) {
broker.moveCollection(txn, col1, parentCol, col2uri.lastSegment());
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc4uri, matching.get(0).getURI());
} finally {
if(parentCol != null) {
parentCol.release(LockMode.WRITE_LOCK);
}
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
@Test
public void renameXMLResource() throws Exception {
final MetaData md = MetaData.get();
assertNotNull(md);
final Metas doc1Metadata = md.getMetas(doc1uri);
assertNotNull(doc1Metadata);
Collection col1 = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
final DocumentImpl doc2 = col1.getDocument(broker, doc2uri.lastSegment());
//add first key-value
doc1Metadata.put(KEY1, doc2);
doc1Metadata.put(KEY2, VALUE1);
List<DocumentImpl> matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc1uri, matching.get(0).getURI());
Collection col = broker.getCollection(col1uri);
assertNotNull(col);
final TransactionManager txnManager = pool.getTransactionManager();
try(final Txn txn = txnManager.beginTransaction()) {
final DocumentImpl doc1 = col1.getDocument(broker, doc1uri.lastSegment());
broker.moveResource(txn, doc1, col, doc2uri.lastSegment());
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc2uri, matching.get(0).getURI());
} finally {
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
@Test
public void moveXMLResource() throws Exception {
final MetaData md = MetaData.get();
assertNotNull(md);
final Metas doc1Metadata = md.getMetas(doc1uri);
assertNotNull(doc1Metadata);
Collection col1 = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
DocumentImpl doc2 = col1.getDocument(broker, doc2uri.lastSegment());
//add first key-value
doc1Metadata.put(KEY1, doc2);
doc1Metadata.put(KEY2, VALUE1);
List<DocumentImpl> matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc1uri, matching.get(0).getURI());
final TransactionManager txnManager = pool.getTransactionManager();
try(final Txn txn = txnManager.beginTransaction()) {
Collection col2 = broker.getOrCreateCollection(txn, col2uri);
broker.saveCollection(txn, col2);
DocumentImpl doc1 = col1.getDocument(broker, doc1uri.lastSegment());
broker.moveResource(txn, doc1, col2, doc4uri.lastSegment());
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc4uri, matching.get(0).getURI());
} finally {
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
/*
* Set to @Ignore because even though it seems to delete
* the XML document /db/test/test_string1.xml
* when @After/clean() function is called
* it causes an error: As it thinks the document is
* still present but then cannot delete it?!?
*/
@Ignore
@Test
public void deleteXMLResource() throws Exception {
final MetaData md = MetaData.get();
assertNotNull(md);
final Metas doc1Metadata = md.getMetas(doc1uri);
assertNotNull(doc1Metadata);
//add some test key-values to metadata of doc1
Collection col1 = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
final DocumentImpl doc2 = col1.getDocument(broker, doc2uri.lastSegment());
//add first key-value
doc1Metadata.put(KEY1, doc2);
doc1Metadata.put(KEY2, VALUE1);
List<DocumentImpl> matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc1uri, matching.get(0).getURI());
final TransactionManager txnManager = pool.getTransactionManager();
try(final Txn txn = txnManager.beginTransaction()) {
DocumentImpl doc1 = col1.getDocument(broker, doc1uri.lastSegment());
broker.removeXMLResource(txn, doc1);
broker.saveCollection(txn, col1);
txnManager.commit(txn);
} catch(Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
//check the metadata was deleted
matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(0, matching.size());
} finally {
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
@Test
public void renameBinaryResource() throws Exception {
final MetaData md = MetaData.get();
assertNotNull(md);
final Metas doc3Metadata = md.getMetas(doc3uri);
assertNotNull(doc3Metadata);
Collection col1 = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
DocumentImpl doc2 = col1.getDocument(broker, doc2uri.lastSegment());
//add first key-value
doc3Metadata.put(KEY1, doc2);
doc3Metadata.put(KEY2, VALUE1);
List<DocumentImpl> matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc3uri, matching.get(0).getURI());
final TransactionManager txnManager = pool.getTransactionManager();
final Txn txn = txnManager.beginTransaction();
try {
DocumentImpl doc3 = col1.getDocument(broker, doc3uri.lastSegment());
broker.moveResource(txn, doc3, col1, doc6uri.lastSegment());
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
txnManager.abort(txn);
fail(e.getMessage());
} finally {
txnManager.close(txn);
}
matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc6uri, matching.get(0).getURI());
} finally {
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
@Test
public void moveBinaryResource() throws Exception {
final MetaData md = MetaData.get();
assertNotNull(md);
final Metas doc3Metadata = md.getMetas(doc3uri);
assertNotNull(doc3Metadata);
Collection col1 = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
DocumentImpl doc2 = col1.getDocument(broker, doc2uri.lastSegment());
//add first key-value
doc3Metadata.put(KEY1, doc2);
doc3Metadata.put(KEY2, VALUE1);
List<DocumentImpl> matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc3uri, matching.get(0).getURI());
final TransactionManager txnManager = pool.getTransactionManager();
try(final Txn txn = txnManager.beginTransaction()) {
Collection col2 = broker.getOrCreateCollection(txn, col2uri);
broker.saveCollection(txn, col2);
DocumentImpl doc3 = col1.getDocument(broker, doc3uri.lastSegment());
broker.moveResource(txn, doc3, col2, doc5uri.lastSegment());
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc5uri, matching.get(0).getURI());
} finally {
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
@Test
public void deleteBinaryResource() throws Exception {
final MetaData md = MetaData.get();
assertNotNull(md);
final Metas doc3Metadata = md.getMetas(doc3uri);
assertNotNull(doc3Metadata);
Collection col1 = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
DocumentImpl doc2 = col1.getDocument(broker, doc2uri.lastSegment());
//add first key-value
doc3Metadata.put(KEY1, doc2);
doc3Metadata.put(KEY2, VALUE1);
List<DocumentImpl> matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(1, matching.size());
assertEquals(doc3uri, matching.get(0).getURI());
final TransactionManager txnManager = pool.getTransactionManager();
try(final Txn txn = txnManager.beginTransaction()) {
DocumentImpl doc3 = col1.getDocument(broker, doc3uri.lastSegment());
broker.removeXMLResource(txn, doc3);
broker.saveCollection(txn, col1);
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
matching = md.matchDocuments(KEY2, VALUE1);
assertEquals(0, matching.size());
} finally {
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
@Before
public void startDB() throws DatabaseConfigurationException, EXistException {
final Path confFile = ConfigurationHelper.lookup("conf.xml");
Configuration config = new Configuration(confFile.toAbsolutePath().toString());
BrokerPool.configure(1, 5, config);
pool = BrokerPool.getInstance();
pool.getPluginsManager().addPlugin("org.exist.storage.md.Plugin");
final TransactionManager txnManager = pool.getTransactionManager();
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
final Txn txn = txnManager.beginTransaction()) {
final Collection root = broker.getOrCreateCollection(txn, col1uri);
assertNotNull(root);
broker.saveCollection(txn, root);
final CollectionConfigurationManager mgr = pool.getConfigurationManager();
mgr.addConfiguration(txn, broker, root, COLLECTION_CONFIG);
//store test data
IndexInfo info = root.validateXMLResource(txn, broker, doc1uri.lastSegment(), XML1);
root.store(txn, broker, info, XML1);
info = root.validateXMLResource(txn, broker, doc2uri.lastSegment(), XML2);
root.store(txn, broker, info, XML2);
root.addBinaryResource(txn, broker, doc3uri.lastSegment(), BINARY.getBytes(), null);
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
}
@After
public void cleanup() {
clean();
shutdown();
}
//@AfterClass
private void shutdown() {
BrokerPool.stopAll(false);
pool = null;
}
private void clean() {
final TransactionManager txnManager = pool.getTransactionManager();
Collection col1 = null;
Collection col2 = null;
try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
final Txn txn = txnManager.beginTransaction()) {
col1 = broker.openCollection(col1uri, LockMode.WRITE_LOCK);
if(col1 != null) {
broker.removeCollection(txn, col1);
}
col2 = broker.openCollection(col2uri, LockMode.WRITE_LOCK);
if(col2 != null) {
broker.removeCollection(txn, col2);
}
txnManager.commit(txn);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
} finally {
if(col2 != null) {
col2.release(LockMode.WRITE_LOCK);
}
if(col1 != null) {
col1.release(LockMode.WRITE_LOCK);
}
}
}
}