You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by wi...@apache.org on 2018/03/02 18:13:37 UTC
[geode] branch develop updated: GEODE-4661: Implement KeySet
protobuf message and handler (#1538)
This is an automated email from the ASF dual-hosted git repository.
wirebaron 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 808d273 GEODE-4661: Implement KeySet protobuf message and handler (#1538)
808d273 is described below
commit 808d273294d6b7e7723c111204df6be7009cb2b8
Author: Brian Rowe <br...@pivotal.io>
AuthorDate: Fri Mar 2 10:13:33 2018 -0800
GEODE-4661: Implement KeySet protobuf message and handler (#1538)
---
.../geode/experimental/driver/ProtobufRegion.java | 16 +++++
.../apache/geode/experimental/driver/Region.java | 9 +++
.../experimental/driver/RegionIntegrationTest.java | 15 ++++
.../src/main/proto/v1/clientProtocol.proto | 3 +
.../src/main/proto/v1/region_API.proto | 8 +++
.../v1/operations/KeySetOperationHandler.java | 68 ++++++++++++++++++
.../registry/ProtobufOperationContextRegistry.java | 7 ++
.../v1/acceptance/CacheOperationsJUnitTest.java | 24 +++++++
.../KeySetOperationHandlerJUnitTest.java | 81 ++++++++++++++++++++++
9 files changed, 231 insertions(+)
diff --git a/geode-experimental-driver/src/main/java/org/apache/geode/experimental/driver/ProtobufRegion.java b/geode-experimental-driver/src/main/java/org/apache/geode/experimental/driver/ProtobufRegion.java
index 9f99f25..a8d53b3 100644
--- a/geode-experimental-driver/src/main/java/org/apache/geode/experimental/driver/ProtobufRegion.java
+++ b/geode-experimental-driver/src/main/java/org/apache/geode/experimental/driver/ProtobufRegion.java
@@ -18,7 +18,9 @@ import java.io.IOException;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.apache.geode.annotations.Experimental;
import org.apache.geode.internal.protocol.protobuf.v1.BasicTypes;
@@ -153,4 +155,18 @@ public class ProtobufRegion<K, V> implements Region<K, V> {
protobufChannel.sendRequest(request, MessageTypeCase.REMOVERESPONSE);
}
+
+ @Override
+ public Set<K> keySet() throws IOException {
+ final Message request = Message.newBuilder()
+ .setKeySetRequest(RegionAPI.KeySetRequest.newBuilder().setRegionName(name)).build();
+ final Message message = protobufChannel.sendRequest(request, MessageTypeCase.KEYSETRESPONSE);
+ final RegionAPI.KeySetResponse keySetResponse = message.getKeySetResponse();
+
+ Set<K> keys = new HashSet<>(keySetResponse.getKeysCount());
+ for (BasicTypes.EncodedValue value : keySetResponse.getKeysList()) {
+ keys.add((K) ValueEncoder.decodeValue(value));
+ }
+ return keys;
+ }
}
diff --git a/geode-experimental-driver/src/main/java/org/apache/geode/experimental/driver/Region.java b/geode-experimental-driver/src/main/java/org/apache/geode/experimental/driver/Region.java
index f92d9a2..54c7138 100644
--- a/geode-experimental-driver/src/main/java/org/apache/geode/experimental/driver/Region.java
+++ b/geode-experimental-driver/src/main/java/org/apache/geode/experimental/driver/Region.java
@@ -17,6 +17,7 @@ package org.apache.geode.experimental.driver;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
+import java.util.Set;
import org.apache.geode.annotations.Experimental;
@@ -85,4 +86,12 @@ public interface Region<K, V> {
* @throws IOException
*/
void remove(K key) throws IOException;
+
+ /**
+ * Gets all the keys for which this region has entries
+ *
+ * @return Set of keys in this region
+ * @throws IOException
+ */
+ Set<K> keySet() throws IOException;
}
diff --git a/geode-experimental-driver/src/test/java/org/apache/geode/experimental/driver/RegionIntegrationTest.java b/geode-experimental-driver/src/test/java/org/apache/geode/experimental/driver/RegionIntegrationTest.java
index 42c4bc6..1b6c085 100644
--- a/geode-experimental-driver/src/test/java/org/apache/geode/experimental/driver/RegionIntegrationTest.java
+++ b/geode-experimental-driver/src/test/java/org/apache/geode/experimental/driver/RegionIntegrationTest.java
@@ -14,17 +14,20 @@
*/
package org.apache.geode.experimental.driver;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Before;
@@ -106,6 +109,18 @@ public class RegionIntegrationTest extends IntegrationTestBase {
assertNull(region.get(document));
}
+ @Test
+ public void keySetTest() throws Exception {
+ Region<String, String> region = driver.getRegion("region");
+ Map<String, String> testMap = new HashMap<>();
+ testMap.put("Key1", "foo");
+ testMap.put("Key2", "foo");
+ testMap.put("Key3", "foo");
+ region.putAll(testMap);
+ assertArrayEquals(testMap.keySet().stream().sorted().toArray(),
+ region.keySet().stream().sorted().toArray());
+ }
+
@Test(expected = IOException.class)
public void putWithBadJSONKeyAndValue() throws IOException {
Region<JSONWrapper, JSONWrapper> region = driver.getRegion("region");
diff --git a/geode-protobuf-messages/src/main/proto/v1/clientProtocol.proto b/geode-protobuf-messages/src/main/proto/v1/clientProtocol.proto
index d049aec..184d6c4 100644
--- a/geode-protobuf-messages/src/main/proto/v1/clientProtocol.proto
+++ b/geode-protobuf-messages/src/main/proto/v1/clientProtocol.proto
@@ -69,6 +69,9 @@ message Message {
OQLQueryRequest oqlQueryRequest = 26;
OQLQueryResponse oqlQueryResponse = 27;
+
+ KeySetRequest keySetRequest = 28;
+ KeySetResponse keySetResponse = 29;
}
}
diff --git a/geode-protobuf-messages/src/main/proto/v1/region_API.proto b/geode-protobuf-messages/src/main/proto/v1/region_API.proto
index c3465db..31039bf 100644
--- a/geode-protobuf-messages/src/main/proto/v1/region_API.proto
+++ b/geode-protobuf-messages/src/main/proto/v1/region_API.proto
@@ -100,3 +100,11 @@ message OQLQueryResponse {
Table tableResult = 3;
}
}
+
+message KeySetRequest {
+ string regionName = 1;
+}
+
+message KeySetResponse {
+ repeated EncodedValue keys = 1;
+}
diff --git a/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/operations/KeySetOperationHandler.java b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/operations/KeySetOperationHandler.java
new file mode 100644
index 0000000..ecab692
--- /dev/null
+++ b/geode-protobuf/src/main/java/org/apache/geode/internal/protocol/protobuf/v1/operations/KeySetOperationHandler.java
@@ -0,0 +1,68 @@
+/*
+ * 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.Set;
+import java.util.stream.Collectors;
+
+import org.apache.logging.log4j.Logger;
+
+import org.apache.geode.annotations.Experimental;
+import org.apache.geode.cache.Region;
+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.Failure;
+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.RegionAPI;
+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.DecodingException;
+import org.apache.geode.internal.protocol.protobuf.v1.serialization.exception.EncodingException;
+import org.apache.geode.security.ResourcePermission;
+
+@Experimental
+public class KeySetOperationHandler
+ implements ProtobufOperationHandler<RegionAPI.KeySetRequest, RegionAPI.KeySetResponse> {
+ private static final Logger logger = LogService.getLogger();
+
+ @Override
+ public Result<RegionAPI.KeySetResponse> process(ProtobufSerializationService serializationService,
+ RegionAPI.KeySetRequest request, MessageExecutionContext messageExecutionContext)
+ throws InvalidExecutionContextException, EncodingException, DecodingException {
+ String regionName = request.getRegionName();
+ Region region = messageExecutionContext.getCache().getRegion(regionName);
+ if (region == null) {
+ logger.error("Received request for nonexistent region: {}", regionName);
+ return Failure.of(BasicTypes.ErrorCode.SERVER_ERROR,
+ "Region \"" + regionName + "\" not found");
+ }
+
+ Set keySet = region.keySet();
+ RegionAPI.KeySetResponse.Builder builder = RegionAPI.KeySetResponse.newBuilder();
+ keySet.stream().map(serializationService::encode)
+ .forEach(value -> builder.addKeys((BasicTypes.EncodedValue) value));
+
+ return Success.of(builder.build());
+ }
+
+ public static ResourcePermission determineRequiredPermission(RegionAPI.KeySetRequest request,
+ ProtobufSerializationService serializer) throws DecodingException {
+ return new ResourcePermission(ResourcePermission.Resource.DATA,
+ ResourcePermission.Operation.READ, request.getRegionName());
+ }
+}
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 4811bac..3bca6fe 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
@@ -32,6 +32,7 @@ import org.apache.geode.internal.protocol.protobuf.v1.operations.GetRegionNamesR
import org.apache.geode.internal.protocol.protobuf.v1.operations.GetRegionRequestOperationHandler;
import org.apache.geode.internal.protocol.protobuf.v1.operations.GetRequestOperationHandler;
import org.apache.geode.internal.protocol.protobuf.v1.operations.GetServerOperationHandler;
+import org.apache.geode.internal.protocol.protobuf.v1.operations.KeySetOperationHandler;
import org.apache.geode.internal.protocol.protobuf.v1.operations.OqlQueryRequestOperationHandler;
import org.apache.geode.internal.protocol.protobuf.v1.operations.PutAllRequestOperationHandler;
import org.apache.geode.internal.protocol.protobuf.v1.operations.PutRequestOperationHandler;
@@ -152,5 +153,11 @@ public class ProtobufOperationContextRegistry {
new OqlQueryRequestOperationHandler(),
opsResp -> ClientProtocol.Message.newBuilder().setOqlQueryResponse(opsResp),
new ResourcePermission(Resource.DATA, Operation.READ)));
+
+ operationContexts.put(MessageTypeCase.KEYSETREQUEST,
+ new ProtobufOperationContext<>(ClientProtocol.Message::getKeySetRequest,
+ new KeySetOperationHandler(),
+ opsResp -> ClientProtocol.Message.newBuilder().setKeySetResponse(opsResp),
+ KeySetOperationHandler::determineRequiredPermission));
}
}
diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheOperationsJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheOperationsJUnitTest.java
index 1d44676..848afff 100644
--- a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheOperationsJUnitTest.java
+++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheOperationsJUnitTest.java
@@ -31,9 +31,11 @@ import java.io.OutputStream;
import java.net.Socket;
import java.util.Collection;
import java.util.HashSet;
+import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.awaitility.Awaitility;
@@ -176,6 +178,13 @@ public class CacheOperationsJUnitTest {
ProtobufUtilities.createProtobufRequestWithGetAllRequest(getAllRequest);
protobufProtocolSerializer.serialize(getAllMessage, outputStream);
validateGetAllResponse(socket, protobufProtocolSerializer);
+
+ RegionAPI.KeySetRequest keySetRequest =
+ RegionAPI.KeySetRequest.newBuilder().setRegionName(TEST_REGION).build();
+ ClientProtocol.Message keySetMessage =
+ ClientProtocol.Message.newBuilder().setKeySetRequest(keySetRequest).build();
+ protobufProtocolSerializer.serialize(keySetMessage, outputStream);
+ validateKeySetResponse(socket, protobufProtocolSerializer);
}
@Test
@@ -347,6 +356,21 @@ public class CacheOperationsJUnitTest {
}
}
+ private void validateKeySetResponse(Socket socket,
+ ProtobufProtocolSerializer protobufProtocolSerializer) throws Exception {
+ ClientProtocol.Message response = deserializeResponse(socket, protobufProtocolSerializer);
+
+ assertEquals(ClientProtocol.Message.MessageTypeCase.KEYSETRESPONSE,
+ response.getMessageTypeCase());
+ RegionAPI.KeySetResponse keySetResponse = response.getKeySetResponse();
+ assertEquals(3, keySetResponse.getKeysCount());
+ List responseKeys = keySetResponse.getKeysList().stream().map(serializationService::decode)
+ .collect(Collectors.toList());
+ assertTrue(responseKeys.contains(TEST_MULTIOP_KEY1));
+ assertTrue(responseKeys.contains(TEST_MULTIOP_KEY2));
+ assertTrue(responseKeys.contains(TEST_MULTIOP_KEY3));
+ }
+
private void validateRemoveResponse(Socket socket,
ProtobufProtocolSerializer protobufProtocolSerializer) throws Exception {
ClientProtocol.Message response = deserializeResponse(socket, protobufProtocolSerializer);
diff --git a/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/KeySetOperationHandlerJUnitTest.java b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/KeySetOperationHandlerJUnitTest.java
new file mode 100644
index 0000000..56c216e
--- /dev/null
+++ b/geode-protobuf/src/test/java/org/apache/geode/internal/protocol/protobuf/v1/operations/KeySetOperationHandlerJUnitTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.internal.protocol.TestExecutionContext;
+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.ProtobufSerializationService;
+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;
+import org.apache.geode.internal.protocol.protobuf.v1.serialization.exception.DecodingException;
+import org.apache.geode.internal.protocol.protobuf.v1.serialization.exception.EncodingException;
+import org.apache.geode.internal.protocol.protobuf.v1.utilities.ProtobufRequestUtilities;
+import org.apache.geode.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class KeySetOperationHandlerJUnitTest extends OperationHandlerJUnitTest {
+ private final String TEST_KEY1 = "Key1";
+ private final String TEST_KEY2 = "Key2";
+ private final String TEST_KEY3 = "Key3";
+ private final String TEST_REGION = "test region";
+
+ @Before
+ public void setUp() throws Exception {
+ Region regionStub = mock(Region.class);
+ when(regionStub.keySet())
+ .thenReturn(new HashSet<String>(Arrays.asList(TEST_KEY1, TEST_KEY2, TEST_KEY3)));
+
+ when(cacheStub.getRegion(TEST_REGION)).thenReturn(regionStub);
+ operationHandler = new KeySetOperationHandler();
+ }
+
+ @Test
+ public void verifyKeySetReturnsExpectedKeys() throws Exception {
+ RegionAPI.KeySetRequest request =
+ RegionAPI.KeySetRequest.newBuilder().setRegionName(TEST_REGION).build();
+ Result result = operationHandler.process(serializationService, request,
+ TestExecutionContext.getNoAuthCacheExecutionContext(cacheStub));
+
+ Assert.assertTrue(result instanceof Success);
+ RegionAPI.KeySetResponse response = (RegionAPI.KeySetResponse) result.getMessage();
+
+ List<Object> results = response.getKeysList().stream().map(serializationService::decode)
+ .collect(Collectors.toList());
+ assertEquals(3, results.size());
+ assertTrue(results.contains(TEST_KEY1));
+ assertTrue(results.contains(TEST_KEY2));
+ assertTrue(results.contains(TEST_KEY3));
+ }
+}
--
To stop receiving notification emails like this one, please contact
wirebaron@apache.org.