/* * Hibernate Search, full-text search for your domain model * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.search.test.util; import java.io.IOException; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.WildcardQuery; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.hibernate.search.engine.integration.impl.ExtendedSearchIntegrator; import org.hibernate.search.indexes.IndexReaderAccessor; import org.hibernate.search.indexes.spi.DirectoryBasedIndexManager; import org.hibernate.search.indexes.spi.IndexManager; import org.hibernate.search.test.TestResourceManager; /** * Provides functionality useful for tests, e.g. for asserting the number of documents in a given index. Specific * implementations exist for different backends. * * @author Gunnar Morling */ public abstract class BackendTestHelper { private static final String ELASTIC_SEARCH_TEST_HELPER_CLASS_NAME = "org.hibernate.search.elasticsearch.testutil.ElasticsearchBackendTestHelper"; protected BackendTestHelper() { } public static BackendTestHelper getInstance(TestResourceManager resourceManager) { BackendTestHelper instance; try { Class<?> clazz = Class.forName( ELASTIC_SEARCH_TEST_HELPER_CLASS_NAME ); instance = (BackendTestHelper) clazz.getConstructor( TestResourceManager.class ).newInstance( resourceManager ); } catch (Exception e) { // ES backend not present, use Lucene-based helper by default instance = new LuceneBackendTestHelper( resourceManager ); } return instance; } /** * Returns the number of indexed documents for the given type. */ public abstract int getNumberOfDocumentsInIndex(Class<?> entityType); /** * Returns the number of indexed documents for the given index. */ public abstract int getNumberOfDocumentsInIndex(String indexName); /** * Returns the number of indexed documents for the given index satisfying the represented term or wildcard query. */ public abstract int getNumberOfDocumentsInIndexByQuery(String indexName, String fieldName, String value); private static class LuceneBackendTestHelper extends BackendTestHelper { private final TestResourceManager resourceManager; public LuceneBackendTestHelper(TestResourceManager resourceManager) { this.resourceManager = resourceManager; } public Directory getDirectory(Class<?> entityType) { ExtendedSearchIntegrator integrator = resourceManager.getExtendedSearchIntegrator(); IndexManager[] indexManagers = integrator.getIndexBinding( entityType ).getIndexManagers(); DirectoryBasedIndexManager indexManager = (DirectoryBasedIndexManager) indexManagers[0]; return indexManager.getDirectoryProvider().getDirectory(); } @Override public int getNumberOfDocumentsInIndex(Class<?> entityType) { try ( IndexReader reader = DirectoryReader.open( getDirectory( entityType ) ) ) { return reader.numDocs(); } catch (IOException e) { throw new RuntimeException( e ); } } @Override public int getNumberOfDocumentsInIndex(String indexName) { try ( // TODO When using IndexReaderAccessor as below, ShardsTest fails; It seems to not know about // the custom shard identifier configured FSDirectory directory = FSDirectory.open( resourceManager.getBaseIndexDir().resolve( indexName ) ); IndexReader reader = DirectoryReader.open( directory ) ) { return reader.numDocs(); } catch (IOException e) { throw new RuntimeException( e ); } } @Override public int getNumberOfDocumentsInIndexByQuery(String indexName, String fieldName, String value) { IndexReaderAccessor indexReaderAccessor = resourceManager.getExtendedSearchIntegrator().getIndexReaderAccessor(); Term term = new Term( fieldName, value ); Query query = value.contains( "*" ) ? new WildcardQuery( term ) : new TermQuery( term ); try ( IndexReader reader = indexReaderAccessor.open( indexName ) ) { IndexSearcher searcher = new IndexSearcher( reader ); TopDocs topDocs = searcher.search( query, 100 ); return topDocs.totalHits; } catch (IOException e) { throw new RuntimeException( e ); } } } }