GEODE-2703: Improve exception message when executing lucene within a transaction
* Throw a LuceneQueryException instead of a TransactionException Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/acd57226 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/acd57226 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/acd57226 Branch: refs/heads/feature/GEODE-2681 Commit: acd57226c1c376c9d456cbde8c96614fdaa54889 Parents: ae8350b Author: Jason Huynh <[email protected]> Authored: Wed Apr 12 13:54:39 2017 -0700 Committer: Ken Howe <[email protected]> Committed: Thu Apr 20 15:13:17 2017 -0700 ---------------------------------------------------------------------- .../cache/lucene/internal/LuceneQueryImpl.java | 11 +++++- .../lucene/LuceneQueriesClientDUnitTest.java | 39 ++++++++++++++++++- .../cache/lucene/LuceneQueriesDUnitTest.java | 40 ++++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/acd57226/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneQueryImpl.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneQueryImpl.java b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneQueryImpl.java index 73d84d7..bfc561a 100644 --- a/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneQueryImpl.java +++ b/geode-lucene/src/main/java/org/apache/geode/cache/lucene/internal/LuceneQueryImpl.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.stream.Collectors; import org.apache.geode.cache.Region; +import org.apache.geode.cache.TransactionException; import org.apache.geode.cache.execute.Execution; import org.apache.geode.cache.execute.FunctionException; import org.apache.geode.cache.execute.FunctionService; @@ -42,6 +43,8 @@ import org.apache.geode.internal.logging.LogService; import org.apache.logging.log4j.Logger; public class LuceneQueryImpl<K, V> implements LuceneQuery<K, V> { + public static final String LUCENE_QUERY_CANNOT_BE_EXECUTED_WITHIN_A_TRANSACTION = + "Lucene Query cannot be executed within a transaction"; Logger logger = LogService.getLogger(); private int limit = LuceneQueryFactory.DEFAULT_LIMIT; @@ -116,12 +119,18 @@ public class LuceneQueryImpl<K, V> implements LuceneQuery<K, V> { } catch (FunctionException e) { if (e.getCause() instanceof LuceneQueryException) { throw new LuceneQueryException(e); + } else if (e.getCause() instanceof TransactionException) { + // When run from client with single hop disabled + throw new LuceneQueryException(LUCENE_QUERY_CANNOT_BE_EXECUTED_WITHIN_A_TRANSACTION); } else if (e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } throw e; - + } catch (TransactionException e) { + // When function execution is run from server + throw new LuceneQueryException(LUCENE_QUERY_CANNOT_BE_EXECUTED_WITHIN_A_TRANSACTION); } + return entries; } http://git-wip-us.apache.org/repos/asf/geode/blob/acd57226/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesClientDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesClientDUnitTest.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesClientDUnitTest.java index b0ae47e..e200a19 100755 --- a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesClientDUnitTest.java +++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesClientDUnitTest.java @@ -14,12 +14,15 @@ */ package org.apache.geode.cache.lucene; +import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.DEFAULT_FIELD; +import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.INDEX_NAME; import static org.apache.geode.cache.lucene.test.LuceneTestUtilities.REGION_NAME; +import static org.junit.Assert.assertTrue; +import org.junit.Test; import org.junit.experimental.categories.Category; import org.apache.geode.cache.Cache; -import org.apache.geode.cache.RegionShortcut; import org.apache.geode.cache.client.ClientCache; import org.apache.geode.cache.client.ClientCacheFactory; import org.apache.geode.cache.client.ClientRegionShortcut; @@ -30,6 +33,7 @@ import org.apache.geode.test.junit.categories.DistributedTest; import org.junit.runner.RunWith; import junitparams.JUnitParamsRunner; +import junitparams.Parameters; @Category(DistributedTest.class) @RunWith(JUnitParamsRunner.class) @@ -64,6 +68,39 @@ public class LuceneQueriesClientDUnitTest extends LuceneQueriesDUnitTest { return new RegionTestableType[] {RegionTestableType.PARTITION_WITH_CLIENT}; } + // Due to singlehop transactions differences, the exception actually isn't thrown + // So the parent test behaves differently if singlehop is enabled or not for a client + @Test + @Parameters(method = "getListOfRegionTestTypes") + public void transactionWithLuceneQueriesShouldThrowException(RegionTestableType regionTestType) { + SerializableRunnableIF createIndex = () -> { + LuceneService luceneService = LuceneServiceProvider.get(getCache()); + luceneService.createIndexFactory().addField("text").create(INDEX_NAME, REGION_NAME); + }; + dataStore1.invoke(() -> initDataStore(createIndex, regionTestType)); + dataStore2.invoke(() -> initDataStore(createIndex, regionTestType)); + accessor.invoke(() -> initAccessor(createIndex, regionTestType)); + + putDataInRegion(accessor); + assertTrue(waitForFlushBeforeExecuteTextSearch(accessor, 60000)); + assertTrue(waitForFlushBeforeExecuteTextSearch(dataStore1, 60000)); + + accessor.invoke(() -> { + Cache cache = getCache(); + try { + LuceneService service = LuceneServiceProvider.get(cache); + LuceneQuery<Integer, TestObject> query; + query = service.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "text:world", + DEFAULT_FIELD); + cache.getCacheTransactionManager().begin(); + PageableLuceneQueryResults<Integer, TestObject> results = query.findPages(); + } finally { + cache.getCacheTransactionManager().rollback(); + } + }); + + } + } http://git-wip-us.apache.org/repos/asf/geode/blob/acd57226/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java index d259205..c319a16 100644 --- a/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java +++ b/geode-lucene/src/test/java/org/apache/geode/cache/lucene/LuceneQueriesDUnitTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.*; import org.apache.geode.cache.Cache; import org.apache.geode.cache.Region; +import org.apache.geode.cache.lucene.internal.LuceneQueryImpl; import org.apache.geode.cache.lucene.test.LuceneTestUtilities; import org.apache.geode.test.dunit.SerializableRunnableIF; import org.apache.geode.test.dunit.VM; @@ -30,6 +31,9 @@ import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import junitparams.JUnitParamsRunner; import junitparams.Parameters; @@ -46,6 +50,42 @@ public class LuceneQueriesDUnitTest extends LuceneQueriesAccessorBase { @Test @Parameters(method = "getListOfRegionTestTypes") + public void transactionWithLuceneQueriesShouldThrowException(RegionTestableType regionTestType) { + SerializableRunnableIF createIndex = () -> { + LuceneService luceneService = LuceneServiceProvider.get(getCache()); + luceneService.createIndexFactory().addField("text").create(INDEX_NAME, REGION_NAME); + }; + dataStore1.invoke(() -> initDataStore(createIndex, regionTestType)); + dataStore2.invoke(() -> initDataStore(createIndex, regionTestType)); + accessor.invoke(() -> initAccessor(createIndex, regionTestType)); + + putDataInRegion(accessor); + assertTrue(waitForFlushBeforeExecuteTextSearch(accessor, 60000)); + assertTrue(waitForFlushBeforeExecuteTextSearch(dataStore1, 60000)); + + accessor.invoke(() -> { + Cache cache = getCache(); + try { + LuceneService service = LuceneServiceProvider.get(cache); + LuceneQuery<Integer, TestObject> query; + query = service.createLuceneQueryFactory().create(INDEX_NAME, REGION_NAME, "text:world", + DEFAULT_FIELD); + cache.getCacheTransactionManager().begin(); + PageableLuceneQueryResults<Integer, TestObject> results = query.findPages(); + fail(); + } catch (LuceneQueryException e) { + if (!e.getMessage() + .equals(LuceneQueryImpl.LUCENE_QUERY_CANNOT_BE_EXECUTED_WITHIN_A_TRANSACTION)) { + fail(); + } + } finally { + cache.getCacheTransactionManager().rollback(); + } + }); + } + + @Test + @Parameters(method = "getListOfRegionTestTypes") public void returnCorrectResultsFromStringQueryWithDefaultAnalyzer( RegionTestableType regionTestType) { SerializableRunnableIF createIndex = () -> {
