You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2017/08/04 23:25:33 UTC
[05/27] geode git commit: GEODE-3284: New flow: getAvailableServers.
This now closed #673
GEODE-3284: New flow: getAvailableServers. This now closed #673
Signed-off-by: Bruce Schuchardt <bs...@pivotal.io>
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/feature/GEODE-3299
Commit: bf2e0f6e03d1c50580a45efdd3588d1a19bdb5d9
Parents: 636e970
Author: Udo Kohlmeyer <uk...@pivotal.io>
Authored: Mon Jul 31 09:23:53 2017 -0700
Committer: Udo Kohlmeyer <uk...@pivotal.io>
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);
+ }
+}