/* * Hibernate, Relational Persistence for Idiomatic Java * * JBoss, Home of Professional Open Source * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * 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, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.hibernate.search.infinispan; import java.util.List; import junit.framework.Assert; import org.apache.lucene.index.Term; import org.apache.lucene.search.TermQuery; import org.hibernate.Transaction; import org.hibernate.cfg.Environment; import org.hibernate.search.FullTextQuery; import org.hibernate.search.FullTextSession; import org.hibernate.search.test.util.FullTextSessionBuilder; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** * Verifies we're able to start from an existing index in Infinispan, * stored in a CacheLoader. Requires a persistent database so that * we can shutdown the SessionFactory and start over again * (simulated via a custom H2 service) * * @author Sanne Grinovero <sanne@hibernate.org> (C) 2012 Red Hat Inc. */ public class StoredIndexTest { private FullTextSessionBuilder node; @Test public void testRestartingNode() { // Run 1 of application: startNode( true ); try { storeEmail( "there are some problems on this planet!" ); assertEmailsFound( "some", 1 ); } finally { //shutdown stopNode(); } // Restart same application: startNode( false ); try { assertEmailsFound( "some", 1 ); storeEmail( "stored stuff should not vanish on this planet" ); assertEmailsFound( "stuff", 1 ); assertEmailsFound( "some", 1 ); assertEmailsFound( "planet", 2 ); } finally { cleanupStoredIndex(); stopNode(); } } /** * Verifies a query on a specific term returns an expected amount of results. * We do actually load entities from database, so both database and index are tested. * * @param termMatch * @param expectedMatches */ private void assertEmailsFound(String termMatch, int expectedMatches) { FullTextSession fullTextSession = node.openFullTextSession(); try { TermQuery termQuery = new TermQuery( new Term( "message", termMatch ) ); FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery( termQuery, SimpleEmail.class ); List<SimpleEmail> list = fullTextQuery.list(); Assert.assertEquals( expectedMatches, list.size() ); if ( expectedMatches != 0 ) { Assert.assertEquals( "complaints-office@world.com", list.get( 0 ).to ); } } finally { fullTextSession.close(); } } /** * Saves a new test email */ private void storeEmail(String content) { SimpleEmail email = new SimpleEmail(); email.to = "complaints-office@world.com"; email.message = content; FullTextSession fullTextSession = node.openFullTextSession(); Transaction transaction = fullTextSession.beginTransaction(); fullTextSession.save( email ); transaction.commit(); fullTextSession.close(); } /** * Creates a new SessionFactory using a shared H2 connection pool, and running * an Infinispan Directory storing the index in memory and write-through filesystem. * @param createSchema set to false to not drop an existing schema */ private void startNode(boolean createSchema) { node = new FullTextSessionBuilder() .setProperty( "hibernate.search.default.directory_provider", "infinispan" ) .setProperty( CacheManagerServiceProvider.INFINISPAN_CONFIGURATION_RESOURCENAME, "filesystem-loading-infinispan.xml" ) // avoid killing the schema when you still have to run the second node: .setProperty( Environment.HBM2DDL_AUTO, createSchema ? "create" : "validate" ) // share the same in-memory database connection pool .setProperty( Environment.CONNECTION_PROVIDER, org.hibernate.search.infinispan.ClusterSharedConnectionProvider.class.getName() ) .addAnnotatedClass( SimpleEmail.class ) .build(); } /** * Closes the SessionFactory, SearchFactory and Infinispan CacheManagers. * Only service to survive is the H2 in memory database. */ public void stopNode() { if ( node != null ) { node.close(); node = null; } } /** * This test uses and Infinispan CacheLoader writing in $tmp directory. * Make sure we at least clear the index so that subsequent runs of the same * test won't fail. */ private void cleanupStoredIndex() { FullTextSession fullTextSession = node.openFullTextSession(); try { Transaction transaction = fullTextSession.beginTransaction(); fullTextSession.purgeAll( SimpleEmail.class ); transaction.commit(); } finally { fullTextSession.close(); } } /** * We need to use the custom H2 connector pool to make sure that when shutting * down the first node we don't kill the database with all data we need * for the second phase of the test. */ @BeforeClass public static void prepareConnectionPool() { ClusterSharedConnectionProvider.realStart(); } /** * Kills the static connection pool of H2 started by {@link #prepareConnectionPool()} */ @AfterClass public static void shutdownConnectionPool() { ClusterSharedConnectionProvider.realStop(); } }