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
wireba...@apache.org.

Reply via email to