GEODE-3105: adding GetRegions handler for protobuf protocol

Added a handler which will catch incoming getRegion requests and will call into 
the cache's rootRegion and return the names of the region it finds.
Added unit test verifying hanlder behavior.
Added integration test verifying module correctness for getRegion.

This closes #607

Signed-off-by: Brian Rowe <br...@pivotal.io>
Signed-off-by: Hitesh Khamesra <hitesh...@yahoo.com>


Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/b0fafd3d
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/b0fafd3d
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/b0fafd3d

Branch: refs/heads/feature/GEODE-3109
Commit: b0fafd3da240257afd75ed09e10f61984b3c59b2
Parents: 6107561
Author: Brian Rowe <br...@pivotal.io>
Authored: Tue Jun 27 16:15:53 2017 -0700
Committer: Hitesh Khamesra <hkhame...@pivotal.io>
Committed: Wed Jun 28 13:39:51 2017 -0700

----------------------------------------------------------------------
 .../GenericProtocolServerConnection.java        |   1 +
 .../protocol/protobuf/ProtobufOpsProcessor.java |   4 +
 .../protobuf/ProtobufStreamProcessor.java       |   4 +
 .../GetRegionsRequestOperationHandler.java      |  48 ++++++++
 geode-protobuf/src/main/proto/region_API.proto  |   3 +-
 .../org/apache/geode/protocol/MessageUtil.java  |  11 ++
 .../RoundTripCacheConnectionJUnitTest.java      |  27 +++++
 ...tRegionRequestOperationHandlerJUnitTest.java | 109 +++++++++++++++++++
 8 files changed, 206 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/b0fafd3d/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
 
b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
index 8edd83c..a2e7305 100644
--- 
a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
+++ 
b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/GenericProtocolServerConnection.java
@@ -67,6 +67,7 @@ public class GenericProtocolServerConnection extends 
ServerConnection {
       // TODO serialization types?
       messageHandler.receiveMessage(inputStream, outputStream, 
this.getCache());
     } catch (IOException e) {
+      logger.warn(e);
       // TODO?
     }
     return;

http://git-wip-us.apache.org/repos/asf/geode/blob/b0fafd3d/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufOpsProcessor.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufOpsProcessor.java
 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufOpsProcessor.java
index 29d3317..4318fb4 100644
--- 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufOpsProcessor.java
+++ 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufOpsProcessor.java
@@ -56,6 +56,8 @@ public class ProtobufOpsProcessor {
         return request.getGetRequest();
       case PUTALLREQUEST:
         return request.getPutAllRequest();
+      case GETREGIONSREQUEST:
+        return request.getGetRegionsRequest();
       default:
         throw new InvalidProtocolMessageException(
             "Unknown request type: " + 
request.getRequestAPICase().getNumber());
@@ -73,6 +75,8 @@ public class ProtobufOpsProcessor {
         return builder.setGetResponse((RegionAPI.GetResponse) 
response).build();
       case PUTALLREQUEST:
         return builder.setPutAllResponse((RegionAPI.PutAllResponse) 
response).build();
+      case GETREGIONSREQUEST:
+        return builder.setGetRegionsResponse((RegionAPI.GetRegionsResponse) 
response).build();
       default:
         throw new InvalidProtocolMessageException(
             "Unknown request type: " + requestType.getNumber());

http://git-wip-us.apache.org/repos/asf/geode/blob/b0fafd3d/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufStreamProcessor.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufStreamProcessor.java
 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufStreamProcessor.java
index 21dbef5..4e76de4 100644
--- 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufStreamProcessor.java
+++ 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/ProtobufStreamProcessor.java
@@ -18,6 +18,7 @@ import org.apache.geode.cache.Cache;
 import org.apache.geode.internal.cache.InternalCache;
 import 
org.apache.geode.internal.cache.tier.sockets.ClientProtocolMessageHandler;
 import org.apache.geode.protocol.exception.InvalidProtocolMessageException;
+import 
org.apache.geode.protocol.protobuf.operations.GetRegionsRequestOperationHandler;
 import 
org.apache.geode.protocol.protobuf.operations.GetRequestOperationHandler;
 import 
org.apache.geode.protocol.protobuf.operations.PutRequestOperationHandler;
 import 
org.apache.geode.protocol.protobuf.serializer.ProtobufProtocolSerializer;
@@ -58,6 +59,9 @@ public class ProtobufStreamProcessor implements 
ClientProtocolMessageHandler {
     registry.registerOperationHandlerForOperationId(
         ClientProtocol.Request.RequestAPICase.PUTREQUEST.getNumber(),
         new PutRequestOperationHandler());
+    registry.registerOperationHandlerForOperationId(
+        ClientProtocol.Request.RequestAPICase.GETREGIONSREQUEST.getNumber(),
+        new GetRegionsRequestOperationHandler());
   }
 
   public void processOneMessage(InputStream inputStream, OutputStream 
outputStream, Cache cache)

http://git-wip-us.apache.org/repos/asf/geode/blob/b0fafd3d/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/operations/GetRegionsRequestOperationHandler.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/operations/GetRegionsRequestOperationHandler.java
 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/operations/GetRegionsRequestOperationHandler.java
new file mode 100644
index 0000000..dc1d8ac
--- /dev/null
+++ 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/operations/GetRegionsRequestOperationHandler.java
@@ -0,0 +1,48 @@
+/*
+ * 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.protocol.protobuf.operations;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Region;
+import org.apache.geode.protocol.operations.OperationHandler;
+import org.apache.geode.protocol.protobuf.BasicTypes;
+import org.apache.geode.protocol.protobuf.EncodingTypeTranslator;
+import org.apache.geode.protocol.protobuf.ProtobufUtilities;
+import org.apache.geode.protocol.protobuf.RegionAPI;
+import org.apache.geode.serialization.SerializationService;
+import 
org.apache.geode.serialization.exception.UnsupportedEncodingTypeException;
+import 
org.apache.geode.serialization.registry.exception.CodecNotRegisteredForTypeException;
+
+import sun.reflect.generics.tree.BaseType;
+
+import java.util.Set;
+
+public class GetRegionsRequestOperationHandler
+    implements OperationHandler<RegionAPI.GetRegionsRequest, 
RegionAPI.GetRegionsResponse> {
+
+  @Override
+  public RegionAPI.GetRegionsResponse process(SerializationService 
serializationService,
+      RegionAPI.GetRegionsRequest request, Cache cache) {
+    Set<Region<?, ?>> regions = cache.rootRegions();
+
+    RegionAPI.GetRegionsResponse.Builder builder = 
RegionAPI.GetRegionsResponse.newBuilder();
+
+    for (Region region : regions) {
+      
builder.addRegions(BasicTypes.Region.newBuilder().setName(region.getName()));
+    }
+    builder.setSuccess(true);
+    return builder.build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/b0fafd3d/geode-protobuf/src/main/proto/region_API.proto
----------------------------------------------------------------------
diff --git a/geode-protobuf/src/main/proto/region_API.proto 
b/geode-protobuf/src/main/proto/region_API.proto
index adeb011..d3af17a 100644
--- a/geode-protobuf/src/main/proto/region_API.proto
+++ b/geode-protobuf/src/main/proto/region_API.proto
@@ -104,5 +104,6 @@ message GetRegionsRequest {
 }
 
 message GetRegionsResponse {
-    repeated Region regions = 1;
+    bool success = 1;
+    repeated Region regions = 2;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geode/blob/b0fafd3d/geode-protobuf/src/test/java/org/apache/geode/protocol/MessageUtil.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/test/java/org/apache/geode/protocol/MessageUtil.java 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/MessageUtil.java
index 73d0803..dc89724 100644
--- a/geode-protobuf/src/test/java/org/apache/geode/protocol/MessageUtil.java
+++ b/geode-protobuf/src/test/java/org/apache/geode/protocol/MessageUtil.java
@@ -103,4 +103,15 @@ public class MessageUtil {
   private static ClientProtocol.MessageHeader.Builder 
getMessageHeaderBuilder() {
     return ClientProtocol.MessageHeader.newBuilder();
   }
+
+  public static RegionAPI.GetRegionsRequest makeGetRegionsRequest() {
+    return RegionAPI.GetRegionsRequest.newBuilder().build();
+  }
+
+  public static ClientProtocol.Message makeGetRegionsRequestMessage(
+      ClientProtocol.MessageHeader header) {
+    ClientProtocol.Request request =
+        
ClientProtocol.Request.newBuilder().setGetRegionsRequest(makeGetRegionsRequest()).build();
+    return 
ClientProtocol.Message.newBuilder().setMessageHeader(header).setRequest(request).build();
+  }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/b0fafd3d/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java
 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java
index 1fbe821..77b984f 100644
--- 
a/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java
+++ 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/RoundTripCacheConnectionJUnitTest.java
@@ -107,6 +107,33 @@ public class RoundTripCacheConnectionJUnitTest {
     validateGetResponse(socket, protobufProtocolSerializer);
   }
 
+  @Test
+  public void testNewProtocolGetRegionCallSucceeds() throws Exception {
+    System.setProperty("geode.feature-protobuf-protocol", "true");
+
+    Socket socket = new Socket("localhost", cacheServerPort);
+    Awaitility.await().atMost(5, TimeUnit.SECONDS).until(socket::isConnected);
+    OutputStream outputStream = socket.getOutputStream();
+    outputStream.write(110);
+
+
+    ProtobufProtocolSerializer protobufProtocolSerializer = new 
ProtobufProtocolSerializer();
+    ClientProtocol.Message getRegionsMessage =
+        
MessageUtil.makeGetRegionsRequestMessage(ClientProtocol.MessageHeader.newBuilder().build());
+    protobufProtocolSerializer.serialize(getRegionsMessage, outputStream);
+
+    ClientProtocol.Message message =
+        protobufProtocolSerializer.deserialize(socket.getInputStream());
+    assertEquals(ClientProtocol.Message.MessageTypeCase.RESPONSE, 
message.getMessageTypeCase());
+    ClientProtocol.Response response = message.getResponse();
+    assertEquals(ClientProtocol.Response.ResponseAPICase.GETREGIONSRESPONSE,
+        response.getResponseAPICase());
+    RegionAPI.GetRegionsResponse getRegionsResponse = 
response.getGetRegionsResponse();
+    assertEquals(true, getRegionsResponse.getSuccess());
+    assertEquals(1, getRegionsResponse.getRegionsCount());
+    assertEquals(TEST_REGION, getRegionsResponse.getRegions(0).getName());
+  }
+
   private void validatePutResponse(Socket socket,
       ProtobufProtocolSerializer protobufProtocolSerializer) throws Exception {
     ClientProtocol.Message message =

http://git-wip-us.apache.org/repos/asf/geode/blob/b0fafd3d/geode-protobuf/src/test/java/org/apache/geode/protocol/protobuf/operations/GetRegionRequestOperationHandlerJUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/test/java/org/apache/geode/protocol/protobuf/operations/GetRegionRequestOperationHandlerJUnitTest.java
 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/protobuf/operations/GetRegionRequestOperationHandlerJUnitTest.java
new file mode 100644
index 0000000..e8f1e65
--- /dev/null
+++ 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/protobuf/operations/GetRegionRequestOperationHandlerJUnitTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.protocol.protobuf.operations;
+
+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 org.apache.geode.LogWriter;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Region;
+import org.apache.geode.protocol.MessageUtil;
+import org.apache.geode.protocol.protobuf.BasicTypes;
+import org.apache.geode.protocol.protobuf.RegionAPI;
+import org.apache.geode.serialization.SerializationService;
+import 
org.apache.geode.serialization.exception.UnsupportedEncodingTypeException;
+import 
org.apache.geode.serialization.registry.exception.CodecAlreadyRegisteredForTypeException;
+import 
org.apache.geode.serialization.registry.exception.CodecNotRegisteredForTypeException;
+import org.apache.geode.test.dunit.Assert;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+@Category(UnitTest.class)
+public class GetRegionRequestOperationHandlerJUnitTest {
+  public static final String TEST_REGION1 = "test region 1";
+  public static final String TEST_REGION2 = "test region 2";
+  public static final String TEST_REGION3 = "test region 3";
+  public Cache cacheStub;
+  public SerializationService serializationServiceStub;
+  private GetRegionsRequestOperationHandler operationHandler;
+
+  @Before
+  public void setUp() throws Exception {
+    serializationServiceStub = mock(SerializationService.class);
+    when(serializationServiceStub.encode(BasicTypes.EncodingType.STRING, 
TEST_REGION1))
+        .thenReturn(TEST_REGION1.getBytes(Charset.forName("UTF-8")));
+    when(serializationServiceStub.encode(BasicTypes.EncodingType.STRING, 
TEST_REGION2))
+        .thenReturn(TEST_REGION2.getBytes(Charset.forName("UTF-8")));
+    when(serializationServiceStub.encode(BasicTypes.EncodingType.STRING, 
TEST_REGION3))
+        .thenReturn(TEST_REGION3.getBytes(Charset.forName("UTF-8")));
+
+    Region<String, String> region1Stub = mock(Region.class);
+    when(region1Stub.getName()).thenReturn(TEST_REGION1);
+    Region<String, String> region2Stub = mock(Region.class);
+    when(region2Stub.getName()).thenReturn(TEST_REGION2);
+    Region<String, String> region3Stub = mock(Region.class);
+    when(region3Stub.getName()).thenReturn(TEST_REGION3);
+
+    cacheStub = mock(Cache.class);
+    when(cacheStub.rootRegions()).thenReturn(Collections.unmodifiableSet(
+        new HashSet<Region<String, String>>(Arrays.asList(region1Stub, 
region2Stub, region3Stub))));
+    operationHandler = new GetRegionsRequestOperationHandler();
+  }
+
+  @Test
+  public void processReturnsCacheRegions() throws 
CodecAlreadyRegisteredForTypeException,
+      UnsupportedEncodingTypeException, CodecNotRegisteredForTypeException {
+    RegionAPI.GetRegionsResponse response = 
operationHandler.process(serializationServiceStub,
+        MessageUtil.makeGetRegionsRequest(), cacheStub);
+
+    Assert.assertEquals(true, response.getSuccess());
+    Assert.assertEquals(3, response.getRegionsCount());
+
+    // There's no guarantee for what order we receive the regions in from the 
response
+    String name1 = response.getRegions(0).getName();
+    String name2 = response.getRegions(1).getName();
+    String name3 = response.getRegions(2).getName();
+    Assert.assertTrue("The same region was returned multiple times",
+        name1 != name2 && name1 != name3 && name2 != name3);
+    Assert.assertTrue(name1 == TEST_REGION1 || name1 == TEST_REGION2 || name1 
== TEST_REGION3);
+    Assert.assertTrue(name2 == TEST_REGION1 || name2 == TEST_REGION2 || name2 
== TEST_REGION3);
+    Assert.assertTrue(name3 == TEST_REGION1 || name3 == TEST_REGION2 || name3 
== TEST_REGION3);
+  }
+
+  @Test
+  public void processReturnsNoCacheRegions() throws 
CodecAlreadyRegisteredForTypeException,
+      UnsupportedEncodingTypeException, CodecNotRegisteredForTypeException {
+    Cache emptyCache = mock(Cache.class);;
+    when(emptyCache.rootRegions())
+        .thenReturn(Collections.unmodifiableSet(new HashSet<Region<String, 
String>>()));
+    RegionAPI.GetRegionsResponse response = 
operationHandler.process(serializationServiceStub,
+        MessageUtil.makeGetRegionsRequest(), emptyCache);
+
+    Assert.assertEquals(true, response.getSuccess());
+    Assert.assertEquals(0, response.getRegionsCount());
+  }
+}

Reply via email to