This is an automated email from the ASF dual-hosted git repository.
jjramos pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new 6933232 GEODE-7487: Update Running CQ Context (#4369)
6933232 is described below
commit 693323257481dbf5b785421061369abb5497742e
Author: Juan José Ramos <[email protected]>
AuthorDate: Thu Nov 28 13:05:19 2019 +0000
GEODE-7487: Update Running CQ Context (#4369)
- Added unit and integration tests.
- Implemented method to invalidate the cache used by CQs.
- Updated the context implementation to change the internal
MethodInvocationAuthorizer used whenever the CQ resets the
ExecutionContext.
- Added a warning message whenever the MethodInvocationAuthorizer
returned by the QueryConfigurationService is null.
---
.../DefaultQuerySecurityIntegrationTest.java | 34 +++------
.../DefaultQueryServiceIntegrationTest.java | 80 ++++++++++++++++++++++
.../internal/ExecutionContextIntegrationTest.java | 41 ++++++++---
.../cache/query/internal/DefaultQueryService.java | 12 +++-
.../cache/query/internal/ExecutionContext.java | 27 ++++----
.../geode/cache/query/internal/cq/ServerCQ.java | 7 ++
.../query/internal/AttributeDescriptorTest.java | 7 +-
.../internal/CompiledAggregateFunctionTest.java | 6 +-
.../cache/query/internal/ExecutionContextTest.java | 23 ++-----
.../cache/query/internal/MethodDispatchTest.java | 7 +-
.../cache/query/internal/NWayMergeResultsTest.java | 6 +-
.../geode/cache/query/internal/QCompilerTest.java | 6 +-
.../query/internal/QueryExecutionContextTest.java | 6 +-
.../internal/index/CompactRangeIndexTest.java | 12 ++--
.../cache/PartitionedRegionQueryEvaluatorTest.java | 9 +--
.../cache/query/cq/internal/ServerCQImpl.java | 16 ++++-
.../cache/query/cq/internal/ServerCQImplTest.java | 76 ++++++++++++++++++++
17 files changed, 281 insertions(+), 94 deletions(-)
diff --git
a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/DefaultQuerySecurityIntegrationTest.java
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/DefaultQuerySecurityIntegrationTest.java
index 17237d4..08fb8a7 100644
---
a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/DefaultQuerySecurityIntegrationTest.java
+++
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/DefaultQuerySecurityIntegrationTest.java
@@ -19,11 +19,11 @@ import static
org.apache.geode.test.awaitility.GeodeAwaitility.await;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.lang.reflect.Method;
+import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
@@ -95,7 +95,7 @@ public class DefaultQuerySecurityIntegrationTest {
}
private void
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(
- String queryString, RegionShortcut regionShortcut) {
+ String queryString) {
IntStream.range(1, executions).forEach(counter -> {
try {
DefaultQuery query = spy(new DefaultQuery(queryString, spiedCache,
false));
@@ -103,12 +103,7 @@ public class DefaultQuerySecurityIntegrationTest {
SelectResults result = (SelectResults) query.execute();
assertThat(result.size()).isEqualTo(entries);
- if (!regionShortcut.equals(RegionShortcut.PARTITION)) {
- assertThat(SpyAuthorizer.instantiations.get()).isEqualTo(counter);
- } else {
- // execute + getEmptyResultSet + executeOnLocalNode
- assertThat(SpyAuthorizer.instantiations.get()).isEqualTo(3 *
counter);
- }
+ assertThat(SpyAuthorizer.instantiations.get()).isEqualTo(1);
} catch (Exception exception) {
throw new RuntimeException(exception);
}
@@ -116,17 +111,14 @@ public class DefaultQuerySecurityIntegrationTest {
}
@Before
- public void setUp() {
+ public void setUp() throws ClassNotFoundException {
SpyAuthorizer.instantiations.set(0);
SpyAuthorizer.authorizations.set(0);
spiedCache = spy(server.getCache());
- doAnswer(answer -> {
- InternalQueryService spyQueryService = spy((InternalQueryService)
answer.callRealMethod());
- doReturn(new
SpyAuthorizer()).when(spyQueryService).getMethodInvocationAuthorizer();
-
- return spyQueryService;
- }).when(spiedCache).getQueryService();
+ QueryConfigurationService queryConfig =
spiedCache.getService(QueryConfigurationService.class);
+ queryConfig.updateMethodAuthorizer(spiedCache,
SpyAuthorizer.class.getName(),
+ Collections.emptySet());
}
@Test
@@ -186,8 +178,7 @@ public class DefaultQuerySecurityIntegrationTest {
createAndPopulateRegion(regionName, regionShortcut);
String queryString = "SELECT object.name FROM /" + regionName + " object";
-
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(queryString,
- regionShortcut);
+
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(queryString);
}
@Test
@@ -199,8 +190,7 @@ public class DefaultQuerySecurityIntegrationTest {
createAndPopulateRegion(regionName, regionShortcut);
String queryString = "SELECT object.privateID, object.name FROM /" +
regionName + " object";
-
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(queryString,
- regionShortcut);
+
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(queryString);
}
@Test
@@ -212,8 +202,7 @@ public class DefaultQuerySecurityIntegrationTest {
createAndPopulateRegion(regionName, regionShortcut);
String queryString = "SELECT object.getName() FROM /" + regionName + "
object";
-
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(queryString,
- regionShortcut);
+
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(queryString);
}
@Test
@@ -225,8 +214,7 @@ public class DefaultQuerySecurityIntegrationTest {
createAndPopulateRegion(regionName, regionShortcut);
String queryString = "SELECT object.getId(), object.getName() FROM /" +
regionName + " object";
-
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(queryString,
- regionShortcut);
+
executeQueryAndAssertThatAuthorizerWasInstantiatedExpectedAmountOfTimes(queryString);
}
private static class SpyQueryExecutor implements Answer {
diff --git
a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/DefaultQueryServiceIntegrationTest.java
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/DefaultQueryServiceIntegrationTest.java
new file mode 100644
index 0000000..7f410df
--- /dev/null
+++
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/DefaultQueryServiceIntegrationTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express
+ * or implied. See the License for the specific language governing permissions
and limitations under
+ * the License.
+ */
+package org.apache.geode.cache.query.internal;
+
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.cache.RegionShortcut;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.test.assertj.LogFileAssert;
+import org.apache.geode.test.junit.categories.OQLQueryTest;
+import org.apache.geode.test.junit.rules.ServerStarterRule;
+
+@Category(OQLQueryTest.class)
+public class DefaultQueryServiceIntegrationTest {
+ private File logFile;
+ private InternalCache spiedCache;
+
+ @Rule
+ public TestName testName = new TestName();
+
+ @Rule
+ public ServerStarterRule server = new ServerStarterRule();
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Before
+ public void setUp() throws IOException {
+ logFile = temporaryFolder.newFile(testName.getMethodName() + ".log");
+ server.withProperty("log-file", logFile.getAbsolutePath())
+ .withRegion(RegionShortcut.LOCAL, testName.getMethodName())
+ .startServer();
+
+ spiedCache = spy(server.getCache());
+ }
+
+ @Test
+ public void constructorShouldThrowExceptionWhenCacheIsNull() {
+ assertThatThrownBy(() -> new DefaultQueryService(null))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Cache must not be null");
+ }
+
+ @Test
+ public void constructorShouldLogWarningWhenMethodAuthorizerIsNull() {
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+ when(mockService.getMethodAuthorizer()).thenReturn(null);
+
when(spiedCache.getService(QueryConfigurationService.class)).thenReturn(mockService);
+
+ assertThatCode(() -> new
DefaultQueryService(spiedCache)).doesNotThrowAnyException();
+ LogFileAssert.assertThat(logFile).contains(
+ "MethodInvocationAuthorizer returned by the QueryConfigurationService
is null, problems might arise if there are queries using method invocations.");
+ }
+}
diff --git
a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/ExecutionContextIntegrationTest.java
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/ExecutionContextIntegrationTest.java
index 53a4c71..85ba93b 100644
---
a/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/ExecutionContextIntegrationTest.java
+++
b/geode-core/src/integrationTest/java/org/apache/geode/cache/query/internal/ExecutionContextIntegrationTest.java
@@ -23,6 +23,7 @@ import static
org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANA
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -33,13 +34,14 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import org.apache.geode.SystemFailure;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.query.NameResolutionException;
import org.apache.geode.cache.query.TypeMismatchException;
import org.apache.geode.cache.query.security.MethodInvocationAuthorizer;
+import org.apache.geode.cache.query.security.RegExMethodAuthorizer;
import org.apache.geode.cache.query.security.RestrictedMethodAuthorizer;
import org.apache.geode.examples.SimpleSecurityManager;
+import org.apache.geode.internal.cache.InternalCache;
import org.apache.geode.test.dunit.ThreadUtils;
import org.apache.geode.test.junit.categories.OQLQueryTest;
import org.apache.geode.test.junit.rules.ServerStarterRule;
@@ -131,6 +133,14 @@ public class ExecutionContextIntegrationTest {
return i;
}
+ private void restartServerWithSecurityEnabled() {
+ server.stopMember();
+ server.withProperty(SECURITY_MANAGER,
SimpleSecurityManager.class.getName())
+ .withProperty("security-username", "cluster")
+ .withProperty("security-password", "cluster")
+ .startServer();
+ }
+
@Test
public void constructorShouldUseConfiguredMethodAuthorizer() {
ExecutionContext unsecuredContext = new QueryExecutionContext(null,
server.getCache());
@@ -140,17 +150,35 @@ public class ExecutionContextIntegrationTest {
assertThat(noOpAuthorizer).isNotNull();
assertThat(noOpAuthorizer).isSameAs(QueryConfigurationServiceImpl.getNoOpAuthorizer());
+ // Security Enabled -> RestrictedMethodAuthorizer
+ restartServerWithSecurityEnabled();
+ ExecutionContext securedContext = new QueryExecutionContext(null,
server.getCache());
+ MethodInvocationAuthorizer authorizer =
securedContext.getMethodInvocationAuthorizer();
+ assertThat(authorizer).isNotNull();
+ assertThat(authorizer).isInstanceOf(RestrictedMethodAuthorizer.class);
+ }
+
+ @Test
+ public void resetShouldUpdateTheMethodInvocationAuthorizer() throws
ClassNotFoundException {
server.stopMember();
// Security Enabled -> RestrictedMethodAuthorizer
- server.withProperty(SECURITY_MANAGER,
SimpleSecurityManager.class.getName())
- .withProperty("security-username", "cluster")
- .withProperty("security-password", "cluster")
- .startServer();
+ restartServerWithSecurityEnabled();
ExecutionContext securedContext = new QueryExecutionContext(null,
server.getCache());
MethodInvocationAuthorizer authorizer =
securedContext.getMethodInvocationAuthorizer();
assertThat(authorizer).isNotNull();
assertThat(authorizer).isInstanceOf(RestrictedMethodAuthorizer.class);
+
+ // Change the authorizer
+ InternalCache internalCache = server.getCache();
+
internalCache.getService(QueryConfigurationService.class).updateMethodAuthorizer(internalCache,
+ RegExMethodAuthorizer.class.getName(), Collections.emptySet());
+
+ // Reset the context - used by CQs when processing events
+ securedContext.reset();
+ MethodInvocationAuthorizer newAuthorizer =
securedContext.getMethodInvocationAuthorizer();
+ assertThat(newAuthorizer).isNotNull();
+ assertThat(newAuthorizer).isInstanceOf(RegExMethodAuthorizer.class);
}
@Test
@@ -323,9 +351,6 @@ public class ExecutionContextIntegrationTest {
while (runtimeIterator.hasNext()) {
assertIteratorScopeMultiThreaded(runtimeIterator);
}
- } catch (VirtualMachineError e) {
- SystemFailure.initiateFailure(e);
- throw e;
} catch (Throwable th) {
throw new RuntimeException(th);
}
diff --git
a/geode-core/src/main/java/org/apache/geode/cache/query/internal/DefaultQueryService.java
b/geode-core/src/main/java/org/apache/geode/cache/query/internal/DefaultQueryService.java
index 2d914bb..cec72be 100644
---
a/geode-core/src/main/java/org/apache/geode/cache/query/internal/DefaultQueryService.java
+++
b/geode-core/src/main/java/org/apache/geode/cache/query/internal/DefaultQueryService.java
@@ -108,14 +108,20 @@ public class DefaultQueryService implements
InternalQueryService {
private Map<Region, HashSet<IndexCreationData>> indexDefinitions =
Collections.synchronizedMap(new HashMap<>());
-
public DefaultQueryService(InternalCache cache) {
if (cache == null)
- throw new IllegalArgumentException("cache must not be null");
- this.cache = cache;
+ throw new IllegalArgumentException("Cache must not be null");
QueryConfigurationService queryConfigurationService =
cache.getService(QueryConfigurationService.class);
+
+ this.cache = cache;
this.methodInvocationAuthorizer =
queryConfigurationService.getMethodAuthorizer();
+
+ // Should never happen, adding the check as a safeguard.
+ if (this.methodInvocationAuthorizer == null) {
+ logger.warn(
+ "MethodInvocationAuthorizer returned by the
QueryConfigurationService is null, problems might arise if there are queries
using method invocations.");
+ }
}
/**
diff --git
a/geode-core/src/main/java/org/apache/geode/cache/query/internal/ExecutionContext.java
b/geode-core/src/main/java/org/apache/geode/cache/query/internal/ExecutionContext.java
index afaba37..54a6e6e 100644
---
a/geode-core/src/main/java/org/apache/geode/cache/query/internal/ExecutionContext.java
+++
b/geode-core/src/main/java/org/apache/geode/cache/query/internal/ExecutionContext.java
@@ -102,13 +102,19 @@ public class ExecutionContext {
static final ThreadLocal<AtomicBoolean> isCanceled =
ThreadLocal.withInitial(AtomicBoolean::new);
- // Authorizer to use during the query execution.
- private final MethodInvocationAuthorizer methodInvocationAuthorizer;
+ /**
+ * Authorizer to use during query execution.
+ * It can not be changed for queries in flight, but it should be modifiable
for running CQs,
+ * that's the only reason why this field is not marked as {@code final}.
+ *
+ * @see ExecutionContext#reset()
+ */
+ private MethodInvocationAuthorizer methodInvocationAuthorizer;
+ private final QueryConfigurationService queryConfigurationService;
/**
* Returns the {@link MethodInvocationAuthorizer} that will be used, if
needed, during the
- * execution
- * of the query associated with this context.
+ * execution of the query associated with this context.
*
* @return the {@link MethodInvocationAuthorizer} that will be used, if
needed, during the
* execution of the query associated with this context.
@@ -124,16 +130,11 @@ public class ExecutionContext {
* @see org.apache.geode.cache.Region#query
*/
public ExecutionContext(Object[] bindArguments, InternalCache cache) {
- this.bindArguments = bindArguments;
this.cache = cache;
+ this.bindArguments = bindArguments;
this.cancelationTask = Optional.empty();
-
- // Authorization & authentication logic happens on server side only.
- if (cache.isClient()) {
- this.methodInvocationAuthorizer =
QueryConfigurationServiceImpl.getNoOpAuthorizer();
- } else {
- this.methodInvocationAuthorizer =
cache.getQueryService().getMethodInvocationAuthorizer();
- }
+ this.queryConfigurationService =
cache.getService(QueryConfigurationService.class);
+ this.methodInvocationAuthorizer =
queryConfigurationService.getMethodAuthorizer();
}
Optional<ScheduledFuture> getCancelationTask() {
@@ -585,6 +586,8 @@ public class ExecutionContext {
*/
public void reset() {
scopes.clear();
+ // Make sure we use the most up to date authorizer in CQs.
+ methodInvocationAuthorizer =
queryConfigurationService.getMethodAuthorizer();
}
public BucketRegion getBucketRegion() {
diff --git
a/geode-core/src/main/java/org/apache/geode/cache/query/internal/cq/ServerCQ.java
b/geode-core/src/main/java/org/apache/geode/cache/query/internal/cq/ServerCQ.java
index abc589c..c36cd4b 100644
---
a/geode-core/src/main/java/org/apache/geode/cache/query/internal/cq/ServerCQ.java
+++
b/geode-core/src/main/java/org/apache/geode/cache/query/internal/cq/ServerCQ.java
@@ -54,6 +54,13 @@ public interface ServerCQ extends InternalCqQuery {
void removeFromCqResultKeys(Object key, boolean isTokenMode);
/**
+ * Invalidates the internal cache containing the keys that are part of the
CQ query results.
+ * Once this method finishes, the CQ engine will not apply the internal
optimization for already
+ * seen keys anymore, not until the cache is manually rebuilt.
+ */
+ void invalidateCqResultKeys();
+
+ /**
* Sets the CQ Results key cache state as initialized.
*/
void setCqResultsCacheInitialized();
diff --git
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/AttributeDescriptorTest.java
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/AttributeDescriptorTest.java
index 34f4062..f7c2a20 100644
---
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/AttributeDescriptorTest.java
+++
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/AttributeDescriptorTest.java
@@ -71,9 +71,10 @@ public class AttributeDescriptorTest {
typeRegistry = new TypeRegistry(mockCache, true);
methodInvocationAuthorizer = spy(MethodInvocationAuthorizer.class);
- InternalQueryService mockQueryService = mock(InternalQueryService.class);
- when(mockCache.getQueryService()).thenReturn(mockQueryService);
-
when(mockQueryService.getMethodInvocationAuthorizer()).thenReturn(methodInvocationAuthorizer);
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockService.getMethodAuthorizer()).thenReturn(methodInvocationAuthorizer);
+
+
when(mockCache.getService(QueryConfigurationService.class)).thenReturn(mockService);
queryExecutionContext = new QueryExecutionContext(null, mockCache);
}
diff --git
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/CompiledAggregateFunctionTest.java
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/CompiledAggregateFunctionTest.java
index f86d424..c7b77d5 100644
---
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/CompiledAggregateFunctionTest.java
+++
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/CompiledAggregateFunctionTest.java
@@ -51,9 +51,9 @@ public class CompiledAggregateFunctionTest {
@Before
public void setUp() throws Exception {
cache = mock(InternalCache.class);
- when(cache.getQueryService()).thenReturn(mock(InternalQueryService.class));
- when(cache.getQueryService().getMethodInvocationAuthorizer())
- .thenReturn(mock(MethodInvocationAuthorizer.class));
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockService.getMethodAuthorizer()).thenReturn(mock(MethodInvocationAuthorizer.class));
+
when(cache.getService(QueryConfigurationService.class)).thenReturn(mockService);
bucketList = Collections.singletonList(1);
}
diff --git
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/ExecutionContextTest.java
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/ExecutionContextTest.java
index 8f00610..4d37c90 100644
---
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/ExecutionContextTest.java
+++
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/ExecutionContextTest.java
@@ -16,8 +16,6 @@ package org.apache.geode.cache.query.internal;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Test;
@@ -29,30 +27,19 @@ import org.apache.geode.internal.cache.InternalCache;
public class ExecutionContextTest {
@Test
- public void constructorShouldUseNoOpMethodAuthorizerOnClientSide() {
+ public void constructorShouldUseConfiguredMethodAuthorizer() {
InternalCache mockCache = mock(InternalCache.class);
- when(mockCache.isClient()).thenReturn(true);
-
- ExecutionContext executionContext = new ExecutionContext(null, mockCache);
- assertThat(executionContext.getMethodInvocationAuthorizer())
- .isSameAs(QueryConfigurationServiceImpl.getNoOpAuthorizer());
- verify(mockCache, times(0)).getQueryService();
- }
-
- @Test
- public void constructorShouldUseConfiguredMethodAuthorizerOnServerSide() {
- InternalCache mockCache = mock(InternalCache.class);
- InternalQueryService mockQueryService = mock(InternalQueryService.class);
- when(mockCache.getQueryService()).thenReturn(mockQueryService);
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockCache.getService(QueryConfigurationService.class)).thenReturn(mockService);
MethodInvocationAuthorizer noOpAuthorizer =
QueryConfigurationServiceImpl.getNoOpAuthorizer();
-
when(mockQueryService.getMethodInvocationAuthorizer()).thenReturn(noOpAuthorizer);
+ when(mockService.getMethodAuthorizer()).thenReturn(noOpAuthorizer);
ExecutionContext executionContextNoOpAuthorizer = new
ExecutionContext(null, mockCache);
assertThat(executionContextNoOpAuthorizer.getMethodInvocationAuthorizer())
.isSameAs(noOpAuthorizer);
MethodInvocationAuthorizer restrictedAuthorizer = new
RestrictedMethodAuthorizer(mockCache);
-
when(mockQueryService.getMethodInvocationAuthorizer()).thenReturn(restrictedAuthorizer);
+ when(mockService.getMethodAuthorizer()).thenReturn(restrictedAuthorizer);
ExecutionContext executionContextRestrictedAuthorizer = new
ExecutionContext(null, mockCache);
assertThat(executionContextRestrictedAuthorizer.getMethodInvocationAuthorizer())
.isSameAs(restrictedAuthorizer);
diff --git
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/MethodDispatchTest.java
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/MethodDispatchTest.java
index 3ae72f3..eaae032 100644
---
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/MethodDispatchTest.java
+++
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/MethodDispatchTest.java
@@ -58,10 +58,11 @@ public class MethodDispatchTest {
emptyList = Collections.emptyList();
methodInvocationAuthorizer = spy(MethodInvocationAuthorizer.class);
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockService.getMethodAuthorizer()).thenReturn(methodInvocationAuthorizer);
InternalCache mockCache = mock(InternalCache.class);
- InternalQueryService mockQueryService = mock(InternalQueryService.class);
- when(mockCache.getQueryService()).thenReturn(mockQueryService);
-
when(mockQueryService.getMethodInvocationAuthorizer()).thenReturn(methodInvocationAuthorizer);
+
when(mockCache.getService(QueryConfigurationService.class)).thenReturn(mockService);
+
queryExecutionContext = new QueryExecutionContext(null, mockCache);
}
diff --git
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/NWayMergeResultsTest.java
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/NWayMergeResultsTest.java
index c341da5..baafff3 100644
---
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/NWayMergeResultsTest.java
+++
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/NWayMergeResultsTest.java
@@ -45,10 +45,10 @@ public class NWayMergeResultsTest {
@Before
public void setUp() {
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockService.getMethodAuthorizer()).thenReturn(mock(MethodInvocationAuthorizer.class));
InternalCache mockCache = mock(InternalCache.class);
-
when(mockCache.getQueryService()).thenReturn(mock(InternalQueryService.class));
- when(mockCache.getQueryService().getMethodInvocationAuthorizer())
- .thenReturn(mock(MethodInvocationAuthorizer.class));
+
when(mockCache.getService(QueryConfigurationService.class)).thenReturn(mockService);
context = new ExecutionContext(null, mockCache);
}
diff --git
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/QCompilerTest.java
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/QCompilerTest.java
index 74bc4f1..fcf4bbd 100644
---
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/QCompilerTest.java
+++
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/QCompilerTest.java
@@ -46,10 +46,10 @@ public class QCompilerTest {
@Before
public void setUp() {
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockService.getMethodAuthorizer()).thenReturn(mock(MethodInvocationAuthorizer.class));
InternalCache mockCache = mock(InternalCache.class);
-
when(mockCache.getQueryService()).thenReturn(mock(InternalQueryService.class));
- when(mockCache.getQueryService().getMethodInvocationAuthorizer())
- .thenReturn(mock(MethodInvocationAuthorizer.class));
+
when(mockCache.getService(QueryConfigurationService.class)).thenReturn(mockService);
context = new QueryExecutionContext(null, mockCache);
}
diff --git
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/QueryExecutionContextTest.java
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/QueryExecutionContextTest.java
index f7ec2fc..6edc038 100644
---
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/QueryExecutionContextTest.java
+++
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/QueryExecutionContextTest.java
@@ -30,10 +30,10 @@ public class QueryExecutionContextTest {
@Before
public void setUp() {
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockService.getMethodAuthorizer()).thenReturn(mock(MethodInvocationAuthorizer.class));
InternalCache mockCache = mock(InternalCache.class);
-
when(mockCache.getQueryService()).thenReturn(mock(InternalQueryService.class));
- when(mockCache.getQueryService().getMethodInvocationAuthorizer())
- .thenReturn(mock(MethodInvocationAuthorizer.class));
+
when(mockCache.getService(QueryConfigurationService.class)).thenReturn(mockService);
context = new QueryExecutionContext(null, mockCache);
}
diff --git
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/CompactRangeIndexTest.java
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/CompactRangeIndexTest.java
index abd7dcb..2d8a3e8 100644
---
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/CompactRangeIndexTest.java
+++
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/CompactRangeIndexTest.java
@@ -30,7 +30,7 @@ import org.mockito.junit.MockitoRule;
import org.apache.geode.Statistics;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.query.internal.DefaultQueryService;
-import org.apache.geode.cache.query.internal.InternalQueryService;
+import org.apache.geode.cache.query.internal.QueryConfigurationService;
import
org.apache.geode.cache.query.internal.index.AbstractIndex.InternalIndexStatistics;
import org.apache.geode.cache.query.security.MethodInvocationAuthorizer;
import org.apache.geode.cache.query.types.ObjectType;
@@ -60,15 +60,16 @@ public class CompactRangeIndexTest {
@Before
public void setup() {
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockService.getMethodAuthorizer()).thenReturn(mock(MethodInvocationAuthorizer.class));
+
when(region.getCache()).thenReturn(cache);
when(region.getAttributes()).thenReturn(mock(RegionAttributes.class));
when(cache.getDistributedSystem()).thenReturn(ids);
when(ids.createAtomicStatistics(any(), eq("Index1"))).thenReturn(stats);
when(cache.getRegion(any())).thenReturn(region);
when(img.putCanonicalizedIteratorNameIfAbsent(any())).thenReturn("index_iter");
- when(cache.getQueryService()).thenReturn(mock(InternalQueryService.class));
- when(cache.getQueryService().getMethodInvocationAuthorizer())
- .thenReturn(mock(MethodInvocationAuthorizer.class));
+
when(cache.getService(QueryConfigurationService.class)).thenReturn(mockService);
IndexCreationHelper helper = new
FunctionalIndexCreationHelper("/exampleRegion", "status",
"*", null, cache, null, img);
@@ -85,7 +86,6 @@ public class CompactRangeIndexTest {
when(region.getCache()).thenReturn(cache);
when(cache.getCachePerfStats()).thenReturn(cacheperfstat);
when(cache.getQueryService()).thenReturn(queryservice);
- when(queryservice.getMethodInvocationAuthorizer()).thenReturn(null);
index.addMapping(entry);
verify(indstats).incNumUpdates();
@@ -97,7 +97,6 @@ public class CompactRangeIndexTest {
when(region.getCache()).thenReturn(cache);
when(cache.getCachePerfStats()).thenReturn(cacheperfstat);
when(cache.getQueryService()).thenReturn(queryservice);
- when(queryservice.getMethodInvocationAuthorizer()).thenReturn(null);
index.removeMapping(entry, 3);
@@ -108,7 +107,6 @@ public class CompactRangeIndexTest {
when(region.getCache()).thenReturn(cache);
when(cache.getCachePerfStats()).thenReturn(cacheperfstat);
when(cache.getQueryService()).thenReturn(queryservice);
- when(queryservice.getMethodInvocationAuthorizer()).thenReturn(null);
index.removeMapping(entry, 1);
index.addMapping(entry);
diff --git
a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryEvaluatorTest.java
b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryEvaluatorTest.java
index 8336733..cc49d56 100644
---
a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryEvaluatorTest.java
+++
b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryEvaluatorTest.java
@@ -40,8 +40,8 @@ import org.apache.geode.cache.query.internal.CompiledSelect;
import org.apache.geode.cache.query.internal.CompiledValue;
import org.apache.geode.cache.query.internal.DefaultQuery;
import org.apache.geode.cache.query.internal.ExecutionContext;
-import org.apache.geode.cache.query.internal.InternalQueryService;
import org.apache.geode.cache.query.internal.LinkedResultSet;
+import org.apache.geode.cache.query.internal.QueryConfigurationService;
import org.apache.geode.cache.query.internal.types.ObjectTypeImpl;
import org.apache.geode.cache.query.security.MethodInvocationAuthorizer;
import org.apache.geode.distributed.internal.DistributionMessage;
@@ -66,14 +66,15 @@ public class PartitionedRegionQueryEvaluatorTest {
@Before
public void setup() throws Exception {
+ QueryConfigurationService mockService =
mock(QueryConfigurationService.class);
+
when(mockService.getMethodAuthorizer()).thenReturn(mock(MethodInvocationAuthorizer.class));
+
localNode = new InternalDistributedMember("localhost", 8888);
remoteNodeA = new InternalDistributedMember("localhost", 8889);
remoteNodeB = new InternalDistributedMember("localhost", 8890);
GemFireCacheImpl cache = Fakes.cache();
system = (InternalDistributedSystem) cache.getDistributedSystem();
- when(cache.getQueryService()).thenReturn(mock(InternalQueryService.class));
- when(cache.getQueryService().getMethodInvocationAuthorizer())
- .thenReturn(mock(MethodInvocationAuthorizer.class));
+
when(cache.getService(QueryConfigurationService.class)).thenReturn(mockService);
allNodes.add(localNode);
allNodes.add(remoteNodeA);
diff --git
a/geode-cq/src/main/java/org/apache/geode/cache/query/cq/internal/ServerCQImpl.java
b/geode-cq/src/main/java/org/apache/geode/cache/query/cq/internal/ServerCQImpl.java
index 2d5b67b..4be8817 100644
---
a/geode-cq/src/main/java/org/apache/geode/cache/query/cq/internal/ServerCQImpl.java
+++
b/geode-cq/src/main/java/org/apache/geode/cache/query/cq/internal/ServerCQImpl.java
@@ -280,7 +280,7 @@ public class ServerCQImpl extends CqQueryImpl implements
DataSerializable, Serve
*
* @return String modified query.
*/
- private Query constructServerSideQuery() throws QueryException {
+ Query constructServerSideQuery() throws QueryException {
InternalCache cache = cqService.getInternalCache();
DefaultQuery locQuery = (DefaultQuery)
cache.getLocalQueryService().newQuery(this.queryString);
CompiledSelect select = locQuery.getSimpleSelect();
@@ -363,6 +363,20 @@ public class ServerCQImpl extends CqQueryImpl implements
DataSerializable, Serve
}
}
+ @Override
+ public void invalidateCqResultKeys() {
+ if (!CqServiceProvider.MAINTAIN_KEYS) {
+ return;
+ }
+
+ if (this.cqResultKeys != null) {
+ synchronized (this.cqResultKeys) {
+ this.cqResultKeys.clear();
+ this.cqResultKeysInitialized = false;
+ }
+ }
+ }
+
/**
* Marks the key as destroyed in the CQ Results key cache.
*/
diff --git
a/geode-cq/src/test/java/org/apache/geode/cache/query/cq/internal/ServerCQImplTest.java
b/geode-cq/src/test/java/org/apache/geode/cache/query/cq/internal/ServerCQImplTest.java
new file mode 100644
index 0000000..3fdf818
--- /dev/null
+++
b/geode-cq/src/test/java/org/apache/geode/cache/query/cq/internal/ServerCQImplTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express
+ * or implied. See the License for the specific language governing permissions
and limitations under
+ * the License.
+ */
+package org.apache.geode.cache.query.cq.internal;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.DataPolicy;
+import org.apache.geode.cache.query.Query;
+import org.apache.geode.cache.query.QueryException;
+import org.apache.geode.cache.query.internal.CqStateImpl;
+import org.apache.geode.internal.cache.LocalRegion;
+import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
+import org.apache.geode.internal.logging.InternalLogWriter;
+
+public class ServerCQImplTest {
+ private ServerCQImpl serverCq;
+ private CqServiceImpl mockCqService;
+
+ @Before
+ @SuppressWarnings("deprecation")
+ public void setUp() {
+ mockCqService = mock(CqServiceImpl.class);
+ when(mockCqService.getCache()).thenReturn(mock(Cache.class));
+ when(mockCqService.getCache().getSecurityLoggerI18n())
+ .thenReturn(mock(InternalLogWriter.class));
+ serverCq = spy(
+ new ServerCQImpl(mockCqService, "cqName", "SELECT * FROM /region",
false, "test"));
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void invalidateCqResultKeysShouldClearCacheAndDisableInitializedFlag()
+ throws QueryException {
+ ClientProxyMembershipID mockClientProxyMembershipID =
mock(ClientProxyMembershipID.class);
+ doNothing().when(serverCq).validateCq();
+ doReturn(mock(Query.class)).when(serverCq).constructServerSideQuery();
+ LocalRegion mockLocalRegion = mock(LocalRegion.class);
+ when(mockLocalRegion.getDataPolicy()).thenReturn(DataPolicy.PARTITION);
+
when(mockCqService.getCache().getRegion(any())).thenReturn(mockLocalRegion);
+ doNothing().when(serverCq).updateCqCreateStats();
+ serverCq.registerCq(mockClientProxyMembershipID, null, CqStateImpl.INIT);
+
+ // Initialize cache
+ serverCq.addToCqResultKeys("key1");
+ serverCq.setCqResultsCacheInitialized();
+ assertThat(serverCq.cqResultKeysInitialized).isTrue();
+ assertThat(serverCq.isPartOfCqResult("key1")).isTrue();
+
+ // Invalidate and assert results
+ serverCq.invalidateCqResultKeys();
+ assertThat(serverCq.cqResultKeysInitialized).isFalse();
+ assertThat(serverCq.isPartOfCqResult("key1")).isFalse();
+ }
+}