Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

ISPN-2140 Fault tolerant ping enabled to detect if cache name defined #1213

Closed
wants to merge 1 commit into from

1 participant

This page is out of date. Refresh to see the latest.
View
21 client/hotrod-client/src/main/java/org/infinispan/client/hotrod/RemoteCacheManager.java
@@ -515,15 +515,13 @@ private void loadFromStream(InputStream stream) {
RemoteCacheImpl<K, V> result = new RemoteCacheImpl<K, V>(this, cacheName);
RemoteCacheHolder rcc = new RemoteCacheHolder(result, forceReturnValueOverride == null ? forceReturnValueDefault : forceReturnValueOverride);
startRemoteCache(rcc);
- if (config.getPingOnStartup()) {
- // If ping not successful assume that the cache does not exist
- // Default cache is always started, so don't do for it
- if (!cacheName.equals(BasicCacheContainer.DEFAULT_CACHE_NAME) &&
- ping(result) == PingResult.CACHE_DOES_NOT_EXIST) {
- return null;
- }
+ // If ping not successful assume that the cache does not exist
+ // Default cache is always started, so don't do for it
+ if (!cacheName.equals(BasicCacheContainer.DEFAULT_CACHE_NAME) &&
+ ping(result) == PingResult.CACHE_DOES_NOT_EXIST) {
+ return null;
}
- // If ping on startup is disabled, or cache is defined in server
+ // If cache is not defined in server
cacheName2RemoteCache.put(cacheName, rcc);
return result;
} else {
@@ -537,12 +535,7 @@ private void loadFromStream(InputStream stream) {
return PingResult.FAIL;
}
- Transport transport = transportFactory.getTransport();
- try {
- return cache.ping(transport);
- } finally {
- transportFactory.releaseTransport(transport);
- }
+ return cache.ping();
}
private void startRemoteCache(RemoteCacheHolder remoteCacheHolder) {
View
5 client/hotrod-client/src/main/java/org/infinispan/client/hotrod/impl/RemoteCacheImpl.java
@@ -56,7 +56,6 @@
import org.infinispan.client.hotrod.impl.operations.ReplaceIfUnmodifiedOperation;
import org.infinispan.client.hotrod.impl.operations.ReplaceOperation;
import org.infinispan.client.hotrod.impl.operations.StatsOperation;
-import org.infinispan.client.hotrod.impl.transport.Transport;
import org.infinispan.client.hotrod.logging.Log;
import org.infinispan.client.hotrod.logging.LogFactory;
import org.infinispan.marshall.Marshaller;
@@ -429,8 +428,8 @@ public V call() throws Exception {
return result;
}
- public PingOperation.PingResult ping(Transport transport) {
- return operationsFactory.newPingOperation(transport).execute();
+ public PingOperation.PingResult ping() {
+ return operationsFactory.newFaultTolerantPingOperation().execute();
}
private byte[] obj2bytes(Object o, boolean isKey) {
View
52 ...rc/main/java/org/infinispan/client/hotrod/impl/operations/FaultTolerantPingOperation.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Red Hat, Inc. and/or its affiliates.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+package org.infinispan.client.hotrod.impl.operations;
+
+import org.infinispan.client.hotrod.Flag;
+import org.infinispan.client.hotrod.impl.protocol.Codec;
+import org.infinispan.client.hotrod.impl.transport.Transport;
+import org.infinispan.client.hotrod.impl.transport.TransportFactory;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A fault tolerant ping operation that can survive to node failures.
+ *
+ * @author Galder Zamarreño
+ * @since 5.2
+ */
+public class FaultTolerantPingOperation extends RetryOnFailureOperation<PingOperation.PingResult> {
+
+ protected FaultTolerantPingOperation(Codec codec, TransportFactory transportFactory,
+ byte[] cacheName, AtomicInteger topologyId, Flag[] flags) {
+ super(codec, transportFactory, cacheName, topologyId, flags);
+ }
+
+ @Override
+ protected Transport getTransport(int retryCount) {
+ return transportFactory.getTransport();
+ }
+
+ @Override
+ protected PingOperation.PingResult executeOperation(Transport transport) {
+ return new PingOperation(codec, topologyId, transport, cacheName).execute();
+ }
+
+}
View
2  ...od-client/src/main/java/org/infinispan/client/hotrod/impl/operations/HotRodOperation.java
@@ -49,7 +49,7 @@
protected final AtomicInteger topologyId;
- private final Codec codec;
+ protected final Codec codec;
private static final byte NO_TX = 0;
private static final byte XA_TX = 1;
View
18 ...-client/src/main/java/org/infinispan/client/hotrod/impl/operations/OperationsFactory.java
@@ -134,10 +134,28 @@ public BulkGetOperation newBulkGetOperation(int size) {
codec, transportFactory, cacheNameBytes, topologyId, flags(), size);
}
+ /**
+ * Construct a ping request directed to a particular node.
+ *
+ * @param transport represents the node to which the operation is directed
+ * @return a ping operation for a particular node
+ */
public PingOperation newPingOperation(Transport transport) {
return new PingOperation(codec, topologyId, transport, cacheNameBytes);
}
+ /**
+ * Construct a fault tolerant ping request. This operation should be capable
+ * to deal with nodes being down, so it will find the first node successful
+ * node to respond to the ping.
+ *
+ * @return a ping operation for the cluster
+ */
+ public FaultTolerantPingOperation newFaultTolerantPingOperation() {
+ return new FaultTolerantPingOperation(
+ codec, transportFactory, cacheNameBytes, topologyId, flags());
+ }
+
private Flag[] flags() {
Flag[] flags = this.flagsMap.get();
this.flagsMap.remove();
View
102 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/PingOnStartupTest.java
@@ -24,6 +24,7 @@
import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory;
import org.infinispan.client.hotrod.test.MultiHotRodServersTest;
+import org.infinispan.client.hotrod.test.RemoteCacheManagerCallable;
import org.infinispan.config.Configuration;
import org.infinispan.config.Configuration.CacheMode;
import org.infinispan.server.hotrod.HotRodServer;
@@ -32,6 +33,7 @@
import java.util.Properties;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.withRemoteCacheManager;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
@@ -55,55 +57,91 @@ public void testTopologyFetched() throws Exception {
"localhost:" + hotRodServer2.getPort() + ";localhost:" + hotRodServer2.getPort());
props.put("infinispan.client.hotrod.ping_on_startup", "true");
props.put("timeBetweenEvictionRunsMillis", "500");
- RemoteCacheManager remoteCacheManager = new RemoteCacheManager(props);
- TcpTransportFactory tcpConnectionFactory = (TcpTransportFactory)
- TestingUtil.extractField(remoteCacheManager, "transportFactory");
- for (int i = 0; i < 10; i++) {
- try {
- if (tcpConnectionFactory.getServers().size() == 1) {
- Thread.sleep(1000);
- } else {
- break;
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() throws Exception {
+ TcpTransportFactory tcpConnectionFactory = (TcpTransportFactory)
+ TestingUtil.extractField(rcm, "transportFactory");
+ for (int i = 0; i < 10; i++) {
+ if (tcpConnectionFactory.getServers().size() == 1) {
+ Thread.sleep(1000);
+ } else {
+ break;
+ }
}
- } finally {
- remoteCacheManager.stop();
+ assertEquals(2, tcpConnectionFactory.getServers().size());
}
- }
- assertEquals(2, tcpConnectionFactory.getServers().size());
+ });
}
- public void testTopologyNotFetched() {
+ public void testTopologyNotFetched() throws Exception {
Properties props = new Properties();
HotRodServer hotRodServer2 = server(1);
props.put("infinispan.client.hotrod.server_list",
- "localhost:" + hotRodServer2.getPort() + ";localhost:" + hotRodServer2.getPort());
+ "localhost:" + hotRodServer2.getPort());
props.put("infinispan.client.hotrod.ping_on_startup", "false");
- RemoteCacheManager remoteCacheManager = new RemoteCacheManager(props);
- TcpTransportFactory tcpConnectionFactory = (TcpTransportFactory)
- TestingUtil.extractField(remoteCacheManager, "transportFactory");
- try {
- assertEquals(1, tcpConnectionFactory.getServers().size());
- } finally {
- remoteCacheManager.stop();
- }
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() throws Exception {
+ TcpTransportFactory tcpConnectionFactory = (TcpTransportFactory)
+ TestingUtil.extractField(rcm, "transportFactory");
+ assertEquals(1, tcpConnectionFactory.getServers().size());
+ }
+ });
}
- public void testGetCacheWithPingOnStartupDisabled() {
+ public void testGetCacheWithPingOnStartupDisabled() throws Exception {
Properties props = new Properties();
HotRodServer hotRodServer2 = server(1);
props.put("infinispan.client.hotrod.server_list",
- "boomoo:12345;localhost:" + hotRodServer2.getPort() + ";localhost:" + hotRodServer2.getPort());
+ "boomoo:12345;localhost:" + hotRodServer2.getPort());
props.put("infinispan.client.hotrod.ping_on_startup", "false");
- RemoteCacheManager remoteCacheManager = new RemoteCacheManager(props);
- try {
- RemoteCache<Object, Object> cache = remoteCacheManager.getCache();
- assertFalse(cache.containsKey("k"));
- } finally {
- remoteCacheManager.stop();
- }
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() throws Exception {
+ RemoteCache<Object, Object> cache = rcm.getCache();
+ assertFalse(cache.containsKey("k"));
+ }
+ });
+ }
+
+ public void testGetCacheWorksIfNodeDown() throws Exception {
+ Properties props = new Properties();
+ HotRodServer hotRodServer2 = server(1);
+ props.put("infinispan.client.hotrod.server_list",
+ "boomoo:12345;localhost:" + hotRodServer2.getPort());
+ props.put("infinispan.client.hotrod.ping_on_startup", "true");
+ props.put("timeBetweenEvictionRunsMillis", "500");
+
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() throws Exception {
+ rcm.getCache();
+ }
+ });
+ }
+
+ public void testGetCacheWorksIfNodeNotDown() throws Exception {
+ Properties props = new Properties();
+ HotRodServer hotRodServer2 = server(1);
+ props.put("infinispan.client.hotrod.server_list",
+ "localhost:" + hotRodServer2.getPort());
+ props.put("infinispan.client.hotrod.ping_on_startup", "true");
+ props.put("timeBetweenEvictionRunsMillis", "500");
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() throws Exception {
+ rcm.getCache();
+ }
+ });
}
}
View
18 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteCacheManagerTest.java
@@ -23,11 +23,14 @@
package org.infinispan.client.hotrod;
import org.infinispan.client.hotrod.impl.ConfigurationProperties;
+import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.server.hotrod.HotRodServer;
import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.net.URL;
@@ -40,23 +43,26 @@
@Test(testName = "client.hotrod.RemoteCacheManagerTest", groups = "functional" )
public class RemoteCacheManagerTest extends SingleCacheManagerTest {
- EmbeddedCacheManager cacheManager = null;
- HotRodServer hotrodServer = null;
+ HotRodServer hotrodServer;
int port;
@Override
protected EmbeddedCacheManager createCacheManager() throws Exception {
- cacheManager = TestCacheManagerFactory.createLocalCacheManager(false);
+ return TestCacheManagerFactory.createLocalCacheManager(false);
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ super.setup();
hotrodServer = TestHelper.startHotRodServer(cacheManager);
port = hotrodServer.getPort();
- return cacheManager;
}
@AfterTest(alwaysRun = true)
public void release() {
try {
- if (cacheManager != null) cacheManager.stop();
- if (hotrodServer != null) hotrodServer.stop();
+ TestingUtil.killCacheManagers(cacheManager);
+ HotRodClientTestingUtil.killServers(hotrodServer);
} catch (Exception e) {
e.printStackTrace();
}
View
27 ...otrod-client/src/test/java/org/infinispan/client/hotrod/test/HotRodClientTestingUtil.java
@@ -34,6 +34,11 @@
private static final Log log = LogFactory.getLog(HotRodClientTestingUtil.class, Log.class);
+ /**
+ * Kills a remote cache manager.
+ *
+ * @param rcm the remote cache manager instance to kill
+ */
public static void killRemoteCacheManager(RemoteCacheManager rcm) {
try {
if (rcm != null) rcm.stop();
@@ -42,6 +47,11 @@ public static void killRemoteCacheManager(RemoteCacheManager rcm) {
}
}
+ /**
+ * Kills a group of Hot Rod servers.
+ *
+ * @param servers the group of Hot Rod servers to kill
+ */
public static void killServers(HotRodServer... servers) {
if (servers != null) {
for (HotRodServer server : servers) {
@@ -54,4 +64,21 @@ public static void killServers(HotRodServer... servers) {
}
}
+ /**
+ * Invoke a task using a remote cache manager. This method guarantees that
+ * the remote manager used in the task will be cleaned up after the task has
+ * completed, regardless of the task outcome.
+ *
+ * @param c task to execute
+ * @throws Exception if the task fails somehow
+ */
+ public static void withRemoteCacheManager(RemoteCacheManagerCallable c)
+ throws Exception {
+ try {
+ c.call();
+ } finally {
+ killRemoteCacheManager(c.rcm);
+ }
+ }
+
}
View
42 ...od-client/src/test/java/org/infinispan/client/hotrod/test/RemoteCacheManagerCallable.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2012 Red Hat, Inc. and/or its affiliates.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+package org.infinispan.client.hotrod.test;
+
+import org.infinispan.client.hotrod.RemoteCacheManager;
+
+/**
+ * A task that executes operations against a given remote cache manager.
+ *
+ * @author Galder Zamarreño
+ * @since 5.2
+ */
+public class RemoteCacheManagerCallable {
+
+ protected final RemoteCacheManager rcm;
+
+ public RemoteCacheManagerCallable(RemoteCacheManager rcm) {
+ this.rcm = rcm;
+ }
+
+ public void call() throws Exception {
+ // No-op
+ }
+
+}
Something went wrong with that request. Please try again.