Repository: geode
Updated Branches:
  refs/heads/develop 636e970d9 -> bf2e0f6e0


GEODE-3284: New flow: getAvailableServers. This now closed #673

Signed-off-by: Bruce Schuchardt <[email protected]>


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

Branch: refs/heads/develop
Commit: bf2e0f6e03d1c50580a45efdd3588d1a19bdb5d9
Parents: 636e970
Author: Udo Kohlmeyer <[email protected]>
Authored: Mon Jul 31 09:23:53 2017 -0700
Committer: Udo Kohlmeyer <[email protected]>
Committed: Wed Aug 2 09:48:43 2017 -0700

----------------------------------------------------------------------
 .../GetAvailableServersOperationHandler.java    |  98 ++++++++++++++
 .../registry/OperationContextRegistry.java      |   6 +
 .../utilities/ProtobufRequestUtilities.java     |  11 +-
 .../protobuf/utilities/ProtobufUtilities.java   |  24 ++--
 geode-protobuf/src/main/proto/basicTypes.proto  |   3 +-
 .../src/main/proto/clientProtocol.proto         |  10 +-
 geode-protobuf/src/main/proto/region_API.proto  |   8 --
 geode-protobuf/src/main/proto/server_API.proto  |   4 +-
 .../protocol/GetAvailableServersDUnitTest.java  | 108 +++++++++++++++
 ...ailableServersOperationHandlerJUnitTest.java | 131 +++++++++++++++++++
 10 files changed, 374 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/operations/GetAvailableServersOperationHandler.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/operations/GetAvailableServersOperationHandler.java
 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/operations/GetAvailableServersOperationHandler.java
new file mode 100644
index 0000000..cf3f828
--- /dev/null
+++ 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/operations/GetAvailableServersOperationHandler.java
@@ -0,0 +1,98 @@
+/*
+ * 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.commons.lang.StringUtils;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.client.internal.locator.GetAllServersRequest;
+import org.apache.geode.cache.client.internal.locator.GetAllServersResponse;
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.distributed.internal.ServerLocation;
+import org.apache.geode.distributed.internal.tcpserver.TcpClient;
+import org.apache.geode.internal.admin.remote.DistributionLocatorId;
+import org.apache.geode.protocol.operations.OperationHandler;
+import org.apache.geode.protocol.protobuf.BasicTypes;
+import org.apache.geode.protocol.protobuf.Failure;
+import org.apache.geode.protocol.protobuf.Result;
+import org.apache.geode.protocol.protobuf.ServerAPI;
+import org.apache.geode.protocol.protobuf.Success;
+import org.apache.geode.serialization.SerializationService;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.stream.Collectors;
+
+public class GetAvailableServersOperationHandler implements
+    OperationHandler<ServerAPI.GetAvailableServersRequest, 
ServerAPI.GetAvailableServersResponse> {
+
+  @Override
+  public Result<ServerAPI.GetAvailableServersResponse> process(
+      SerializationService serializationService, 
ServerAPI.GetAvailableServersRequest request,
+      Cache cache) {
+
+    InternalDistributedSystem distributedSystem =
+        (InternalDistributedSystem) cache.getDistributedSystem();
+    Properties properties = distributedSystem.getProperties();
+    String locatorsString = 
properties.getProperty(ConfigurationProperties.LOCATORS);
+
+    HashSet<DistributionLocatorId> locators = new HashSet();
+    StringTokenizer stringTokenizer = new StringTokenizer(locatorsString, ",");
+    while (stringTokenizer.hasMoreTokens()) {
+      String locator = stringTokenizer.nextToken();
+      if (StringUtils.isNotEmpty(locator)) {
+        locators.add(new DistributionLocatorId(locator));
+      }
+    }
+
+    TcpClient tcpClient = getTcpClient();
+    for (DistributionLocatorId locator : locators) {
+      try {
+        return getGetAvailableServersFromLocator(tcpClient, locator.getHost());
+      } catch (IOException | ClassNotFoundException e) {
+        // try the next locator
+      }
+    }
+    return Failure
+        .of(BasicTypes.ErrorResponse.newBuilder().setMessage("Unable to find a 
locator").build());
+  }
+
+  private Result<ServerAPI.GetAvailableServersResponse> 
getGetAvailableServersFromLocator(
+      TcpClient tcpClient, InetSocketAddress address) throws IOException, 
ClassNotFoundException {
+    GetAllServersResponse getAllServersResponse = (GetAllServersResponse) 
tcpClient
+        .requestToServer(address, new GetAllServersRequest(), 1000, true);
+    Collection<BasicTypes.Server> servers =
+        (Collection<BasicTypes.Server>) 
getAllServersResponse.getServers().stream()
+            .map(serverLocation -> getServerProtobufMessage((ServerLocation) 
serverLocation))
+            .collect(Collectors.toList());
+    ServerAPI.GetAvailableServersResponse.Builder builder =
+        
ServerAPI.GetAvailableServersResponse.newBuilder().addAllServers(servers);
+    return Success.of(builder.build());
+  }
+
+  protected TcpClient getTcpClient() {
+    return new TcpClient();
+  }
+
+  private BasicTypes.Server getServerProtobufMessage(ServerLocation 
serverLocation) {
+    BasicTypes.Server.Builder serverBuilder = BasicTypes.Server.newBuilder();
+    
serverBuilder.setHostname(serverLocation.getHostName()).setPort(serverLocation.getPort());
+    return serverBuilder.build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/registry/OperationContextRegistry.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/registry/OperationContextRegistry.java
 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/registry/OperationContextRegistry.java
index 37bb322..b160adc 100644
--- 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/registry/OperationContextRegistry.java
+++ 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/registry/OperationContextRegistry.java
@@ -22,6 +22,7 @@ import org.apache.geode.protocol.protobuf.ClientProtocol;
 import 
org.apache.geode.protocol.protobuf.ClientProtocol.Request.RequestAPICase;
 import org.apache.geode.protocol.protobuf.OperationContext;
 import 
org.apache.geode.protocol.protobuf.operations.GetAllRequestOperationHandler;
+import 
org.apache.geode.protocol.protobuf.operations.GetAvailableServersOperationHandler;
 import 
org.apache.geode.protocol.protobuf.operations.GetRegionNamesRequestOperationHandler;
 import 
org.apache.geode.protocol.protobuf.operations.GetRegionRequestOperationHandler;
 import 
org.apache.geode.protocol.protobuf.operations.GetRequestOperationHandler;
@@ -75,5 +76,10 @@ public class OperationContextRegistry {
         new OperationContext<>(ClientProtocol.Request::getGetRegionRequest,
             new GetRegionRequestOperationHandler(),
             opsResp -> 
ClientProtocol.Response.newBuilder().setGetRegionResponse(opsResp)));
+
+    operationContexts.put(RequestAPICase.GETAVAILABLESERVERSREQUEST, new 
OperationContext<>(
+        ClientProtocol.Request::getGetAvailableServersRequest,
+        new GetAvailableServersOperationHandler(),
+        opsResp -> 
ClientProtocol.Response.newBuilder().setGetAvailableServersResponse(opsResp)));
   }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufRequestUtilities.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufRequestUtilities.java
 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufRequestUtilities.java
index 01be750..e184592 100644
--- 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufRequestUtilities.java
+++ 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufRequestUtilities.java
@@ -14,11 +14,12 @@
  */
 package org.apache.geode.protocol.protobuf.utilities;
 
-import java.util.Set;
-
 import org.apache.geode.protocol.protobuf.BasicTypes;
 import org.apache.geode.protocol.protobuf.ClientProtocol;
 import org.apache.geode.protocol.protobuf.RegionAPI;
+import org.apache.geode.protocol.protobuf.ServerAPI;
+
+import java.util.Set;
 
 /**
  * This class contains helper functions for generating ClientProtocol.Request 
objects
@@ -106,4 +107,10 @@ public abstract class ProtobufRequestUtilities {
     putAllRequestBuilder.addAllEntry(entries);
     return 
ClientProtocol.Request.newBuilder().setPutAllRequest(putAllRequestBuilder).build();
   }
+
+  public static ServerAPI.GetAvailableServersRequest 
createGetAvailableServersRequest() {
+    ServerAPI.GetAvailableServersRequest.Builder builder =
+        ServerAPI.GetAvailableServersRequest.newBuilder();
+    return builder.build();
+  }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufUtilities.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufUtilities.java
 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufUtilities.java
index c7bf6aa..27c141d 100644
--- 
a/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufUtilities.java
+++ 
b/geode-protobuf/src/main/java/org/apache/geode/protocol/protobuf/utilities/ProtobufUtilities.java
@@ -15,6 +15,7 @@
 package org.apache.geode.protocol.protobuf.utilities;
 
 import com.google.protobuf.ByteString;
+
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionAttributes;
 import org.apache.geode.protocol.protobuf.BasicTypes;
@@ -38,7 +39,7 @@ import 
org.apache.geode.serialization.registry.exception.CodecNotRegisteredForTy
 public abstract class ProtobufUtilities {
   /**
    * Creates a object containing the type and value encoding of a piece of data
-   *
+   * 
    * @param serializationService - object which knows how to encode objects 
for the protobuf
    *        protocol {@link ProtobufSerializationService}
    * @param unencodedValue - the value object which is to be encoded
@@ -60,7 +61,7 @@ public abstract class ProtobufUtilities {
 
   /**
    * Creates a protobuf key,value pair from an encoded key and value
-   *
+   * 
    * @param key - an EncodedValue containing the key of the entry
    * @param value - an EncodedValue containing the value of the entry
    * @return a protobuf Entry object containing the passed key and value
@@ -72,7 +73,7 @@ public abstract class ProtobufUtilities {
 
   /**
    * Creates a protobuf key,value pair from unencoded data
-   *
+   * 
    * @param serializationService - object which knows how to encode objects 
for the protobuf
    *        protocol {@link ProtobufSerializationService}
    * @param unencodedKey - the unencoded key for the entry
@@ -92,7 +93,7 @@ public abstract class ProtobufUtilities {
 
   /**
    * This creates a protobuf message containing a ClientProtocol.Response
-   *
+   * 
    * @param messageHeader - The header for the message
    * @param response - The response for the message
    * @return a protobuf Message containing the above parameters
@@ -105,7 +106,7 @@ public abstract class ProtobufUtilities {
 
   /**
    * This creates a protobuf message containing a ClientProtocol.Request
-   *
+   * 
    * @param messageHeader - The header for the message
    * @param request - The request for the message
    * @return a protobuf Message containing the above parameters
@@ -118,7 +119,7 @@ public abstract class ProtobufUtilities {
 
   /**
    * This creates a protobuf message containing a ClientProtocol.Request
-   *
+   * 
    * @param getAllRequest - The request for the message
    * @return a protobuf Message containing the above parameters
    */
@@ -129,7 +130,7 @@ public abstract class ProtobufUtilities {
 
   /**
    * This builds the MessageHeader for a response which matches an incoming 
request
-   *
+   * 
    * @param request - The request message that we're responding to.
    * @return the MessageHeader the response to the passed request
    */
@@ -140,7 +141,7 @@ public abstract class ProtobufUtilities {
 
   /**
    * This creates a MessageHeader
-   *
+   * 
    * @param correlationId - An identifier used to correlate requests and 
responses
    * @return a MessageHeader containing the above parameters
    */
@@ -150,7 +151,7 @@ public abstract class ProtobufUtilities {
 
   /**
    * This will return the object encoded in a protobuf EncodedValue
-   *
+   * 
    * @param serializationService - object which knows how to encode objects 
for the protobuf
    *        protocol {@link ProtobufSerializationService}
    * @param encodedValue - The value to be decoded
@@ -169,7 +170,6 @@ public abstract class ProtobufUtilities {
   }
 
   /**
-   * @param region
    * @return a Protobuf BasicTypes.Region message that represents the {@link 
Region}
    */
   public static BasicTypes.Region createRegionMessageFromRegion(Region region) 
{
@@ -197,4 +197,8 @@ public abstract class ProtobufUtilities {
     return 
ClientProtocol.Request.newBuilder().setGetRegionNamesRequest(getRegionNamesRequest)
         .build();
   }
+
+  public static ClientProtocol.Request.Builder createProtobufRequestBuilder() {
+    return ClientProtocol.Request.newBuilder();
+  }
 }

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/main/proto/basicTypes.proto
----------------------------------------------------------------------
diff --git a/geode-protobuf/src/main/proto/basicTypes.proto 
b/geode-protobuf/src/main/proto/basicTypes.proto
index ad254cd..a9d07d8 100644
--- a/geode-protobuf/src/main/proto/basicTypes.proto
+++ b/geode-protobuf/src/main/proto/basicTypes.proto
@@ -61,7 +61,8 @@ message Region {
 }
 
 message Server {
-    string url = 1;
+    string hostname = 1;
+    int32 port = 2;
 }
 
 message ErrorResponse {

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/main/proto/clientProtocol.proto
----------------------------------------------------------------------
diff --git a/geode-protobuf/src/main/proto/clientProtocol.proto 
b/geode-protobuf/src/main/proto/clientProtocol.proto
index 6b037ca..c64d4de 100644
--- a/geode-protobuf/src/main/proto/clientProtocol.proto
+++ b/geode-protobuf/src/main/proto/clientProtocol.proto
@@ -43,13 +43,12 @@ message Request {
         GetAllRequest getAllRequest = 5;
         RemoveRequest removeRequest = 6;
         RemoveAllRequest removeAllRequest = 7;
-        ListKeysRequest listKeysRequest = 8;
 
         CreateRegionRequest createRegionRequest = 21;
         DestroyRegionRequest destroyRegionRequest = 22;
 
-        PingRequest pingRequest = 41;
-        GetServersRequest getServersRequest = 42;
+//        PingRequest pingRequest = 41;
+        GetAvailableServersRequest getAvailableServersRequest = 42;
         GetRegionNamesRequest getRegionNamesRequest = 43;
         GetRegionRequest getRegionRequest = 44;
 
@@ -64,15 +63,14 @@ message Response {
         GetAllResponse getAllResponse = 5;
         RemoveResponse removeResponse = 6;
         RemoveAllResponse removeAllResponse = 7;
-        ListKeysResponse listKeysResponse = 8;
 
         ErrorResponse errorResponse = 13;
 
         CreateRegionResponse createRegionResponse = 20;
         DestroyRegionResponse destroyRegionResponse = 21;
 
-        PingResponse pingResponse = 41;
-        GetServersResponse getServersResponse = 42;
+//        PingResponse pingResponse = 41;
+        GetAvailableServersResponse getAvailableServersResponse = 42;
         GetRegionNamesResponse getRegionNamesResponse = 43;
         GetRegionResponse getRegionResponse = 44;
     }

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/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 bf2c15e..2a93a7d 100644
--- a/geode-protobuf/src/main/proto/region_API.proto
+++ b/geode-protobuf/src/main/proto/region_API.proto
@@ -55,14 +55,6 @@ message GetAllResponse {
     repeated Entry entries = 1;
 }
 
-message ListKeysRequest {
-    string regionName = 1;
-}
-
-message ListKeysResponse {
-    repeated EncodedValue key = 1;
-}
-
 message RemoveRequest {
     string regionName = 1;
     EncodedValue key = 2;

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/main/proto/server_API.proto
----------------------------------------------------------------------
diff --git a/geode-protobuf/src/main/proto/server_API.proto 
b/geode-protobuf/src/main/proto/server_API.proto
index 8c4e345..81622cc 100644
--- a/geode-protobuf/src/main/proto/server_API.proto
+++ b/geode-protobuf/src/main/proto/server_API.proto
@@ -27,10 +27,10 @@ message PingResponse {
     int32 sequenceNumber = 1;
 }
 
-message GetServersRequest {
+message GetAvailableServersRequest {
 
 }
 
-message GetServersResponse {
+message GetAvailableServersResponse {
     repeated Server servers = 1;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/test/java/org/apache/geode/protocol/GetAvailableServersDUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/test/java/org/apache/geode/protocol/GetAvailableServersDUnitTest.java
 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/GetAvailableServersDUnitTest.java
new file mode 100644
index 0000000..4d6390b
--- /dev/null
+++ 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/GetAvailableServersDUnitTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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;
+
+import org.apache.geode.cache.server.CacheServer;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.protocol.exception.InvalidProtocolMessageException;
+import org.apache.geode.protocol.protobuf.ClientProtocol;
+import org.apache.geode.protocol.protobuf.ServerAPI;
+import 
org.apache.geode.protocol.protobuf.serializer.ProtobufProtocolSerializer;
+import org.apache.geode.protocol.protobuf.utilities.ProtobufRequestUtilities;
+import org.apache.geode.protocol.protobuf.utilities.ProtobufUtilities;
+import org.apache.geode.test.dunit.DistributedTestUtils;
+import org.apache.geode.test.dunit.Host;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
+import org.apache.geode.test.dunit.rules.DistributedRestoreSystemProperties;
+import org.apache.geode.test.junit.categories.DistributedTest;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.IOException;
+import java.net.Socket;
+
+import static org.junit.Assert.assertEquals;
+
+@Category(DistributedTest.class)
+public class GetAvailableServersDUnitTest extends JUnit4CacheTestCase {
+
+  @Rule
+  public DistributedRestoreSystemProperties distributedRestoreSystemProperties 
=
+      new DistributedRestoreSystemProperties();
+
+  @Before
+  public void setup() {
+
+  }
+
+  @Test
+  public void testGetAllAvailableServersRequest()
+      throws IOException, InvalidProtocolMessageException {
+    Host host = Host.getHost(0);
+    VM vm0 = host.getVM(0);
+    VM vm1 = host.getVM(1);
+    VM vm2 = host.getVM(2);
+
+    int locatorPort = DistributedTestUtils.getDUnitLocatorPort();
+
+    // int cacheServer1Port = vm0.invoke("Start Cache1", () -> 
startCacheWithCacheServer());
+    int cacheServer1Port = startCacheWithCacheServer();
+    int cacheServer2Port = vm1.invoke("Start Cache2", () -> 
startCacheWithCacheServer());
+    int cacheServer3Port = vm2.invoke("Start Cache3", () -> 
startCacheWithCacheServer());
+
+    vm0.invoke(() -> {
+      Socket socket = new Socket(host.getHostName(), cacheServer1Port);
+      socket.getOutputStream().write(110);
+
+      ClientProtocol.Request.Builder protobufRequestBuilder =
+          ProtobufUtilities.createProtobufRequestBuilder();
+      ClientProtocol.Message getAvailableServersRequestMessage =
+          
ProtobufUtilities.createProtobufMessage(ProtobufUtilities.createMessageHeader(1233445),
+              protobufRequestBuilder.setGetAvailableServersRequest(
+                  
ProtobufRequestUtilities.createGetAvailableServersRequest()).build());
+
+      ProtobufProtocolSerializer protobufProtocolSerializer = new 
ProtobufProtocolSerializer();
+      protobufProtocolSerializer.serialize(getAvailableServersRequestMessage,
+          socket.getOutputStream());
+
+      ClientProtocol.Message getAvailableServersResponseMessage =
+          protobufProtocolSerializer.deserialize(socket.getInputStream());
+      assertEquals(1233445,
+          
getAvailableServersResponseMessage.getMessageHeader().getCorrelationId());
+      assertEquals(ClientProtocol.Message.MessageTypeCase.RESPONSE,
+          getAvailableServersResponseMessage.getMessageTypeCase());
+      ClientProtocol.Response messageResponse = 
getAvailableServersResponseMessage.getResponse();
+      
assertEquals(ClientProtocol.Response.ResponseAPICase.GETAVAILABLESERVERSRESPONSE,
+          messageResponse.getResponseAPICase());
+      ServerAPI.GetAvailableServersResponse getAvailableServersResponse =
+          messageResponse.getGetAvailableServersResponse();
+      assertEquals(3, getAvailableServersResponse.getServersCount());
+    });
+  }
+
+  private Integer startCacheWithCacheServer() throws IOException {
+    System.setProperty("geode.feature-protobuf-protocol", "true");
+
+    InternalCache cache = getCache();
+    CacheServer cacheServer = cache.addCacheServer();
+    cacheServer.setPort(0);
+    cacheServer.start();
+    return cacheServer.getPort();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/bf2e0f6e/geode-protobuf/src/test/java/org/apache/geode/protocol/protobuf/operations/GetAvailableServersOperationHandlerJUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-protobuf/src/test/java/org/apache/geode/protocol/protobuf/operations/GetAvailableServersOperationHandlerJUnitTest.java
 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/protobuf/operations/GetAvailableServersOperationHandlerJUnitTest.java
new file mode 100644
index 0000000..77b088d
--- /dev/null
+++ 
b/geode-protobuf/src/test/java/org/apache/geode/protocol/protobuf/operations/GetAvailableServersOperationHandlerJUnitTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.client.internal.locator.GetAllServersResponse;
+import org.apache.geode.distributed.ConfigurationProperties;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.distributed.internal.ServerLocation;
+import org.apache.geode.distributed.internal.tcpserver.TcpClient;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.protocol.protobuf.BasicTypes;
+import org.apache.geode.protocol.protobuf.Failure;
+import org.apache.geode.protocol.protobuf.Result;
+import org.apache.geode.protocol.protobuf.ServerAPI;
+import 
org.apache.geode.protocol.protobuf.ServerAPI.GetAvailableServersResponse;
+import org.apache.geode.protocol.protobuf.Success;
+import org.apache.geode.protocol.protobuf.utilities.ProtobufRequestUtilities;
+import org.apache.geode.test.junit.categories.UnitTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@Category(UnitTest.class)
+public class GetAvailableServersOperationHandlerJUnitTest extends 
OperationHandlerJUnitTest {
+
+  private TcpClient mockTCPClient;
+
+  @Before
+  public void setUp() throws Exception {
+    super.setUp();
+
+    operationHandler = mock(GetAvailableServersOperationHandler.class);
+    cacheStub = mock(GemFireCacheImpl.class);
+    when(operationHandler.process(any(), any(), any())).thenCallRealMethod();
+    InternalDistributedSystem mockDistributedSystem = 
mock(InternalDistributedSystem.class);
+    when(cacheStub.getDistributedSystem()).thenReturn(mockDistributedSystem);
+    Properties mockProperties = mock(Properties.class);
+    when(mockDistributedSystem.getProperties()).thenReturn(mockProperties);
+    String locatorString = "testLocator1Host[12345],testLocator2Host[23456]";
+    
when(mockProperties.getProperty(ConfigurationProperties.LOCATORS)).thenReturn(locatorString);
+    mockTCPClient = mock(TcpClient.class);
+    when(((GetAvailableServersOperationHandler) 
operationHandler).getTcpClient())
+        .thenReturn(mockTCPClient);
+  }
+
+  @Test
+  public void testServerReturnedFromHandler() throws Exception {
+    when(mockTCPClient.requestToServer(any(), any(), anyInt(), anyBoolean()))
+        .thenReturn(new GetAllServersResponse(new ArrayList<ServerLocation>() {
+          {
+            add(new ServerLocation("hostname1", 12345));
+            add(new ServerLocation("hostname2", 23456));
+          }
+        }));
+
+    ServerAPI.GetAvailableServersRequest getAvailableServersRequest =
+        ProtobufRequestUtilities.createGetAvailableServersRequest();
+    Result operationHandlerResult =
+        operationHandler.process(serializationServiceStub, 
getAvailableServersRequest, cacheStub);
+    assertTrue(operationHandlerResult instanceof Success);
+    ValidateGetAvailableServersResponse(
+        (GetAvailableServersResponse) operationHandlerResult.getMessage());
+  }
+
+  @Test
+  public void testServerReturnedFromSecondLocatorIfFirstDown() throws 
Exception {
+    when(mockTCPClient.requestToServer(any(), any(), anyInt(), anyBoolean()))
+        .thenThrow(new IOException("BOOM!!!"))
+        .thenReturn(new GetAllServersResponse(new ArrayList<ServerLocation>() {
+          {
+            add(new ServerLocation("hostname1", 12345));
+            add(new ServerLocation("hostname2", 23456));
+          }
+        }));
+
+    ServerAPI.GetAvailableServersRequest getAvailableServersRequest =
+        ProtobufRequestUtilities.createGetAvailableServersRequest();
+    Result operationHandlerResult =
+        operationHandler.process(serializationServiceStub, 
getAvailableServersRequest, cacheStub);
+    assertTrue(operationHandlerResult instanceof Success);
+    ValidateGetAvailableServersResponse(
+        (GetAvailableServersResponse) operationHandlerResult.getMessage());
+  }
+
+  private void ValidateGetAvailableServersResponse(
+      GetAvailableServersResponse getAvailableServersResponse) {
+    assertEquals(2, getAvailableServersResponse.getServersCount());
+    BasicTypes.Server server = getAvailableServersResponse.getServers(0);
+    assertEquals("hostname1", server.getHostname());
+    assertEquals(12345, server.getPort());
+    server = getAvailableServersResponse.getServers(1);
+    assertEquals("hostname2", server.getHostname());
+    assertEquals(23456, server.getPort());
+  }
+
+  @Test
+  public void testProcessFailsIfNoLocatorsAvailable() throws Exception {
+    when(mockTCPClient.requestToServer(any(), any(), anyInt(), anyBoolean()))
+        .thenThrow(new IOException("BOOM!!!"));
+
+    ServerAPI.GetAvailableServersRequest getAvailableServersRequest =
+        ProtobufRequestUtilities.createGetAvailableServersRequest();
+    Result operationHandlerResult =
+        operationHandler.process(serializationServiceStub, 
getAvailableServersRequest, cacheStub);
+    assertTrue(operationHandlerResult instanceof Failure);
+  }
+}

Reply via email to