This is an automated email from the ASF dual-hosted git repository. gosullivan 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 6011e09 GEODE-3127: add function execution to new client protocol. (#1357) 6011e09 is described below commit 6011e094432c2e528d1c04912d63a7f51fa7c6f4 Author: Galen O'Sullivan <gosulli...@pivotal.io> AuthorDate: Fri Feb 2 10:03:12 2018 -0800 GEODE-3127: add function execution to new client protocol. (#1357) * GEODE-3127: add function execution to new client protocol. This only supports function execution on a region so far. It assumes the default result collector, which returns a list of results, so the response message returns a list of results. * MessageExecutionContext uses InternalCache instead of Cache * Remove super.setUp calls from operation handlers because the @Before annotation already ensures these are called before the @Before methods of child classes. --- .../client/protocol/ClientProtocolService.java | 5 +- .../src/main/proto/v1/clientProtocol.proto | 5 + .../src/main/proto/v1/function_API.proto | 29 ++ .../v1/LocatorMessageExecutionContext.java | 4 +- .../protobuf/v1/MessageExecutionContext.java | 4 +- .../protobuf/v1/ProtobufProtocolService.java | 4 +- .../protobuf/v1/ProtobufSerializationService.java | 6 +- .../protobuf/v1/ServerMessageExecutionContext.java | 12 +- ...uteFunctionOnRegionRequestOperationHandler.java | 135 ++++++++ .../registry/ProtobufOperationContextRegistry.java | 13 +- .../internal/protocol/TestExecutionContext.java | 4 +- .../v1/FunctionExecutionIntegrationTest.java | 360 +++++++++++++++++++++ ...onOnRegionRequestOperationHandlerJUnitTest.java | 161 +++++++++ .../GetAllRequestOperationHandlerJUnitTest.java | 2 - ...egionNamesRequestOperationHandlerJUnitTest.java | 6 +- .../GetRegionRequestOperationHandlerJUnitTest.java | 6 +- .../GetRequestOperationHandlerJUnitTest.java | 2 - .../GetServerOperationHandlerJUnitTest.java | 2 - .../v1/operations/OperationHandlerJUnitTest.java | 5 +- .../PutAllRequestOperationHandlerJUnitTest.java | 1 - .../PutRequestOperationHandlerJUnitTest.java | 2 - .../RemoveRequestOperationHandlerJUnitTest.java | 2 - 22 files changed, 730 insertions(+), 40 deletions(-) diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/client/protocol/ClientProtocolService.java b/geode-core/src/main/java/org/apache/geode/internal/cache/client/protocol/ClientProtocolService.java index d31a4d5..855cb09 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/client/protocol/ClientProtocolService.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/client/protocol/ClientProtocolService.java @@ -16,8 +16,8 @@ package org.apache.geode.internal.cache.client.protocol; import org.apache.geode.StatisticsFactory; -import org.apache.geode.cache.Cache; import org.apache.geode.distributed.internal.InternalLocator; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.security.SecurityService; /** @@ -32,7 +32,8 @@ public interface ClientProtocolService { * handshake has happened. * */ - ClientProtocolProcessor createProcessorForCache(Cache cache, SecurityService securityService); + ClientProtocolProcessor createProcessorForCache(InternalCache cache, + SecurityService securityService); /** * Create a locator processor. The locator does not currently provide any authentication. diff --git a/geode-protobuf-messages/src/main/proto/v1/clientProtocol.proto b/geode-protobuf-messages/src/main/proto/v1/clientProtocol.proto index 21bc2fa..6bbe295 100644 --- a/geode-protobuf-messages/src/main/proto/v1/clientProtocol.proto +++ b/geode-protobuf-messages/src/main/proto/v1/clientProtocol.proto @@ -25,6 +25,7 @@ import "v1/region_API.proto"; import "v1/locator_API.proto"; import "v1/basicTypes.proto"; import "v1/connection_API.proto"; +import "v1/function_API.proto"; message Message { oneof messageType { @@ -46,6 +47,8 @@ message Request { GetRegionNamesRequest getRegionNamesRequest = 41; GetRegionRequest getRegionRequest = 42; + ExecuteFunctionOnRegionRequest executeFunctionOnRegionRequest = 43; + AuthenticationRequest authenticationRequest = 100; } } @@ -63,6 +66,8 @@ message Response { GetRegionNamesResponse getRegionNamesResponse = 41; GetRegionResponse getRegionResponse = 42; + ExecuteFunctionOnRegionResponse executeFunctionOnRegionResponse= 43; + AuthenticationResponse authenticationResponse = 100; ErrorResponse errorResponse = 1000; diff --git a/geode-protobuf-messages/src/main/proto/v1/function_API.proto b/geode-protobuf-messages/src/main/proto/v1/function_API.proto new file mode 100644 index 0000000..77d2280 --- /dev/null +++ b/geode-protobuf-messages/src/main/proto/v1/function_API.proto @@ -0,0 +1,29 @@ +/* + * 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. + */ +syntax = "proto3"; +package org.apache.geode.internal.protocol.protobuf.v1; + +import "v1/basicTypes.proto"; + +message ExecuteFunctionOnRegionRequest { + string functionID = 1; + string region = 2; + EncodedValue arguments = 3; + repeated EncodedValue keyFilter = 4; +} + +message ExecuteFunctionOnRegionResponse { + repeated EncodedValue results = 1; // some functions don't return arguments. +} diff --git a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/LocatorMessageExecutionContext.java b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/LocatorMessageExecutionContext.java index 98908de..a38f49c 100644 --- a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/LocatorMessageExecutionContext.java +++ b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/LocatorMessageExecutionContext.java @@ -17,8 +17,8 @@ package org.apache.geode.internal.protocol.protobuf.v1; import org.apache.geode.annotations.Experimental; -import org.apache.geode.cache.Cache; import org.apache.geode.distributed.Locator; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.exception.InvalidExecutionContextException; import org.apache.geode.internal.protocol.protobuf.statistics.ClientStatistics; import org.apache.geode.internal.protocol.protobuf.v1.state.ProtobufConnectionStateProcessor; @@ -41,7 +41,7 @@ public class LocatorMessageExecutionContext extends MessageExecutionContext { * @throws InvalidExecutionContextException if there is no cache available */ @Override - public Cache getCache() throws InvalidExecutionContextException { + public InternalCache getCache() throws InvalidExecutionContextException { setConnectionStateProcessor(new ProtobufConnectionTerminatingStateProcessor()); throw new InvalidExecutionContextException( "Operations on the locator should not to try to operate on a server"); diff --git a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/MessageExecutionContext.java b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/MessageExecutionContext.java index c97f596..80d560b 100644 --- a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/MessageExecutionContext.java +++ b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/MessageExecutionContext.java @@ -15,8 +15,8 @@ package org.apache.geode.internal.protocol.protobuf.v1; import org.apache.geode.annotations.Experimental; -import org.apache.geode.cache.Cache; import org.apache.geode.distributed.Locator; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.exception.InvalidExecutionContextException; import org.apache.geode.internal.protocol.protobuf.statistics.ClientStatistics; import org.apache.geode.internal.protocol.protobuf.v1.state.ProtobufConnectionStateProcessor; @@ -36,7 +36,7 @@ public abstract class MessageExecutionContext { return protobufConnectionStateProcessor; } - public abstract Cache getCache() throws InvalidExecutionContextException; + public abstract InternalCache getCache() throws InvalidExecutionContextException; public abstract Locator getLocator() throws InvalidExecutionContextException; diff --git a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ProtobufProtocolService.java b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ProtobufProtocolService.java index 8d7d718..bfc2048 100644 --- a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ProtobufProtocolService.java +++ b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ProtobufProtocolService.java @@ -15,8 +15,8 @@ package org.apache.geode.internal.protocol.protobuf.v1; import org.apache.geode.StatisticsFactory; -import org.apache.geode.cache.Cache; import org.apache.geode.distributed.internal.InternalLocator; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.client.protocol.ClientProtocolProcessor; import org.apache.geode.internal.cache.client.protocol.ClientProtocolService; import org.apache.geode.internal.protocol.protobuf.ProtocolVersion; @@ -38,7 +38,7 @@ public class ProtobufProtocolService implements ClientProtocolService { } @Override - public ClientProtocolProcessor createProcessorForCache(Cache cache, + public ClientProtocolProcessor createProcessorForCache(InternalCache cache, SecurityService securityService) { assert (statistics != null); diff --git a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ProtobufSerializationService.java b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ProtobufSerializationService.java index 40a9cd7..5442776 100644 --- a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ProtobufSerializationService.java +++ b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ProtobufSerializationService.java @@ -33,11 +33,15 @@ public class ProtobufSerializationService implements SerializationService<BasicT * @param value the value to be encoded * * @return EncodedValue message with the serialized value - * @throws EncodingException */ @Override public BasicTypes.EncodedValue encode(Object value) throws EncodingException { + if (value == null) { + return BasicTypes.EncodedValue.getDefaultInstance(); + } + BasicTypes.EncodedValue.Builder builder = BasicTypes.EncodedValue.newBuilder(); + try { ProtobufEncodingTypes protobufEncodingTypes = ProtobufEncodingTypes.valueOf(value.getClass()); switch (protobufEncodingTypes) { diff --git a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ServerMessageExecutionContext.java b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ServerMessageExecutionContext.java index bf14b43..1abd1ad 100644 --- a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ServerMessageExecutionContext.java +++ b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/ServerMessageExecutionContext.java @@ -17,19 +17,19 @@ package org.apache.geode.internal.protocol.protobuf.v1; import org.apache.geode.annotations.Experimental; -import org.apache.geode.cache.Cache; import org.apache.geode.distributed.Locator; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.exception.InvalidExecutionContextException; import org.apache.geode.internal.protocol.protobuf.statistics.ClientStatistics; import org.apache.geode.internal.protocol.protobuf.v1.state.ProtobufConnectionStateProcessor; @Experimental public class ServerMessageExecutionContext extends MessageExecutionContext { - private final Cache cache; + private final InternalCache cache; - public ServerMessageExecutionContext(Cache cache, ClientStatistics statistics, - ProtobufConnectionStateProcessor initialProtobufConnectionStateProcessor) { - super(statistics, initialProtobufConnectionStateProcessor); + public ServerMessageExecutionContext(InternalCache cache, ClientStatistics statistics, + ProtobufConnectionStateProcessor initialConnectionStateProcessor) { + super(statistics, initialConnectionStateProcessor); this.cache = cache; } @@ -40,7 +40,7 @@ public class ServerMessageExecutionContext extends MessageExecutionContext { * @throws InvalidExecutionContextException if there is no cache available */ @Override - public Cache getCache() throws InvalidExecutionContextException { + public InternalCache getCache() throws InvalidExecutionContextException { return cache; } diff --git a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/operations/ExecuteFunctionOnRegionRequestOperationHandler.java b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/operations/ExecuteFunctionOnRegionRequestOperationHandler.java new file mode 100644 index 0000000..932db99 --- /dev/null +++ b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/operations/ExecuteFunctionOnRegionRequestOperationHandler.java @@ -0,0 +1,135 @@ +/* + * 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.internal.protocol.protobuf.v1.operations; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.logging.log4j.Logger; + +import org.apache.geode.cache.Region; +import org.apache.geode.cache.execute.Execution; +import org.apache.geode.cache.execute.Function; +import org.apache.geode.cache.execute.FunctionException; +import org.apache.geode.cache.execute.FunctionService; +import org.apache.geode.cache.execute.ResultCollector; +import org.apache.geode.internal.exception.InvalidExecutionContextException; +import org.apache.geode.internal.logging.LogService; +import org.apache.geode.internal.protocol.operations.ProtobufOperationHandler; +import org.apache.geode.internal.protocol.protobuf.v1.BasicTypes; +import org.apache.geode.internal.protocol.protobuf.v1.ClientProtocol; +import org.apache.geode.internal.protocol.protobuf.v1.Failure; +import org.apache.geode.internal.protocol.protobuf.v1.FunctionAPI; +import org.apache.geode.internal.protocol.protobuf.v1.MessageExecutionContext; +import org.apache.geode.internal.protocol.protobuf.v1.ProtobufSerializationService; +import org.apache.geode.internal.protocol.protobuf.v1.Result; +import org.apache.geode.internal.protocol.protobuf.v1.Success; +import org.apache.geode.internal.protocol.protobuf.v1.serialization.exception.EncodingException; +import org.apache.geode.internal.protocol.protobuf.v1.state.exception.ConnectionStateException; +import org.apache.geode.internal.security.SecurityService; +import org.apache.geode.security.NotAuthorizedException; + +public class ExecuteFunctionOnRegionRequestOperationHandler implements + ProtobufOperationHandler<FunctionAPI.ExecuteFunctionOnRegionRequest, FunctionAPI.ExecuteFunctionOnRegionResponse> { + @Override + public Result<FunctionAPI.ExecuteFunctionOnRegionResponse, ClientProtocol.ErrorResponse> process( + ProtobufSerializationService serializationService, + FunctionAPI.ExecuteFunctionOnRegionRequest request, + MessageExecutionContext messageExecutionContext) + throws InvalidExecutionContextException, ConnectionStateException { + + final String functionID = request.getFunctionID(); + final String regionName = request.getRegion(); + + final Function<?> function = FunctionService.getFunction(functionID); + if (function == null) { + return Failure.of(ClientProtocol.ErrorResponse.newBuilder() + .setError(BasicTypes.Error.newBuilder().setErrorCode(BasicTypes.ErrorCode.INVALID_REQUEST) + .setMessage("Function with ID \"" + functionID + "\" not found").build()) + .build()); + } + + final Region<Object, Object> region = messageExecutionContext.getCache().getRegion(regionName); + if (region == null) { + return Failure.of(ClientProtocol.ErrorResponse.newBuilder() + .setError(BasicTypes.Error.newBuilder().setErrorCode(BasicTypes.ErrorCode.INVALID_REQUEST) + .setMessage("Region \"" + regionName + "\" not found")) + .build()); + } + + final SecurityService securityService = messageExecutionContext.getCache().getSecurityService(); + + try { + // check security for function. + function.getRequiredPermissions(regionName).forEach(securityService::authorize); + } catch (NotAuthorizedException ex) { + return Failure.of(ClientProtocol.ErrorResponse.newBuilder() + .setError(BasicTypes.Error.newBuilder() + .setMessage("Authorization failed for function \"" + functionID + "\"") + .setErrorCode(BasicTypes.ErrorCode.AUTHORIZATION_FAILED)) + .build()); + } + + try { + Execution execution = FunctionService.onRegion(region); + + final Object arguments = serializationService.decode(request.getArguments()); + + if (arguments != null) { + execution = execution.setArguments(arguments); + } + + execution = execution.withFilter(parseFilter(serializationService, request)); + + final ResultCollector<Object, List<Object>> resultCollector = execution.execute(functionID); + + if (function.hasResult()) { + List<Object> results = resultCollector.getResult(); + + final FunctionAPI.ExecuteFunctionOnRegionResponse.Builder responseMessage = + FunctionAPI.ExecuteFunctionOnRegionResponse.newBuilder(); + for (Object result : results) { + responseMessage.addResults(serializationService.encode(result)); + } + return Success.of(responseMessage.build()); + } else { + // This is fire and forget. + return Success.of(FunctionAPI.ExecuteFunctionOnRegionResponse.newBuilder().build()); + } + } catch (FunctionException ex) { + return Failure.of(ClientProtocol.ErrorResponse.newBuilder() + .setError(BasicTypes.Error.newBuilder().setErrorCode(BasicTypes.ErrorCode.SERVER_ERROR) + .setMessage("Function execution failed: " + ex.toString())) + .build()); + } catch (EncodingException ex) { + return Failure.of(ClientProtocol.ErrorResponse.newBuilder() + .setError(BasicTypes.Error.newBuilder().setErrorCode(BasicTypes.ErrorCode.SERVER_ERROR) + .setMessage("Encoding failed: " + ex.toString())) + .build()); + } + } + + private Set<Object> parseFilter(ProtobufSerializationService serializationService, + FunctionAPI.ExecuteFunctionOnRegionRequest request) throws EncodingException { + List<BasicTypes.EncodedValue> encodedFilter = request.getKeyFilterList(); + Set<Object> filter = new HashSet<>(); + + for (BasicTypes.EncodedValue filterKey : encodedFilter) { + filter.add(serializationService.decode(filterKey)); + } + return filter; + } +} diff --git a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/registry/ProtobufOperationContextRegistry.java b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/registry/ProtobufOperationContextRegistry.java index 03c6f70..9068486 100644 --- a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/registry/ProtobufOperationContextRegistry.java +++ b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/registry/ProtobufOperationContextRegistry.java @@ -22,6 +22,7 @@ import org.apache.geode.annotations.Experimental; import org.apache.geode.internal.protocol.protobuf.v1.ClientProtocol; import org.apache.geode.internal.protocol.protobuf.v1.ClientProtocol.Request.RequestAPICase; import org.apache.geode.internal.protocol.protobuf.v1.ProtobufOperationContext; +import org.apache.geode.internal.protocol.protobuf.v1.operations.ExecuteFunctionOnRegionRequestOperationHandler; import org.apache.geode.internal.protocol.protobuf.v1.operations.GetAllRequestOperationHandler; import org.apache.geode.internal.protocol.protobuf.v1.operations.GetRegionNamesRequestOperationHandler; import org.apache.geode.internal.protocol.protobuf.v1.operations.GetRegionRequestOperationHandler; @@ -51,8 +52,7 @@ public class ProtobufOperationContextRegistry { new ProtobufOperationContext<>(ClientProtocol.Request::getAuthenticationRequest, new AuthenticationRequestOperationHandler(), opsResp -> ClientProtocol.Response.newBuilder().setAuthenticationResponse(opsResp), - new ResourcePermission(ResourcePermission.Resource.DATA, - ResourcePermission.Operation.READ))); + new ResourcePermission(ResourcePermission.NULL, ResourcePermission.NULL))); operationContexts.put(RequestAPICase.GETREQUEST, new ProtobufOperationContext<>(ClientProtocol.Request::getGetRequest, @@ -109,5 +109,14 @@ public class ProtobufOperationContextRegistry { opsResp -> ClientProtocol.Response.newBuilder().setGetServerResponse(opsResp), new ResourcePermission(ResourcePermission.Resource.CLUSTER, ResourcePermission.Operation.READ))); + + operationContexts.put(RequestAPICase.EXECUTEFUNCTIONONREGIONREQUEST, + new ProtobufOperationContext<>(ClientProtocol.Request::getExecuteFunctionOnRegionRequest, + new ExecuteFunctionOnRegionRequestOperationHandler(), + opsResp -> ClientProtocol.Response.newBuilder() + .setExecuteFunctionOnRegionResponse(opsResp), + // Resource permissions get handled per-function, since they have varying permission + // requirements. + new ResourcePermission(ResourcePermission.NULL, ResourcePermission.NULL))); } } diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/TestExecutionContext.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/TestExecutionContext.java index c5a373a..1a4c3f5 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/TestExecutionContext.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/TestExecutionContext.java @@ -14,8 +14,8 @@ */ package org.apache.geode.internal.protocol; -import org.apache.geode.cache.Cache; import org.apache.geode.distributed.internal.InternalLocator; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.protocol.protobuf.statistics.NoOpStatistics; import org.apache.geode.internal.protocol.protobuf.v1.LocatorMessageExecutionContext; import org.apache.geode.internal.protocol.protobuf.v1.MessageExecutionContext; @@ -23,7 +23,7 @@ import org.apache.geode.internal.protocol.protobuf.v1.ServerMessageExecutionCont import org.apache.geode.internal.protocol.protobuf.v1.state.NoSecurityProtobufConnectionStateProcessor; public class TestExecutionContext { - public static MessageExecutionContext getNoAuthCacheExecutionContext(Cache cache) { + public static MessageExecutionContext getNoAuthCacheExecutionContext(InternalCache cache) { return new ServerMessageExecutionContext(cache, new NoOpStatistics(), new NoSecurityProtobufConnectionStateProcessor()); } diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/FunctionExecutionIntegrationTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/FunctionExecutionIntegrationTest.java new file mode 100644 index 0000000..0fc5e68 --- /dev/null +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/FunctionExecutionIntegrationTest.java @@ -0,0 +1,360 @@ +/* + * 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.internal.protocol.protobuf.v1; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.Socket; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import org.awaitility.Awaitility; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheFactory; +import org.apache.geode.cache.DataPolicy; +import org.apache.geode.cache.Region; +import org.apache.geode.cache.RegionFactory; +import org.apache.geode.cache.execute.Function; +import org.apache.geode.cache.execute.FunctionContext; +import org.apache.geode.cache.execute.FunctionException; +import org.apache.geode.cache.execute.FunctionService; +import org.apache.geode.cache.execute.RegionFunctionContext; +import org.apache.geode.cache.server.CacheServer; +import org.apache.geode.distributed.ConfigurationProperties; +import org.apache.geode.internal.AvailablePortHelper; +import org.apache.geode.management.internal.security.ResourceConstants; +import org.apache.geode.security.ResourcePermission; +import org.apache.geode.security.SecurityManager; +import org.apache.geode.test.junit.categories.IntegrationTest; + +@Category(IntegrationTest.class) +public class FunctionExecutionIntegrationTest { + private static final String TEST_REGION = "testRegion"; + private static final String TEST_FUNCTION_ID = "testFunction"; + public static final String SECURITY_PRINCIPAL = "principle"; + private ProtobufSerializationService serializationService; + private Socket socket; + private Cache cache; + private SecurityManager securityManager; + + @Before + public void setUp() throws Exception { + CacheFactory cacheFactory = new CacheFactory(new Properties()); + cacheFactory.set(ConfigurationProperties.MCAST_PORT, "0"); + cacheFactory.set(ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION, "false"); + cacheFactory.set(ConfigurationProperties.USE_CLUSTER_CONFIGURATION, "false"); + + securityManager = mock(SecurityManager.class); + cacheFactory.setSecurityManager(securityManager); + when(securityManager.authenticate(any())).thenReturn(SECURITY_PRINCIPAL); + when(securityManager.authorize(eq(SECURITY_PRINCIPAL), any())).thenReturn(true); + + cache = cacheFactory.create(); + + CacheServer cacheServer = cache.addCacheServer(); + int cacheServerPort = AvailablePortHelper.getRandomAvailableTCPPort(); + cacheServer.setPort(cacheServerPort); + cacheServer.start(); + + RegionFactory<Object, Object> regionFactory = cache.createRegionFactory(); + regionFactory.setDataPolicy(DataPolicy.PARTITION); + Region<Object, Object> testRegion = regionFactory.create(TEST_REGION); + + + System.setProperty("geode.feature-protobuf-protocol", "true"); + + socket = new Socket("localhost", cacheServerPort); + + Awaitility.await().atMost(5, TimeUnit.SECONDS).until(socket::isConnected); + + MessageUtil.performAndVerifyHandshake(socket); + + serializationService = new ProtobufSerializationService(); + } + + private static class TestFunction<T> implements Function<T> { + private final java.util.function.Function<FunctionContext<T>, Object> executeFunction; + // non-null iff function has been executed. + private final AtomicReference<FunctionContext> context = new AtomicReference<>(); + private final boolean hasResult; + + TestFunction() { + this.executeFunction = arg -> null; + this.hasResult = true; + } + + TestFunction(java.util.function.Function<FunctionContext<T>, Object> executeFunction, + boolean hasResult) { + this.executeFunction = executeFunction; + this.hasResult = hasResult; + } + + @Override + public String getId() { + return TEST_FUNCTION_ID; + } + + @Override + public void execute(FunctionContext<T> context) { + this.context.set(context); + context.getResultSender().lastResult(executeFunction.apply(context)); + } + + @Override + public boolean hasResult() { + return hasResult; + } + + @Override + public boolean isHA() { + // set for testing; we shouldn't need to test with isHA true because that's function service + // details. + return false; + } + + FunctionContext getContext() { + return context.get(); + } + } + + @After + public void tearDown() { + cache.close(); + try { + socket.close(); + } catch (IOException ignore) { + } + FunctionService.unregisterFunction(TEST_FUNCTION_ID); + } + + @Test + public void handlesNoResultFunction() throws IOException { + TestFunction<Object> testFunction = new TestFunction<>(context -> null, false); + FunctionService.registerFunction(testFunction); + final ClientProtocol.Message responseMessage = authenticateAndSendMessage(); + + assertNotNull(responseMessage); + assertEquals(ClientProtocol.Message.MessageTypeCase.RESPONSE, + responseMessage.getMessageTypeCase()); + final ClientProtocol.Response response = responseMessage.getResponse(); + assertEquals(ClientProtocol.Response.ResponseAPICase.EXECUTEFUNCTIONONREGIONRESPONSE, + response.getResponseAPICase()); + final FunctionAPI.ExecuteFunctionOnRegionResponse executeFunctionOnRegionResponse = + response.getExecuteFunctionOnRegionResponse(); + + assertEquals(0, executeFunctionOnRegionResponse.getResultsCount()); + + Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> testFunction.getContext() != null); + } + + @Test + public void handlesResultFunction() throws Exception { + final TestFunction<Object> testFunction = + new TestFunction<>(functionContext -> Integer.valueOf(22), true); + FunctionService.registerFunction(testFunction); + final ClientProtocol.Message responseMessage = authenticateAndSendMessage(); + + final FunctionAPI.ExecuteFunctionOnRegionResponse executeFunctionOnRegionResponse = + getFunctionResponse(responseMessage); + + assertEquals(1, executeFunctionOnRegionResponse.getResultsCount()); + + final Object responseValue = + serializationService.decode(executeFunctionOnRegionResponse.getResults(0)); + assertTrue(responseValue instanceof Integer); + assertEquals(22, responseValue); + } + + @Test + public void handlesException() throws IOException { + final TestFunction<Object> testFunction = new TestFunction<>(context -> { + throw new FunctionException(); + }, true); + FunctionService.registerFunction(testFunction); + + final ClientProtocol.Message message = authenticateAndSendMessage(); + + assertEquals(ClientProtocol.Message.MessageTypeCase.RESPONSE, message.getMessageTypeCase()); + assertEquals(ClientProtocol.Response.ResponseAPICase.ERRORRESPONSE, + message.getResponse().getResponseAPICase()); + final BasicTypes.Error error = message.getResponse().getErrorResponse().getError(); + assertEquals(BasicTypes.ErrorCode.SERVER_ERROR, error.getErrorCode()); + } + + @Test + public void handlesObjectThatCannotBeDecoded() throws IOException { + final TestFunction<Object> testFunction = new TestFunction<>(context -> { + return new Object(); + }, true); + FunctionService.registerFunction(testFunction); + + final ClientProtocol.Message message = authenticateAndSendMessage(); + + + assertEquals(ClientProtocol.Message.MessageTypeCase.RESPONSE, message.getMessageTypeCase()); + assertEquals(ClientProtocol.Response.ResponseAPICase.ERRORRESPONSE, + message.getResponse().getResponseAPICase()); + final BasicTypes.Error error = message.getResponse().getErrorResponse().getError(); + + assertEquals(BasicTypes.ErrorCode.SERVER_ERROR, error.getErrorCode()); + + } + + @Test + public void handlesNullReturnValues() throws Exception { + final TestFunction<Object> testFunction = new TestFunction<>(functionContext -> null, true); + FunctionService.registerFunction(testFunction); + final ClientProtocol.Message responseMessage = authenticateAndSendMessage(); + + final FunctionAPI.ExecuteFunctionOnRegionResponse executeFunctionOnRegionResponse = + getFunctionResponse(responseMessage); + + assertEquals(1, executeFunctionOnRegionResponse.getResultsCount()); + + final Object responseValue = + serializationService.decode(executeFunctionOnRegionResponse.getResults(0)); + assertNull(responseValue); + } + + @Test + public void argumentsArePassedToFunction() throws Exception { + final TestFunction<Object> testFunction = + new TestFunction<>(functionContext -> functionContext.getArguments(), true); + FunctionService.registerFunction(testFunction); + ClientProtocol.Message.Builder message = createRequestMessageBuilder( + FunctionAPI.ExecuteFunctionOnRegionRequest.newBuilder().setFunctionID(TEST_FUNCTION_ID) + .setRegion(TEST_REGION).setArguments(serializationService.encode("hello"))); + + authenticateWithServer(); + final ClientProtocol.Message responseMessage = writeMessage(message.build()); + + FunctionAPI.ExecuteFunctionOnRegionResponse response = getFunctionResponse(responseMessage); + + assertEquals("hello", serializationService.decode(response.getResults(0))); + } + + @Test + public void filterIsPassedToFunction() throws Exception { + final TestFunction<Object> testFunction = new TestFunction<>(context -> "result", true); + FunctionService.registerFunction(testFunction); + Set<Object> expectedFilter = new HashSet<>(Arrays.asList("key1", "key2")); + + final ClientProtocol.Message.Builder message = createRequestMessageBuilder( + FunctionAPI.ExecuteFunctionOnRegionRequest.newBuilder().setFunctionID(TEST_FUNCTION_ID) + .setRegion(TEST_REGION).addKeyFilter(serializationService.encode("key1")) + .addKeyFilter(serializationService.encode("key2"))); + + authenticateWithServer(); + final ClientProtocol.Message responseMessage = writeMessage(message.build()); + + FunctionAPI.ExecuteFunctionOnRegionResponse response = getFunctionResponse(responseMessage); + assertEquals("result", serializationService.decode(response.getResults(0))); + + final RegionFunctionContext context = (RegionFunctionContext) testFunction.getContext(); + + final Set<?> filter = context.getFilter(); + + assertEquals(expectedFilter, filter); + + } + + @Test + public void permissionsAreRequiredToExecute() throws IOException { + final ResourcePermission requiredPermission = new ResourcePermission( + ResourcePermission.Resource.DATA, ResourcePermission.Operation.MANAGE); + + final TestFunction<Object> testFunction = new TestFunction<Object>() { + @Override + public Collection<ResourcePermission> getRequiredPermissions(String regionName) { + return Arrays.asList(requiredPermission); + } + }; + FunctionService.registerFunction(testFunction); + + when(securityManager.authenticate(any())).thenReturn(SECURITY_PRINCIPAL); + + when(securityManager.authorize(eq(SECURITY_PRINCIPAL), eq(requiredPermission))) + .thenReturn(false); + + final ClientProtocol.Message message = authenticateAndSendMessage(); + assertEquals("message=" + message, BasicTypes.ErrorCode.AUTHORIZATION_FAILED, + message.getResponse().getErrorResponse().getError().getErrorCode()); + + verify(securityManager).authorize(eq(SECURITY_PRINCIPAL), eq(requiredPermission)); + } + + private FunctionAPI.ExecuteFunctionOnRegionResponse getFunctionResponse( + ClientProtocol.Message responseMessage) { + assertEquals(responseMessage.getResponse().toString(), + ClientProtocol.Response.ResponseAPICase.EXECUTEFUNCTIONONREGIONRESPONSE, + responseMessage.getResponse().getResponseAPICase()); + return responseMessage.getResponse().getExecuteFunctionOnRegionResponse(); + } + + private void authenticateWithServer() throws IOException { + ClientProtocol.Message.Builder request = ClientProtocol.Message.newBuilder() + .setRequest(ClientProtocol.Request.newBuilder() + .setAuthenticationRequest(ConnectionAPI.AuthenticationRequest.newBuilder() + .putCredentials(ResourceConstants.USER_NAME, "someuser") + .putCredentials(ResourceConstants.PASSWORD, "somepassword"))); + + ClientProtocol.Message response = writeMessage(request.build()); + assertEquals(response.toString(), true, + response.getResponse().getAuthenticationResponse().getAuthenticated()); + } + + private ClientProtocol.Message authenticateAndSendMessage() throws IOException { + authenticateWithServer(); + + final ClientProtocol.Message request = + createRequestMessageBuilder(FunctionAPI.ExecuteFunctionOnRegionRequest.newBuilder() + .setFunctionID(TEST_FUNCTION_ID).setRegion(TEST_REGION)).build(); + + return writeMessage(request); + } + + + private ClientProtocol.Message.Builder createRequestMessageBuilder( + FunctionAPI.ExecuteFunctionOnRegionRequest.Builder functionRequest) { + return ClientProtocol.Message.newBuilder().setRequest( + ClientProtocol.Request.newBuilder().setExecuteFunctionOnRegionRequest(functionRequest)); + } + + private ClientProtocol.Message writeMessage(ClientProtocol.Message request) throws IOException { + request.writeDelimitedTo(socket.getOutputStream()); + + return ClientProtocol.Message.parseDelimitedFrom(socket.getInputStream()); + } + +} diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/ExecuteFunctionOnRegionRequestOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/ExecuteFunctionOnRegionRequestOperationHandlerJUnitTest.java new file mode 100644 index 0000000..1384c3b --- /dev/null +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/ExecuteFunctionOnRegionRequestOperationHandlerJUnitTest.java @@ -0,0 +1,161 @@ +/* + * 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.internal.protocol.protobuf.v1.operations; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.concurrent.atomic.AtomicReference; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import org.apache.geode.cache.Region; +import org.apache.geode.cache.execute.Function; +import org.apache.geode.cache.execute.FunctionContext; +import org.apache.geode.cache.execute.FunctionService; +import org.apache.geode.internal.cache.InternalCache; +import org.apache.geode.internal.cache.LocalRegion; +import org.apache.geode.internal.protocol.protobuf.statistics.ProtobufClientStatistics; +import org.apache.geode.internal.protocol.protobuf.v1.BasicTypes; +import org.apache.geode.internal.protocol.protobuf.v1.ClientProtocol; +import org.apache.geode.internal.protocol.protobuf.v1.Failure; +import org.apache.geode.internal.protocol.protobuf.v1.FunctionAPI; +import org.apache.geode.internal.protocol.protobuf.v1.ProtobufSerializationService; +import org.apache.geode.internal.protocol.protobuf.v1.Result; +import org.apache.geode.internal.protocol.protobuf.v1.ServerMessageExecutionContext; +import org.apache.geode.internal.security.SecurityService; +import org.apache.geode.management.internal.security.ResourcePermissions; +import org.apache.geode.security.NotAuthorizedException; +import org.apache.geode.test.junit.categories.UnitTest; + +/** + * Unfortunately, we can't test the happy path with a unit test, because the function service is + * static, and there's mocking function execution is too complicated. + */ +@Category(UnitTest.class) +public class ExecuteFunctionOnRegionRequestOperationHandlerJUnitTest { + private static final String TEST_REGION = "testRegion"; + private static final String TEST_FUNCTION_ID = "testFunction"; + public static final String NOT_A_REGION = "notARegion"; + private Region regionStub; + private InternalCache cacheStub; + private ExecuteFunctionOnRegionRequestOperationHandler operationHandler; + private ProtobufSerializationService serializationService; + private TestFunction function; + + private static class TestFunction implements Function { + // non-null iff function has been executed. + private AtomicReference<FunctionContext> context = new AtomicReference<>(); + + @Override + public String getId() { + return TEST_FUNCTION_ID; + } + + @Override + public void execute(FunctionContext context) { + this.context.set(context); + context.getResultSender().lastResult("result"); + } + + FunctionContext getContext() { + return context.get(); + } + } + + @Before + public void setUp() { + regionStub = mock(LocalRegion.class); + cacheStub = mock(InternalCache.class); + serializationService = new ProtobufSerializationService(); + + when(cacheStub.getRegion(TEST_REGION)).thenReturn(regionStub); + when(cacheStub.getSecurityService()).thenReturn(mock(SecurityService.class)); + + + + operationHandler = new ExecuteFunctionOnRegionRequestOperationHandler(); + + function = new TestFunction(); + FunctionService.registerFunction(function); + } + + @After + public void tearDown() { + FunctionService.unregisterFunction(TEST_FUNCTION_ID); + } + + @Test + public void failsOnUnknownRegion() throws Exception { + final FunctionAPI.ExecuteFunctionOnRegionRequest request = + FunctionAPI.ExecuteFunctionOnRegionRequest.newBuilder().setFunctionID(TEST_FUNCTION_ID) + .setRegion(NOT_A_REGION).build(); + + final Result<FunctionAPI.ExecuteFunctionOnRegionResponse, ClientProtocol.ErrorResponse> result = + operationHandler.process(serializationService, request, mockedMessageExecutionContext()); + + assertTrue(result instanceof Failure); + + verify(cacheStub).getRegion(NOT_A_REGION); + } + + @Test + public void requiresPermissions() throws Exception { + final SecurityService securityService = mock(SecurityService.class); + doThrow(new NotAuthorizedException("we should catch this")).when(securityService) + .authorize(ResourcePermissions.DATA_WRITE); + when(cacheStub.getSecurityService()).thenReturn(securityService); + + final FunctionAPI.ExecuteFunctionOnRegionRequest request = + FunctionAPI.ExecuteFunctionOnRegionRequest.newBuilder().setFunctionID(TEST_FUNCTION_ID) + .setRegion(TEST_REGION).build(); + + final Result<FunctionAPI.ExecuteFunctionOnRegionResponse, ClientProtocol.ErrorResponse> result = + operationHandler.process(serializationService, request, mockedMessageExecutionContext()); + + assertTrue(result instanceof Failure); + + assertEquals(BasicTypes.ErrorCode.AUTHORIZATION_FAILED, + result.getErrorMessage().getError().getErrorCode()); + + } + + @Test + public void functionNotFound() throws Exception { + final FunctionAPI.ExecuteFunctionOnRegionRequest request = + FunctionAPI.ExecuteFunctionOnRegionRequest.newBuilder().setFunctionID(TEST_FUNCTION_ID) + .setRegion(TEST_REGION).build(); + + FunctionService.unregisterFunction(TEST_FUNCTION_ID); + + final Result<FunctionAPI.ExecuteFunctionOnRegionResponse, ClientProtocol.ErrorResponse> result = + operationHandler.process(serializationService, request, mockedMessageExecutionContext()); + + final ClientProtocol.ErrorResponse errorMessage = result.getErrorMessage(); + + assertEquals(BasicTypes.ErrorCode.INVALID_REQUEST, errorMessage.getError().getErrorCode()); + } + + private ServerMessageExecutionContext mockedMessageExecutionContext() { + return new ServerMessageExecutionContext(cacheStub, mock(ProtobufClientStatistics.class), null); + } +} diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetAllRequestOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetAllRequestOperationHandlerJUnitTest.java index 4f3f94b..6a4d03e 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetAllRequestOperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetAllRequestOperationHandlerJUnitTest.java @@ -57,8 +57,6 @@ public class GetAllRequestOperationHandlerJUnitTest extends OperationHandlerJUni @Before public void setUp() throws Exception { - super.setUp(); - regionStub = mock(Region.class); when(regionStub.get(TEST_KEY1)).thenReturn(TEST_VALUE1); when(regionStub.get(TEST_KEY2)).thenReturn(TEST_VALUE2); diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRegionNamesRequestOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRegionNamesRequestOperationHandlerJUnitTest.java index a26c0ea..d2fbc7f 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRegionNamesRequestOperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRegionNamesRequestOperationHandlerJUnitTest.java @@ -29,8 +29,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.apache.geode.cache.Cache; import org.apache.geode.cache.Region; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.protocol.protobuf.v1.RegionAPI; import org.apache.geode.internal.protocol.protobuf.v1.Result; import org.apache.geode.internal.protocol.protobuf.v1.Success; @@ -45,8 +45,6 @@ public class GetRegionNamesRequestOperationHandlerJUnitTest extends OperationHan @Before public void setUp() throws Exception { - super.setUp(); - Region<String, String> region1Stub = mock(Region.class); when(region1Stub.getName()).thenReturn(TEST_REGION1); Region<String, String> region2Stub = mock(Region.class); @@ -88,7 +86,7 @@ public class GetRegionNamesRequestOperationHandlerJUnitTest extends OperationHan @Test public void processReturnsNoCacheRegions() throws Exception { - Cache emptyCache = mock(Cache.class);; + InternalCache emptyCache = mock(InternalCache.class); when(emptyCache.rootRegions()) .thenReturn(Collections.unmodifiableSet(new HashSet<Region<String, String>>())); Result result = operationHandler.process(serializationService, diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRegionRequestOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRegionRequestOperationHandlerJUnitTest.java index fb3f8b3..2671224 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRegionRequestOperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRegionRequestOperationHandlerJUnitTest.java @@ -26,11 +26,11 @@ import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.apache.geode.cache.Cache; import org.apache.geode.cache.DataPolicy; import org.apache.geode.cache.Region; import org.apache.geode.cache.RegionAttributes; import org.apache.geode.cache.Scope; +import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.protocol.protobuf.v1.BasicTypes; import org.apache.geode.internal.protocol.protobuf.v1.ClientProtocol; import org.apache.geode.internal.protocol.protobuf.v1.Failure; @@ -46,8 +46,6 @@ public class GetRegionRequestOperationHandlerJUnitTest extends OperationHandlerJ @Before public void setUp() throws Exception { - super.setUp(); - region1Stub = mock(Region.class); when(region1Stub.getName()).thenReturn(TEST_REGION1); @@ -87,7 +85,7 @@ public class GetRegionRequestOperationHandlerJUnitTest extends OperationHandlerJ @Test public void processReturnsNoCacheRegions() throws Exception { - Cache emptyCache = mock(Cache.class); + InternalCache emptyCache = mock(InternalCache.class); when(emptyCache.rootRegions()) .thenReturn(Collections.unmodifiableSet(new HashSet<Region<String, String>>())); String unknownRegionName = "UNKNOWN_REGION"; diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRequestOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRequestOperationHandlerJUnitTest.java index 52da737..bd0a416 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRequestOperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetRequestOperationHandlerJUnitTest.java @@ -47,8 +47,6 @@ public class GetRequestOperationHandlerJUnitTest extends OperationHandlerJUnitTe @Before public void setUp() throws Exception { - super.setUp(); - Region regionStub = mock(Region.class); when(regionStub.get(TEST_KEY)).thenReturn(TEST_VALUE); when(regionStub.get(MISSING_KEY)).thenReturn(null); diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetServerOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetServerOperationHandlerJUnitTest.java index f2f4ce8..415c7fb 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetServerOperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/GetServerOperationHandlerJUnitTest.java @@ -54,8 +54,6 @@ public class GetServerOperationHandlerJUnitTest extends OperationHandlerJUnitTes @Before public void setUp() throws Exception { - super.setUp(); - operationHandler = new GetServerOperationHandler(); internalLocatorMock = mock(InternalLocator.class); serverLocatorAdviseeMock = mock(ServerLocator.class); diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/OperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/OperationHandlerJUnitTest.java index 54d0f2c..e0a8649 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/OperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/OperationHandlerJUnitTest.java @@ -27,12 +27,13 @@ import org.apache.geode.test.junit.categories.UnitTest; @Category(UnitTest.class) public class OperationHandlerJUnitTest { - protected Cache cacheStub; + protected InternalCache cacheStub; protected ProtobufSerializationService serializationService; protected ProtobufOperationHandler operationHandler; + // if we name this setUp, then our children override, which is all kinds of annoying. @Before - public void setUp() throws Exception { + public void setUpForChildJUnitTests() throws Exception { cacheStub = mock(InternalCache.class); serializationService = new ProtobufSerializationService(); } diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/PutAllRequestOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/PutAllRequestOperationHandlerJUnitTest.java index a9f0488..de00034 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/PutAllRequestOperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/PutAllRequestOperationHandlerJUnitTest.java @@ -57,7 +57,6 @@ public class PutAllRequestOperationHandlerJUnitTest extends OperationHandlerJUni @Before public void setUp() throws Exception { - super.setUp(); regionMock = mock(Region.class); when(regionMock.put(TEST_INVALID_KEY, TEST_INVALID_VALUE)) .thenThrow(new ClassCastException(EXCEPTION_TEXT)); diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/PutRequestOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/PutRequestOperationHandlerJUnitTest.java index 38895b8..4322bec 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/PutRequestOperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/PutRequestOperationHandlerJUnitTest.java @@ -50,8 +50,6 @@ public class PutRequestOperationHandlerJUnitTest extends OperationHandlerJUnitTe @Before public void setUp() throws Exception { - super.setUp(); - regionMock = mock(Region.class); when(regionMock.put(TEST_KEY, TEST_VALUE)).thenReturn(1); diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/RemoveRequestOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/RemoveRequestOperationHandlerJUnitTest.java index c5f109e..e67ae04 100644 --- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/RemoveRequestOperationHandlerJUnitTest.java +++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/RemoveRequestOperationHandlerJUnitTest.java @@ -49,8 +49,6 @@ public class RemoveRequestOperationHandlerJUnitTest extends OperationHandlerJUni @Before public void setUp() throws Exception { - super.setUp(); - regionStub = mock(Region.class); when(regionStub.remove(TEST_KEY)).thenReturn(TEST_VALUE); when(regionStub.containsKey(TEST_KEY)).thenReturn(true); -- To stop receiving notification emails like this one, please contact gosulli...@apache.org.