/*
* Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Stephane Lacoin
*/
package org.eclipse.ecr.core.storage.sql;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.ecr.core.api.ClientException;
import org.eclipse.ecr.core.api.CoreSession;
import org.eclipse.ecr.core.api.DocumentModel;
import org.eclipse.ecr.core.api.blobholder.BlobHolder;
import org.eclipse.ecr.core.api.impl.DocumentModelImpl;
import org.eclipse.ecr.core.api.impl.blob.StringBlob;
import org.eclipse.ecr.core.event.Event;
import org.eclipse.ecr.core.event.EventBundle;
import org.eclipse.ecr.core.event.EventService;
import org.eclipse.ecr.core.event.PostCommitEventListener;
import org.eclipse.ecr.core.storage.sql.coremodel.BinaryTextListener;
import org.eclipse.ecr.core.storage.sql.testlib.TXSQLRepositoryTestCase;
import org.eclipse.ecr.runtime.api.Framework;
import org.eclipse.ecr.runtime.transaction.TransactionHelper;
public class TestSQLBinariesIndexing extends TXSQLRepositoryTestCase {
protected static final Log log = LogFactory.getLog(TestSQLBinariesIndexing.class);
public static final String TEST_BUNDLE = "org.eclipse.ecr.core.storage.sql.test";
protected static CountDownLatch startIndexation;
protected static final Thread thread = Thread.currentThread();
protected static DocumentModel doc;
protected Object originalPoolSize;
protected Object originalMaxPoolSize;
protected void setEventAsyncPoolSizes() {
Properties properties = System.getProperties();
originalPoolSize = properties.setProperty(
"org.eclipse.ecr.core.event.async.poolSize", "1");
originalMaxPoolSize = properties.setProperty(
"org.eclipse.ecr.core.event.async.maxPoolSize", "1");
}
protected void restoreEventAsyncPoolSizes() {
Properties properties = System.getProperties();
if (originalPoolSize == null) {
properties.remove("org.eclipse.ecr.core.event.async.poolSize");
} else {
properties.put("org.eclipse.ecr.core.event.async.poolSize",
originalPoolSize);
}
if (originalMaxPoolSize == null) {
properties.remove("org.eclipse.ecr.core.event.async.maxPoolSize");
} else {
properties.put("org.eclipse.ecr.core.event.async.maxPoolSize",
originalMaxPoolSize);
}
}
@Override
public void setUp() throws Exception {
setEventAsyncPoolSizes();
startIndexation = new CountDownLatch(1);
super.setUp();
populate(session);
docsAreNotIndexed();
}
@Override
public void tearDown() throws Exception {
startIndexation.countDown();
restoreEventAsyncPoolSizes();
super.tearDown();
}
@Override
protected void deployRepositoryContrib() throws Exception {
super.deployRepositoryContrib();
deployBundle("org.eclipse.ecr.convert.api");
deployBundle("org.eclipse.ecr.convert");
deployContrib(TEST_BUNDLE,
"OSGI-INF/test-asynch-binaries-indexing-contrib.xml");
}
public void populate(CoreSession repo) throws ClientException {
doc = repo.createDocumentModel("/", "source", "File");
BlobHolder holder = doc.getAdapter(BlobHolder.class);
holder.setBlob(new StringBlob("test"));
doc = repo.createDocument(doc);
((DocumentModelImpl) doc).detach(true);
}
public static class SynchHandler implements PostCommitEventListener {
@Override
public void handleEvent(EventBundle events) throws ClientException {
for (Event event : events) {
if (BinaryTextListener.EVENT_NAME.equals(event.getName())) {
try {
TestSQLBinariesIndexing.startIndexation.await();
} catch (InterruptedException e) {
throw new ClientException("Cannot wait for test", e);
}
}
}
}
}
protected void flushAndCommit() throws ClientException {
session.save();
closeSession();
session = null;
TransactionHelper.commitOrRollbackTransaction();
}
protected void recycleSession() throws Exception {
if (session != null) {
flushAndCommit();
}
TransactionHelper.startTransaction();
openSession();
}
protected List<DocumentModel> indexedDocs() throws ClientException {
return session.query("SELECT * FROM Document WHERE ecm:fulltext = 'test'");
}
protected List<DocumentModel> requestedDocs() throws ClientException {
String request = String.format(
"SELECT * from Document where ecm:fulltextJobId = '%s'",
doc.getId());
return session.query(request);
}
protected void waitForIndexing() throws Exception {
flushAndCommit(); // flush and commit transaction
startIndexation.countDown();
Framework.getLocalService(EventService.class).waitForAsyncCompletion();
startIndexation = new CountDownLatch(1);
recycleSession();
}
protected void docsAreNotIndexed() throws Exception {
recycleSession();
assertEquals(0, indexedDocs().size());
}
public void testBinariesAreIndexed() throws Exception {
assertEquals(1, requestedDocs().size());
assertEquals(0, indexedDocs().size());
waitForIndexing();
assertEquals(0, requestedDocs().size());
assertEquals(1, indexedDocs().size());
}
public void testCopiesAreIndexed() throws Exception {
assertEquals(1, requestedDocs().size());
assertEquals(0, indexedDocs().size());
session.copy(doc.getRef(), session.getRootDocument().getRef(), "copy").getRef();
recycleSession();
// check copy is part of requested
assertEquals(2, requestedDocs().size());
waitForIndexing();
// check other doc is indexed also
assertEquals(0, requestedDocs().size());
assertEquals(2, indexedDocs().size());
// check other doc is not indexed twice
DocumentModel rehydratedDoc = session.getDocument(doc.getRef());
rehydratedDoc.getAdapter(BlobHolder.class).setBlob(
new StringBlob("other"));
session.saveDocument(rehydratedDoc);
recycleSession();
waitForIndexing();
assertEquals(1, indexedDocs().size());
}
public void testVersionsAreIndexed() throws Exception {
assertEquals(1, requestedDocs().size());
assertEquals(0, indexedDocs().size());
session.checkIn(doc.getRef(), null, null);
waitForIndexing();
assertEquals(2, indexedDocs().size());
}
}