From d97184aeb2a87d1b95893da491baaf28147a5cb0 Mon Sep 17 00:00:00 2001
From: Ben Cotton
Date: Mon, 17 Mar 2014 18:59:57 -0400
Subject: [PATCH] complete re-synch of OffHeapDataContainer.java and @Test
---
.../test/cache/remote/DefaultCacheTest.java | 88 ++
.../cdi/test/cache/remote/NamedCacheTest.java | 95 ++
.../cdi/test/cache/remote/Small.java | 25 +
.../remote/SpecificCacheManagerTest.java | 86 ++
.../client/hotrod/ApacheCommonsPoolTest.java | 103 ++
.../client/hotrod/BaseBulkGetKeysTest.java | 110 ++
.../client/hotrod/BaseBulkGetTest.java | 122 ++
.../client/hotrod/BulkGetKeysDistTest.java | 46 +
.../client/hotrod/BulkGetKeysReplTest.java | 26 +
.../client/hotrod/BulkGetKeysSimpleTest.java | 28 +
.../client/hotrod/BulkGetReplTest.java | 26 +
.../client/hotrod/BulkGetSimpleTest.java | 42 +
.../client/hotrod/CSAIntegrationTest.java | 173 +++
.../client/hotrod/CacheContainerTest.java | 58 +
.../hotrod/CacheManagerNotStartedTest.java | 123 ++
.../hotrod/CacheManagerStoppedTest.java | 125 ++
.../hotrod/ClientAsymmetricClusterTest.java | 47 +
.../hotrod/ClientConnectionPoolingTest.java | 286 ++++
.../hotrod/ClientSocketReadTimeoutTest.java | 122 ++
.../hotrod/ConsistentHashComparisonTest.java | 185 +++
.../hotrod/ConsistentHashFactoryTest.java | 37 +
.../hotrod/ConsistentHashPerformanceTest.java | 76 +
.../ConsistentHashV1IntegrationTest.java | 198 +++
.../client/hotrod/ConsistentHashV1Test.java | 152 ++
.../client/hotrod/DefaultExpirationTest.java | 72 +
.../client/hotrod/DistTopologyChangeTest.java | 15 +
.../client/hotrod/DroppedConnectionsTest.java | 80 ++
.../infinispan/client/hotrod/ExpiryTest.java | 43 +
.../client/hotrod/ForceReturnValueTest.java | 88 ++
.../client/hotrod/ForceReturnValuesTest.java | 57 +
.../HeavyLoadConnectionPoolingTest.java | 122 ++
.../hotrod/HitsAwareCacheManagersTest.java | 120 ++
.../hotrod/HotRod10CSAIntegrationTest.java | 22 +
.../hotrod/HotRodAsyncReplicationTest.java | 61 +
.../client/hotrod/HotRodIntegrationTest.java | 274 ++++
.../hotrod/HotRodServerStartStopTest.java | 57 +
.../client/hotrod/HotRodStatisticsTest.java | 140 ++
.../client/hotrod/PingOnStartupTest.java | 141 ++
.../client/hotrod/RemoteAsyncAPITest.java | 297 ++++
.../client/hotrod/RemoteCacheManagerTest.java | 140 ++
.../client/hotrod/ReplTopologyChangeTest.java | 147 ++
.../RoundRobinBalancingIntegrationTest.java | 225 +++
.../RoundRobinBalancingStrategyTest.java | 155 ++
.../client/hotrod/ServerErrorTest.java | 94 ++
.../client/hotrod/ServerRestartTest.java | 72 +
.../client/hotrod/ServerShutdownTest.java | 70 +
.../client/hotrod/SocketTimeoutErrorTest.java | 111 ++
.../hotrod/SomeAsyncExecutorFactory.java | 7 +
.../hotrod/SomeCustomConsistentHashV1.java | 7 +
.../hotrod/SomeRequestBalancingStrategy.java | 7 +
.../client/hotrod/SomeTransportfactory.java | 7 +
.../org/infinispan/client/hotrod/SslTest.java | 110 ++
.../infinispan/client/hotrod/TestHelper.java | 68 +
.../hotrod/TransportObjectFactoryTest.java | 36 +
.../client/hotrod/WorkerThread.java | 110 ++
.../configuration/ConfigurationTest.java | 119 ++
.../marshall/ApacheAvroMarshallerTest.java | 152 ++
.../hotrod/marshall/EmbeddedAccount.java | 62 +
.../marshall/EmbeddedAccountMarshaller.java | 42 +
.../hotrod/marshall/EmbeddedCompatTest.java | 194 +++
.../marshall/ProtoStreamMarshallerTest.java | 113 ++
.../query/HotRodQueryFileSystemTest.java | 52 +
.../query/HotRodQueryIspnDirectoryTest.java | 20 +
.../client/hotrod/query/HotRodQueryTest.java | 224 +++
.../hotrod/query/HotRodTunedQueryTest.java | 63 +
.../MultiHotRodServerIspnDirQueryTest.java | 63 +
...MultiHotRodServerIspnDirReplQueryTest.java | 66 +
.../query/MultiHotRodServerQueryTest.java | 163 +++
...RemoteQueryDslConditionsFilestoreTest.java | 58 +
.../RemoteQueryDslConditionsIspnDirTest.java | 58 +
.../query/RemoteQueryDslConditionsTest.java | 1269 +++++++++++++++++
.../query/RemoteQueryDslIterationTest.java | 206 +++
.../hotrod/query/RemoteQueryJmxTest.java | 196 +++
.../hotrod/retry/AbstractRetryTest.java | 109 ++
.../hotrod/retry/DistributionRetryTest.java | 159 +++
.../hotrod/retry/ReplicationRetryTest.java | 141 ++
.../hotrod/retry/RetryOnFailureUnitTest.java | 106 ++
.../hotrod/retry/ServerFailureRetryTest.java | 54 +
.../stress/ClientConsistentHashPerfTest.java | 63 +
.../hotrod/test/HotRodClientTestingUtil.java | 84 ++
.../hotrod/test/MultiHotRodServersTest.java | 91 ++
.../test/RemoteCacheManagerCallable.java | 23 +
.../infinispan/container/DataContainer.java | 10 +-
.../container/DefaultDataContainer.java | 2 +-
.../configuration/QueryableDataContainer.java | 6 +-
...oncurrentOperationsInPrimaryOwnerTest.java | 4 +-
.../org/infinispan/jcache/JCacheEntry.java | 1 -
maven-settings.xml | 107 --
maven-settings.xml.redhat | 32 -
off-heap/pom.xml.off-heap | 294 ++++
.../query/remote/QueryFacadeImpl.java | 6 +-
.../query/remote/QueryFacadeImplTest.java | 5 +-
92 files changed, 9592 insertions(+), 159 deletions(-)
create mode 100644 cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/DefaultCacheTest.java
create mode 100644 cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/NamedCacheTest.java
create mode 100644 cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/Small.java
create mode 100644 cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/SpecificCacheManagerTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ApacheCommonsPoolTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BaseBulkGetKeysTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BaseBulkGetTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BulkGetKeysDistTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BulkGetKeysReplTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BulkGetKeysSimpleTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BulkGetReplTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BulkGetSimpleTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/CSAIntegrationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/CacheContainerTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/CacheManagerNotStartedTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/CacheManagerStoppedTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ClientAsymmetricClusterTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ClientConnectionPoolingTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ClientSocketReadTimeoutTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ConsistentHashComparisonTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ConsistentHashFactoryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ConsistentHashPerformanceTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ConsistentHashV1IntegrationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ConsistentHashV1Test.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/DefaultExpirationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/DistTopologyChangeTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/DroppedConnectionsTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ExpiryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ForceReturnValueTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ForceReturnValuesTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HeavyLoadConnectionPoolingTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HitsAwareCacheManagersTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRod10CSAIntegrationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodAsyncReplicationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodIntegrationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodServerStartStopTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodStatisticsTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/PingOnStartupTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteAsyncAPITest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteCacheManagerTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ReplTopologyChangeTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RoundRobinBalancingIntegrationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RoundRobinBalancingStrategyTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerErrorTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerRestartTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerShutdownTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SocketTimeoutErrorTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeAsyncExecutorFactory.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeCustomConsistentHashV1.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeRequestBalancingStrategy.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeTransportfactory.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SslTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/TestHelper.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/TransportObjectFactoryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/WorkerThread.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/configuration/ConfigurationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/ApacheAvroMarshallerTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedAccount.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedAccountMarshaller.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedCompatTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/ProtoStreamMarshallerTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryFileSystemTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryIspnDirectoryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodTunedQueryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerIspnDirQueryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerIspnDirReplQueryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerQueryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsFilestoreTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsIspnDirTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslIterationTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryJmxTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/AbstractRetryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/DistributionRetryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/ReplicationRetryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/RetryOnFailureUnitTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/ServerFailureRetryTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/stress/ClientConsistentHashPerfTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/HotRodClientTestingUtil.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/MultiHotRodServersTest.java
create mode 100644 client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/RemoteCacheManagerCallable.java
delete mode 100644 maven-settings.xml
create mode 100644 off-heap/pom.xml.off-heap
diff --git a/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/DefaultCacheTest.java b/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/DefaultCacheTest.java
new file mode 100644
index 000000000000..b46f9a05f820
--- /dev/null
+++ b/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/DefaultCacheTest.java
@@ -0,0 +1,88 @@
+package org.infinispan.cdi.test.cache.remote;
+
+import org.infinispan.cdi.Remote;
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.core.test.ServerTestingUtil;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+
+import static org.infinispan.cdi.test.testutil.Deployments.baseDeployment;
+import static org.infinispan.client.hotrod.TestHelper.startHotRodServer;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tests the default cache injection.
+ *
+ * @author Kevin Pollet (C) 2011 SERLI
+ */
+@Test(groups = "functional", testName = "cdi.test.cache.remote.DefaultCacheTest")
+public class DefaultCacheTest extends Arquillian {
+
+ private static final String SERVER_LIST_KEY = "infinispan.client.hotrod.server_list";
+
+ @Deployment
+ public static Archive> deployment() {
+ return baseDeployment()
+ .addClass(DefaultCacheTest.class);
+ }
+
+ private static HotRodServer hotRodServer;
+ private static EmbeddedCacheManager embeddedCacheManager;
+
+ @Inject
+ @Remote
+ private RemoteCache cache;
+
+ @Inject
+ private RemoteCache remoteCache;
+
+ @BeforeTest
+ public void beforeMethod() {
+ embeddedCacheManager = TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration(TestCacheManagerFactory
+ .getDefaultCacheConfiguration(false)));
+ hotRodServer = startHotRodServer(embeddedCacheManager);
+ }
+
+ @AfterTest(alwaysRun = true)
+ public void afterMethod() {
+ TestingUtil.killCacheManagers(embeddedCacheManager);
+ ServerTestingUtil.killServer(hotRodServer);
+ }
+
+ public void testDefaultCache() {
+ cache.put("pete", "British");
+ cache.put("manik", "Sri Lankan");
+
+ assertEquals(cache.get("pete"), "British");
+ assertEquals(cache.get("manik"), "Sri Lankan");
+ assertEquals(remoteCache.get("pete"), "British");
+ assertEquals(remoteCache.get("manik"), "Sri Lankan");
+ }
+
+ /**
+ * Overrides the default remote cache manager.
+ */
+ @Produces
+ @ApplicationScoped
+ public static RemoteCacheManager defaultRemoteCacheManager() {
+ return new RemoteCacheManager(
+ new org.infinispan.client.hotrod.configuration.ConfigurationBuilder()
+ .addServers("127.0.0.1:" + hotRodServer.getPort()).build());
+ }
+
+}
diff --git a/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/NamedCacheTest.java b/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/NamedCacheTest.java
new file mode 100644
index 000000000000..7663c4cad2aa
--- /dev/null
+++ b/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/NamedCacheTest.java
@@ -0,0 +1,95 @@
+package org.infinispan.cdi.test.cache.remote;
+
+import org.infinispan.cdi.Remote;
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+
+import static org.infinispan.cdi.test.testutil.Deployments.baseDeployment;
+import static org.infinispan.client.hotrod.TestHelper.startHotRodServer;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tests the named cache injection.
+ *
+ * @author Kevin Pollet (C) 2011 SERLI
+ */
+@Test(groups = "functional", testName = "cdi.test.cache.remote.NamedCacheTest")
+public class NamedCacheTest extends Arquillian {
+
+ private static final String SERVER_LIST_KEY = "infinispan.client.hotrod.server_list";
+
+ @Deployment
+ public static Archive> deployment() {
+ return baseDeployment()
+ .addClass(NamedCacheTest.class)
+ .addClass(Small.class);
+ }
+
+ private static HotRodServer hotRodServer;
+ private static EmbeddedCacheManager embeddedCacheManager;
+
+ @Inject
+ @Remote("small")
+ private RemoteCache cache;
+
+ @Inject
+ @Small
+ private RemoteCache cacheWithQualifier;
+
+ @BeforeTest
+ public void beforeMethod() {
+ embeddedCacheManager = TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration(TestCacheManagerFactory
+ .getDefaultCacheConfiguration(false)));
+ embeddedCacheManager.defineConfiguration("small", embeddedCacheManager.getDefaultCacheConfiguration());
+ hotRodServer = startHotRodServer(embeddedCacheManager);
+ }
+
+ @AfterTest(alwaysRun = true)
+ public void afterMethod() {
+ if (embeddedCacheManager != null) embeddedCacheManager.stop();
+ if (hotRodServer != null) hotRodServer.stop();
+ }
+
+ public void testNamedCache() {
+ cache.put("pete", "British");
+ cache.put("manik", "Sri Lankan");
+
+ assertEquals(cache.getName(), "small");
+ assertEquals(cache.get("pete"), "British");
+ assertEquals(cache.get("manik"), "Sri Lankan");
+
+ // here we check that the cache injection with the @Small qualifier works
+ // like the injection with the @Remote qualifier
+
+ assertEquals(cacheWithQualifier.getName(), "small");
+ assertEquals(cacheWithQualifier.get("pete"), "British");
+ assertEquals(cacheWithQualifier.get("manik"), "Sri Lankan");
+ }
+
+ /**
+ * Overrides the default remote cache manager.
+ */
+ @Produces
+ @ApplicationScoped
+ public static RemoteCacheManager defaultRemoteCacheManager() {
+ return new RemoteCacheManager(
+ new org.infinispan.client.hotrod.configuration.ConfigurationBuilder()
+ .addServers("127.0.0.1:" + hotRodServer.getPort()).build());
+ }
+
+}
diff --git a/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/Small.java b/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/Small.java
new file mode 100644
index 000000000000..5971a08b90bb
--- /dev/null
+++ b/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/Small.java
@@ -0,0 +1,25 @@
+package org.infinispan.cdi.test.cache.remote;
+
+import org.infinispan.cdi.Remote;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * @author Kevin Pollet (C) 2011 SERLI
+ */
+@Remote("small")
+@Qualifier
+@Target({TYPE, METHOD, PARAMETER, FIELD})
+@Retention(RUNTIME)
+@Documented
+public @interface Small {
+}
diff --git a/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/SpecificCacheManagerTest.java b/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/SpecificCacheManagerTest.java
new file mode 100644
index 000000000000..6ea7194828d2
--- /dev/null
+++ b/cdi/extension/src/test/java/org/infinispan/cdi/test/cache/remote/SpecificCacheManagerTest.java
@@ -0,0 +1,86 @@
+package org.infinispan.cdi.test.cache.remote;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.shrinkwrap.api.Archive;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+
+import static org.infinispan.cdi.test.testutil.Deployments.baseDeployment;
+import static org.infinispan.client.hotrod.TestHelper.startHotRodServer;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tests that the use of a specific cache manager for one cache.
+ *
+ * @author Kevin Pollet (C) 2011 SERLI
+ */
+@Test(groups = "functional", testName = "cdi.test.cache.remote.SpecificCacheManagerTest")
+public class SpecificCacheManagerTest extends Arquillian {
+
+ private static final String SERVER_LIST_KEY = "infinispan.client.hotrod.server_list";
+
+ @Deployment
+ public static Archive> deployment() {
+ return baseDeployment()
+ .addClass(SpecificCacheManagerTest.class)
+ .addClass(Small.class);
+ }
+
+ private static HotRodServer hotRodServer;
+ private static EmbeddedCacheManager embeddedCacheManager;
+
+ @Inject
+ @Small
+ private RemoteCache cache;
+
+ @BeforeTest
+ public void beforeMethod() {
+ embeddedCacheManager = TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration(TestCacheManagerFactory
+ .getDefaultCacheConfiguration(false)));
+ embeddedCacheManager.defineConfiguration("small", embeddedCacheManager.getDefaultCacheConfiguration());
+ hotRodServer = startHotRodServer(embeddedCacheManager);
+ }
+
+ @AfterTest(alwaysRun = true)
+ public void afterMethod() {
+ if (embeddedCacheManager != null) embeddedCacheManager.stop();
+ if (hotRodServer != null) hotRodServer.stop();
+ }
+
+ public void testSpecificCacheManager() {
+ cache.put("pete", "British");
+ cache.put("manik", "Sri Lankan");
+
+ assertEquals(cache.getName(), "small");
+ assertEquals(cache.get("pete"), "British");
+ assertEquals(cache.get("manik"), "Sri Lankan");
+ }
+
+ /**
+ * Produces a specific cache manager for the small cache.
+ *
+ * @see Small
+ */
+ @Small
+ @Produces
+ @ApplicationScoped
+ public static RemoteCacheManager smallRemoteCacheManager() {
+ return new RemoteCacheManager(
+ new org.infinispan.client.hotrod.configuration.ConfigurationBuilder()
+ .addServers("127.0.0.1:" + hotRodServer.getPort()).build());
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ApacheCommonsPoolTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ApacheCommonsPoolTest.java
new file mode 100644
index 000000000000..cdd7f8dc4b8c
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ApacheCommonsPoolTest.java
@@ -0,0 +1,103 @@
+package org.infinispan.client.hotrod;
+
+import org.apache.commons.pool.BaseKeyedPoolableObjectFactory;
+import org.apache.commons.pool.KeyedObjectPool;
+import org.apache.commons.pool.KeyedObjectPoolFactory;
+import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory;
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.fail;
+
+/**
+ * // TODO: Document this
+ *
+ * @author Galder Zamarreño
+ * @since // TODO
+ */
+@Test(groups = "functional", testName = "client.hotrod.ApacheCommonsPoolTest")
+public class ApacheCommonsPoolTest {
+
+ public void testBorrowValidObjectFromPool() throws Exception {
+ KeyedObjectPool pool =
+ BasicPoolFactory.createPoolFactory().createPool();
+ String obj = pool.borrowObject(1);
+ assertEquals("1", obj);
+ }
+
+ @Test(expectedExceptions = TooHighException.class)
+ public void testBorrowFromPoolException() throws Exception {
+ GenericKeyedObjectPoolFactory poolFactory =
+ BasicPoolFactory.createPoolFactory();
+ try {
+ poolFactory.createPool().borrowObject(Integer.MAX_VALUE);
+ } finally {
+ BasicPoolFactory basicPoolFactory =
+ (BasicPoolFactory) poolFactory.getFactory();
+ assertEquals("invalid", basicPoolFactory.getState(Integer.MAX_VALUE));
+ }
+ }
+
+ public void testInvalidateBorrowFromPool() throws Exception {
+ GenericKeyedObjectPoolFactory poolFactory =
+ BasicPoolFactory.createPoolFactory();
+ KeyedObjectPool pool = poolFactory.createPool();
+ try {
+ pool.borrowObject(Integer.MAX_VALUE);
+ fail("Should have thrown a TooHighException");
+ } catch (TooHighException e) {
+ // Expected, now invalidate object
+ pool.invalidateObject(Integer.MAX_VALUE, null);
+ BasicPoolFactory basicPoolFactory =
+ (BasicPoolFactory) poolFactory.getFactory();
+ assertEquals("destroyed", basicPoolFactory.getState(Integer.MAX_VALUE));
+ }
+ }
+
+ private static class BasicPoolFactory
+ extends BaseKeyedPoolableObjectFactory {
+
+ private Map state = new HashMap();
+
+ private BasicPoolFactory() {
+ // Singleton
+ }
+
+ @Override
+ public String makeObject(Integer key) throws Exception {
+ if (Integer.MAX_VALUE == key.intValue()) {
+ state.put(key, "invalid");
+ throw new TooHighException("Too high");
+ }
+
+ return key.toString();
+ }
+
+ @Override
+ public void destroyObject(Integer key, String obj) throws Exception {
+ state.put(key, "destroyed");
+ }
+
+ public String getState(Integer key) {
+ return state.get(key);
+ }
+
+ public static GenericKeyedObjectPoolFactory createPoolFactory() {
+ return new GenericKeyedObjectPoolFactory(
+ new BasicPoolFactory());
+ }
+
+ }
+
+ private static class TooHighException extends RuntimeException {
+
+ public TooHighException(String message) {
+ super(message); // TODO: Customise this generated block
+ }
+
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BaseBulkGetKeysTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BaseBulkGetKeysTest.java
new file mode 100644
index 000000000000..7efe35edc3cc
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/BaseBulkGetKeysTest.java
@@ -0,0 +1,110 @@
+package org.infinispan.client.hotrod;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+/**
+ * Tests functionality related to getting multiple entries from a HotRod server
+ * in bulk.
+ *
+ * @author Ray Tsang
+ * @since 5.2
+ */
+@Test(groups = "functional")
+public abstract class BaseBulkGetKeysTest extends MultipleCacheManagersTest {
+ protected HotRodServer[] hotrodServers;
+ protected RemoteCacheManager remoteCacheManager;
+ protected RemoteCache
+ *
+ * This test is disabled because the limitations of the protocol do not allow
+ * for this to work as expected. This test will be enabled once v2 of the
+ * protocol has been implemented and the functionality is there to support it.
+ *
+ * @author Galder Zamarreño
+ * @since 5.0
+ */
+@Test(groups = "unstable", testName = "client.hotrod.ExpiryTest", description = "original group: functional")
+public class ExpiryTest extends MultiHotRodServersTest {
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false);
+ builder.expiration().lifespan(2000L).maxIdle(3000L);
+ createHotRodServers(1, builder);
+ }
+
+ public void testGlobalExpiry(Method m) throws Exception {
+ RemoteCacheManager client0 = client(0);
+ RemoteCache cache0 = client0.getCache();
+ String v1 = v(m);
+ cache0.put(1, v1);
+ Thread.sleep(2500);
+ assertEquals(null, cache0.get(1));
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ForceReturnValueTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ForceReturnValueTest.java
new file mode 100644
index 000000000000..58978ca914e9
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ForceReturnValueTest.java
@@ -0,0 +1,88 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.assertNull;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.*;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(testName = "client.hotrod.ForceReturnValueTest", groups = "functional")
+public class ForceReturnValueTest extends SingleCacheManagerTest {
+
+ RemoteCache remoteCache;
+
+ private RemoteCacheManager remoteCacheManager;
+
+ private HotRodServer hotrodServer;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ // This method should be limited to starting the cache manager, to avoid
+ // leaks as a result of code after creating the cache manager failing.
+ return TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration());
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ super.setup();
+ hotrodServer = TestHelper.startHotRodServer(cacheManager);
+ remoteCacheManager = new RemoteCacheManager("localhost",hotrodServer.getPort());
+ remoteCache = remoteCacheManager.getCache();
+ }
+
+ @AfterClass
+ public void destroy() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotrodServer);
+ super.teardown();
+ }
+
+ public void testPut() {
+ assert null == remoteCache.put("aKey", "aValue");
+ assert "aValue".equals(remoteCache.withFlags(Flag.FORCE_RETURN_VALUE).put("aKey", "otherValue"));
+ assert remoteCache.containsKey("aKey");
+ assert remoteCache.get("aKey").equals("otherValue");
+ }
+
+ public void testRemove() {
+ assert null == remoteCache.put("aKey", "aValue");
+ assert remoteCache.get("aKey").equals("aValue");
+ assert "aValue".equals(remoteCache.withFlags(Flag.FORCE_RETURN_VALUE).remove("aKey"));
+ assert !remoteCache.containsKey("aKey");
+ }
+
+ public void testRemoveNonExistForceReturnPrevious() {
+ assertNull(remoteCache.withFlags(Flag.FORCE_RETURN_VALUE).remove("aKey"));
+ remoteCache.put("k", "v");
+ }
+
+ public void testContains() {
+ assert !remoteCache.containsKey("aKey");
+ remoteCache.put("aKey", "aValue");
+ assert remoteCache.containsKey("aKey");
+ }
+
+ public void testReplace() {
+ assert null == remoteCache.replace("aKey", "anotherValue");
+ remoteCache.put("aKey", "aValue");
+ assert "aValue".equals(remoteCache.withFlags(Flag.FORCE_RETURN_VALUE).replace("aKey", "anotherValue"));
+ assert remoteCache.get("aKey").equals("anotherValue");
+ }
+
+ public void testPutIfAbsent() {
+ remoteCache.put("aKey", "aValue");
+ assert null == remoteCache.putIfAbsent("aKey", "anotherValue");
+ Object existingValue = remoteCache.withFlags(Flag.FORCE_RETURN_VALUE).putIfAbsent("aKey", "anotherValue");
+ assert "aValue".equals(existingValue) : "Existing value was:" + existingValue;
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ForceReturnValuesTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ForceReturnValuesTest.java
new file mode 100644
index 000000000000..443d2871de49
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ForceReturnValuesTest.java
@@ -0,0 +1,57 @@
+package org.infinispan.client.hotrod;
+
+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.fwk.CleanupAfterMethod;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import java.util.Properties;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+@Test(testName = "client.hotrod.ForceReturnValuesTest", groups = "functional")
+@CleanupAfterMethod
+public class ForceReturnValuesTest extends SingleCacheManagerTest {
+ private HotRodServer hotRodServer;
+ private RemoteCacheManager remoteCacheManager;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ cacheManager = TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration());
+ cache = cacheManager.getCache();
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ Properties hotrodClientConf = new Properties();
+ hotrodClientConf.put("infinispan.client.hotrod.server_list", "localhost:" + hotRodServer.getPort());
+ remoteCacheManager = new RemoteCacheManager(hotrodClientConf);
+ return cacheManager;
+ }
+
+ @AfterMethod
+ void shutdown() {
+ HotRodClientTestingUtil.killRemoteCacheManager(remoteCacheManager);
+ HotRodClientTestingUtil.killServers(hotRodServer);
+ }
+
+ public void testDontForceReturnValues() {
+ RemoteCache rc = remoteCacheManager.getCache();
+ String rv = rc.put("Key", "Value");
+ assert rv == null;
+ rv = rc.put("Key", "Value2");
+ assert rv == null;
+ }
+
+ public void testForceReturnValues() {
+ RemoteCache rc = remoteCacheManager.getCache(true);
+ String rv = rc.put("Key", "Value");
+ assert rv == null;
+ rv = rc.put("Key", "Value2");
+ assert rv != null;
+ assert "Value".equals(rv);
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HeavyLoadConnectionPoolingTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HeavyLoadConnectionPoolingTest.java
new file mode 100644
index 000000000000..b55cace6d738
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HeavyLoadConnectionPoolingTest.java
@@ -0,0 +1,122 @@
+package org.infinispan.client.hotrod;
+
+import org.apache.commons.pool.impl.GenericKeyedObjectPool;
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory;
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.interceptors.base.CommandInterceptor;
+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.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ExecutionException;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test (testName = "client.hotrod.HeavyLoadConnectionPoolingTest", groups = "functional")
+public class HeavyLoadConnectionPoolingTest extends SingleCacheManagerTest {
+ private HotRodServer hotRodServer;
+ private RemoteCacheManager remoteCacheManager;
+ private RemoteCache remoteCache;
+ private GenericKeyedObjectPool,?> connectionPool;
+
+ @AfterMethod
+ @Override
+ protected void clearContent() {
+ }
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ cacheManager = TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration());
+ cache = cacheManager.getCache();
+
+ // make sure all operations take at least 100 msecs
+ cache.getAdvancedCache().addInterceptor(new ConstantDelayTransportInterceptor(100), 0);
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ Properties hotrodClientConf = new Properties();
+ hotrodClientConf.setProperty("infinispan.client.hotrod.server_list", "localhost:"+hotRodServer.getPort());
+ hotrodClientConf.setProperty("timeBetweenEvictionRunsMillis", "500");
+ hotrodClientConf.setProperty("minEvictableIdleTimeMillis", "100");
+ hotrodClientConf.setProperty("numTestsPerEvictionRun", "10");
+ hotrodClientConf.setProperty("infinispan.client.hotrod.ping_on_startup", "true");
+ remoteCacheManager = new RemoteCacheManager(hotrodClientConf);
+ remoteCache = remoteCacheManager.getCache();
+
+ TcpTransportFactory tcpConnectionFactory = (TcpTransportFactory) TestingUtil.extractField(remoteCacheManager, "transportFactory");
+ connectionPool = (GenericKeyedObjectPool, ?>) TestingUtil.extractField(tcpConnectionFactory, "connectionPool");
+
+ return cacheManager;
+ }
+
+ @AfterClass
+ @Override
+ protected void destroyAfterClass() {
+ super.destroyAfterClass();
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotRodServer);
+ }
+
+ public void testHeavyLoad() throws InterruptedException, ExecutionException {
+ List workers = new ArrayList();
+
+ //create 20 threads and do work with them
+ for (int i =0; i < 20; i++) {
+ WorkerThread workerThread = new WorkerThread(remoteCache);
+ workers.add(workerThread);
+ workerThread.stress();
+ }
+ while (connectionPool.getNumActive() <= 15) {
+ Thread.sleep(10);
+ }
+
+ for (WorkerThread wt: workers) {
+ wt.stop();
+ }
+
+ for (WorkerThread wt: workers) {
+ wt.awaitTermination();
+ }
+
+ //now wait for the idle thread to wake up and clean them
+
+ eventually(new Condition() {
+ @Override
+ public boolean isSatisfied() throws Exception {
+ int numIdle = connectionPool.getNumIdle();
+ int numActive = connectionPool.getNumActive();
+ return numIdle == 0 && numActive == 0;
+ }
+ });
+ }
+
+ public static class ConstantDelayTransportInterceptor extends CommandInterceptor {
+
+ private int millis;
+
+ public ConstantDelayTransportInterceptor(int millis) {
+ this.millis = millis;
+ }
+
+ @Override
+ protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
+ Thread.sleep(millis);
+ return super.handleDefault(ctx, command);
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HitsAwareCacheManagersTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HitsAwareCacheManagersTest.java
new file mode 100644
index 000000000000..2d455db81383
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HitsAwareCacheManagersTest.java
@@ -0,0 +1,120 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.Cache;
+import org.infinispan.commands.VisitableCommand;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.interceptors.base.CommandInterceptor;
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.testng.annotations.BeforeMethod;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+public abstract class HitsAwareCacheManagersTest extends MultipleCacheManagersTest {
+
+ protected Map hrServ2CacheManager = new HashMap();
+ protected Map addr2hrServer = new HashMap();
+
+ @Override
+ @BeforeMethod(alwaysRun=true)
+ public void createBeforeMethod() throws Throwable {
+ if (cleanupAfterMethod()) {
+ hrServ2CacheManager.clear();
+ addr2hrServer.clear();
+ }
+ super.createBeforeMethod();
+ }
+
+ protected HitCountInterceptor getHitCountInterceptor(Cache cache) {
+ HitCountInterceptor hitCountInterceptor = null;
+ List interceptorChain = cache.getAdvancedCache().getInterceptorChain();
+ for (CommandInterceptor interceptor : interceptorChain) {
+ boolean isHitCountInterceptor = interceptor instanceof HitCountInterceptor;
+ if (hitCountInterceptor != null && isHitCountInterceptor) {
+ throw new IllegalStateException("Two HitCountInterceptors! " + interceptorChain);
+ }
+ if (isHitCountInterceptor) {
+ hitCountInterceptor = (HitCountInterceptor) interceptor;
+ }
+ }
+ return hitCountInterceptor;
+ }
+
+ protected void assertOnlyServerHit(SocketAddress serverAddress) {
+ CacheContainer cacheContainer = hrServ2CacheManager.get(serverAddress);
+ HitCountInterceptor interceptor = getHitCountInterceptor(cacheContainer.getCache());
+ assert interceptor.getHits() == 1 : "Expected one hit but received " + interceptor.getHits();
+ for (CacheContainer cm : hrServ2CacheManager.values()) {
+ if (cm != cacheContainer) {
+ interceptor = getHitCountInterceptor(cm.getCache());
+ assert interceptor.getHits() == 0 : "Expected 0 hits but got " + interceptor.getHits();
+ }
+ }
+ }
+
+ protected void assertNoHits() {
+ for (CacheContainer cm : hrServ2CacheManager.values()) {
+ HitCountInterceptor interceptor = getHitCountInterceptor(cm.getCache());
+ assert interceptor.getHits() == 0 : "Expected 0 hits but got " + interceptor.getHits();
+ }
+ }
+
+ protected InetSocketAddress getAddress(HotRodServer hotRodServer) {
+ InetSocketAddress socketAddress = new InetSocketAddress(hotRodServer.getHost(), hotRodServer.getPort());
+ addr2hrServer.put(socketAddress, hotRodServer);
+ return socketAddress;
+ }
+
+ protected void resetStats() {
+ for (EmbeddedCacheManager manager : cacheManagers) {
+ HitCountInterceptor cmi = getHitCountInterceptor(manager.getCache());
+ cmi.reset();
+ }
+ }
+
+ protected void addInterceptors() {
+ for (EmbeddedCacheManager manager : cacheManagers) {
+ addHitCountInterceptor(manager.getCache());
+ }
+ }
+
+ private void addHitCountInterceptor(Cache cache) {
+ HitCountInterceptor interceptor = new HitCountInterceptor();
+ cache.getAdvancedCache().addInterceptor(interceptor, 1);
+ }
+
+ /**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+ public static class HitCountInterceptor extends CommandInterceptor{
+
+ private volatile int invocationCount;
+
+ @Override
+ protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable {
+ if (ctx.isOriginLocal()) {
+ invocationCount ++;
+ }
+ return super.handleDefault(ctx, command);
+ }
+
+ public int getHits() {
+ return invocationCount;
+ }
+
+ public void reset() {
+ invocationCount = 0;
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRod10CSAIntegrationTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRod10CSAIntegrationTest.java
new file mode 100644
index 000000000000..caa319db820f
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRod10CSAIntegrationTest.java
@@ -0,0 +1,22 @@
+package org.infinispan.client.hotrod;
+
+import org.testng.annotations.Test;
+
+import java.util.Properties;
+
+/**
+ * Tests consistent hash algorithm consistency between the client and server
+ * using Hot Rod's 1.0 protocol.
+ *
+ * @author Galder Zamarreño
+ * @since 5.1
+ */
+@Test(groups = "functional", testName = "client.hotrod.HotRod10CSAIntegrationTest")
+public class HotRod10CSAIntegrationTest extends CSAIntegrationTest {
+
+ @Override
+ protected void setHotRodProtocolVersion(Properties props) {
+ props.setProperty("infinispan.client.hotrod.protocol_version", "1.0");
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodAsyncReplicationTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodAsyncReplicationTest.java
new file mode 100644
index 000000000000..441f4f11a53b
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodAsyncReplicationTest.java
@@ -0,0 +1,61 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.test.MultiHotRodServersTest;
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.test.ReplListener;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+import static org.infinispan.test.TestingUtil.v;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+@Test(groups = "functional", testName = "client.hotrod.HotRodAsyncReplicationTest")
+public class HotRodAsyncReplicationTest extends MultiHotRodServersTest {
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ ConfigurationBuilder builder = hotRodCacheConfiguration(
+ getDefaultClusteredCacheConfig(CacheMode.REPL_ASYNC, false));
+ builder.clustering().async().replQueueInterval(1000L).useReplQueue(true);
+ builder.eviction().maxEntries(3);
+
+ createHotRodServers(2, builder);
+ }
+
+ public void testPutKeyValue(Method m) {
+ final RemoteCache remoteCache0 = client(0).getCache();
+ final RemoteCache remoteCache1 = client(1).getCache();
+
+ ReplListener replList0 = getReplListener(0);
+ ReplListener replList1 = getReplListener(1);
+
+ replList0.expect(PutKeyValueCommand.class);
+ replList1.expect(PutKeyValueCommand.class);
+
+ final String v1 = v(m);
+ remoteCache0.put(1, v1);
+
+ replList0.waitForRpc();
+ replList1.waitForRpc();
+
+ assertEquals(v1, remoteCache1.get(1));
+ assertEquals(v1, remoteCache1.get(1)); // Called twice to cover all round robin options
+ assertEquals(v1, remoteCache0.get(1));
+ assertEquals(v1, remoteCache0.get(1)); // Called twice to cover all round robin options
+ }
+
+ private ReplListener getReplListener(int cacheIndex) {
+ ReplListener replList = listeners.get(cache(cacheIndex));
+ if (replList == null)
+ replList = new ReplListener(cache(cacheIndex), true, true);
+ else
+ replList.reconfigureListener(true, true);
+
+ return replList;
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodIntegrationTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodIntegrationTest.java
new file mode 100644
index 000000000000..1e9604a9ea28
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodIntegrationTest.java
@@ -0,0 +1,274 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.commons.util.concurrent.NotifyingFuture;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+
+import static org.infinispan.test.TestingUtil.k;
+import static org.infinispan.test.TestingUtil.v;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertNull;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.*;
+
+/**
+ * @author mmarkus
+ * @since 4.1
+ */
+@Test (testName = "client.hotrod.HotRodIntegrationTest", groups = "functional" )
+public class HotRodIntegrationTest extends SingleCacheManagerTest {
+
+ private static final Log log = LogFactory.getLog(HotRodIntegrationTest.class);
+
+ private static final String CACHE_NAME = "replSync";
+
+ RemoteCache defaultRemote;
+ RemoteCache remoteCache;
+ private RemoteCacheManager remoteCacheManager;
+
+ protected HotRodServer hotrodServer;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ ConfigurationBuilder builder = hotRodCacheConfiguration(
+ getDefaultStandaloneCacheConfig(false));
+ EmbeddedCacheManager cm = TestCacheManagerFactory
+ .createCacheManager(hotRodCacheConfiguration());
+ cm.defineConfiguration(CACHE_NAME, builder.build());
+ return cm;
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ super.setup();
+ //pass the config file to the cache
+ hotrodServer = TestHelper.startHotRodServer(cacheManager);
+ log.info("Started server on port: " + hotrodServer.getPort());
+
+ remoteCacheManager = getRemoteCacheManager();
+ defaultRemote = remoteCacheManager.getCache();
+ remoteCache = remoteCacheManager.getCache(CACHE_NAME);
+ }
+
+ protected RemoteCacheManager getRemoteCacheManager() {
+ Properties config = new Properties();
+ config.put("infinispan.client.hotrod.server_list", "127.0.0.1:" + hotrodServer.getPort());
+ return new RemoteCacheManager(config);
+ }
+
+
+ @AfterClass
+ public void testDestroyRemoteCacheFactory() {
+ HotRodClientTestingUtil.killRemoteCacheManager(remoteCacheManager);
+ HotRodClientTestingUtil.killServers(hotrodServer);
+ }
+
+ public void testPut() throws Exception {
+ assert null == remoteCache.put("aKey", "aValue");
+ assertHotRodEquals(cacheManager, CACHE_NAME, "aKey", "aValue");
+ assert null == defaultRemote.put("otherKey", "otherValue");
+ assertHotRodEquals(cacheManager, "otherKey", "otherValue");
+ assert remoteCache.containsKey("aKey");
+ assert defaultRemote.containsKey("otherKey");
+ assert remoteCache.get("aKey").equals("aValue");
+ assert defaultRemote.get("otherKey").equals("otherValue");
+ }
+
+ public void testRemove() throws Exception {
+ assert null == remoteCache.put("aKey", "aValue");
+ assertHotRodEquals(cacheManager, CACHE_NAME, "aKey", "aValue");
+
+ assert remoteCache.get("aKey").equals("aValue");
+
+ assert null == remoteCache.remove("aKey");
+ assertHotRodEquals(cacheManager, CACHE_NAME, "aKey", null);
+ assert !remoteCache.containsKey("aKey");
+ }
+
+ public void testContains() {
+ assert !remoteCache.containsKey("aKey");
+ remoteCache.put("aKey", "aValue");
+ assert remoteCache.containsKey("aKey");
+ }
+
+ public void testGetVersionedCacheEntry() {
+ VersionedValue value = remoteCache.getVersioned("aKey");
+ assertNull("expected null but received: " + value, remoteCache.getVersioned("aKey"));
+ remoteCache.put("aKey", "aValue");
+ assert remoteCache.get("aKey").equals("aValue");
+ VersionedValue valueBinary = remoteCache.getVersioned("aKey");
+ assert valueBinary != null;
+ assertEquals(valueBinary.getValue(), "aValue");
+ log.info("Version is: " + valueBinary.getVersion());
+
+ //now put the same value
+ remoteCache.put("aKey", "aValue");
+ VersionedValue entry2 = remoteCache.getVersioned("aKey");
+ assertEquals(entry2.getValue(), "aValue");
+
+ assert entry2.getVersion() != valueBinary.getVersion();
+ assert !valueBinary.equals(entry2);
+
+ //now put a different value
+ remoteCache.put("aKey", "anotherValue");
+ VersionedValue entry3 = remoteCache.getVersioned("aKey");
+ assertEquals(entry3.getValue(), "anotherValue");
+ assert entry3.getVersion() != entry2.getVersion();
+ assert !entry3.equals(entry2);
+ }
+
+ public void testGetWithMetadata() {
+ MetadataValue> value = remoteCache.getWithMetadata("aKey");
+ assertNull("expected null but received: " + value, value);
+ remoteCache.put("aKey", "aValue");
+ assert remoteCache.get("aKey").equals("aValue");
+ MetadataValue> immortalValue = remoteCache.getWithMetadata("aKey");
+ assertNotNull(immortalValue);
+ assertEquals("aValue", immortalValue.getValue());
+ assertEquals(-1, immortalValue.getLifespan());
+ assertEquals(-1, immortalValue.getMaxIdle());
+
+ remoteCache.put("bKey", "bValue", 60, TimeUnit.SECONDS);
+ MetadataValue> mortalValueWithLifespan = remoteCache.getWithMetadata("bKey");
+ assertNotNull(mortalValueWithLifespan);
+ assertEquals("bValue", mortalValueWithLifespan.getValue());
+ assertEquals(60, mortalValueWithLifespan.getLifespan());
+ assertEquals(-1, mortalValueWithLifespan.getMaxIdle());
+
+ remoteCache.put("cKey", "cValue", 60, TimeUnit.SECONDS, 30, TimeUnit.SECONDS);
+ MetadataValue> mortalValueWithMaxIdle = remoteCache.getWithMetadata("cKey");
+ assertNotNull(mortalValueWithMaxIdle);
+ assertEquals("cValue", mortalValueWithMaxIdle.getValue());
+ assertEquals(60, mortalValueWithMaxIdle.getLifespan());
+ assertEquals(30, mortalValueWithMaxIdle.getMaxIdle());
+ }
+
+ public void testReplace() {
+ assert null == remoteCache.replace("aKey", "anotherValue");
+ remoteCache.put("aKey", "aValue");
+ assert null == remoteCache.replace("aKey", "anotherValue");
+ assert remoteCache.get("aKey").equals("anotherValue");
+ }
+
+ public void testReplaceIfUnmodified() {
+ assert null == remoteCache.replace("aKey", "aValue");
+
+
+ remoteCache.put("aKey", "aValue");
+ VersionedValue valueBinary = remoteCache.getVersioned("aKey");
+ assert remoteCache.replaceWithVersion("aKey", "aNewValue", valueBinary.getVersion());
+
+ VersionedValue entry2 = remoteCache.getVersioned("aKey");
+ assert entry2.getVersion() != valueBinary.getVersion();
+ assertEquals(entry2.getValue(), "aNewValue");
+
+ assert !remoteCache.replaceWithVersion("aKey", "aNewValue", valueBinary.getVersion());
+ }
+
+ public void testReplaceIfUnmodifiedWithExpiry(Method m) throws InterruptedException {
+ final int key = 1;
+ remoteCache.put(key, v(m));
+ VersionedValue valueBinary = remoteCache.getVersioned(key);
+ int lifespanSecs = 3; // seconds
+ long lifespan = TimeUnit.SECONDS.toMillis(lifespanSecs);
+ long startTime = System.currentTimeMillis();
+ String newValue = v(m, 2);
+ assert remoteCache.replaceWithVersion(key, newValue, valueBinary.getVersion(), lifespanSecs);
+
+ while (true) {
+ Object value = remoteCache.get(key);
+ if (System.currentTimeMillis() >= startTime + lifespan)
+ break;
+ assertEquals(v(m, 2), value);
+ Thread.sleep(100);
+ }
+
+ while (System.currentTimeMillis() < startTime + lifespan + 2000) {
+ if (remoteCache.get(key) == null) break;
+ Thread.sleep(50);
+ }
+
+ assertNull(remoteCache.get(key));
+ }
+
+ public void testReplaceWithVersionWithLifespanAsync(Method m) throws Exception {
+ int lifespanInSecs = 1; //seconds
+ final String k = k(m), v = v(m), newV = v(m, 2);
+ assertNull(remoteCache.replace(k, v));
+
+ remoteCache.put(k, v);
+ VersionedValue valueBinary = remoteCache.getVersioned(k);
+ long lifespan = TimeUnit.SECONDS.toMillis(lifespanInSecs);
+ long startTime = System.currentTimeMillis();
+ NotifyingFuture future = remoteCache.replaceWithVersionAsync(
+ k, newV, valueBinary.getVersion(), lifespanInSecs);
+ assert future.get();
+
+ while (true) {
+ VersionedValue entry2 = remoteCache.getVersioned(k);
+ if (System.currentTimeMillis() >= startTime + lifespan)
+ break;
+ // version should have changed; value should have changed
+ assert entry2.getVersion() != valueBinary.getVersion();
+ assertEquals(newV, entry2.getValue());
+ Thread.sleep(100);
+ }
+
+ while (System.currentTimeMillis() < startTime + lifespan + 2000) {
+ if (remoteCache.get(k) == null) break;
+ Thread.sleep(50);
+ }
+
+ assertNull(remoteCache.getVersioned(k));
+ }
+
+ public void testRemoveIfUnmodified() {
+ assert !remoteCache.removeWithVersion("aKey", 12321212l);
+
+ remoteCache.put("aKey", "aValue");
+ VersionedValue valueBinary = remoteCache.getVersioned("aKey");
+ assert remoteCache.removeWithVersion("aKey", valueBinary.getVersion());
+ assertHotRodEquals(cacheManager, CACHE_NAME, "aKey", null);
+
+ remoteCache.put("aKey", "aNewValue");
+
+ VersionedValue entry2 = remoteCache.getVersioned("aKey");
+ assert entry2.getVersion() != valueBinary.getVersion();
+ assertEquals(entry2.getValue(), "aNewValue");
+
+ assert !remoteCache.removeWithVersion("aKey", valueBinary.getVersion());
+ }
+
+ public void testPutIfAbsent() {
+ remoteCache.put("aKey", "aValue");
+ assert null == remoteCache.putIfAbsent("aKey", "anotherValue");
+ assertEquals(remoteCache.get("aKey"),"aValue");
+
+ assertEquals(remoteCache.get("aKey"),"aValue");
+ assert remoteCache.containsKey("aKey");
+
+ assert true : remoteCache.replace("aKey", "anotherValue");
+ }
+
+ public void testClear() {
+ remoteCache.put("aKey", "aValue");
+ remoteCache.put("aKey2", "aValue");
+ remoteCache.clear();
+ assert !remoteCache.containsKey("aKey");
+ assert !remoteCache.containsKey("aKey2");
+ assert cache.isEmpty();
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodServerStartStopTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodServerStartStopTest.java
new file mode 100644
index 000000000000..d5834ec4d02f
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodServerStartStopTest.java
@@ -0,0 +1,57 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.assertEquals;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(testName = "client.hotrod.HotRodServerStartStopTest", groups = "functional")
+public class HotRodServerStartStopTest extends MultipleCacheManagersTest {
+ private HotRodServer hotRodServer1;
+ private HotRodServer hotRodServer2;
+
+ @AfterMethod
+ @Override
+ protected void clearContent() throws Throwable {
+ }
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ ConfigurationBuilder builder = hotRodCacheConfiguration(
+ getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false));
+ addClusterEnabledCacheManager(builder);
+ addClusterEnabledCacheManager(builder);
+
+ hotRodServer1 = TestHelper.startHotRodServer(manager(0));
+ hotRodServer2 = TestHelper.startHotRodServer(manager(1));
+
+ assert manager(0).getCache() != null;
+ assert manager(1).getCache() != null;
+
+ waitForClusterToForm();
+ }
+
+ public void testTouchServer() {
+ RemoteCacheManager remoteCacheManager = new RemoteCacheManager("localhost", hotRodServer1.getPort(), true);
+ RemoteCache remoteCache = remoteCacheManager.getCache();
+ remoteCache.put("k", "v");
+ assertEquals("v", remoteCache.get("k"));
+ killRemoteCacheManager(remoteCacheManager);
+ }
+
+ @Test (dependsOnMethods = "testTouchServer")
+ public void testHrServerStop() {
+ killServers(hotRodServer1, hotRodServer2);
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodStatisticsTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodStatisticsTest.java
new file mode 100644
index 000000000000..e523402fd163
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/HotRodStatisticsTest.java
@@ -0,0 +1,140 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.*;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(groups = "functional", testName = "client.hotrod.HotRodStatisticsTest")
+public class HotRodStatisticsTest {
+
+ private HotRodServer hotrodServer;
+ private CacheContainer cacheContainer;
+ private RemoteCacheManager rcm;
+ private RemoteCache remoteCache;
+ long startTime;
+
+ @BeforeMethod
+ protected void setup() throws Exception {
+ ConfigurationBuilder cfg = hotRodCacheConfiguration();
+ cfg.jmxStatistics().enable();
+ cacheContainer = TestCacheManagerFactory
+ .createClusteredCacheManagerEnforceJmxDomain(getClass().getSimpleName(), cfg);
+
+ hotrodServer = TestHelper.startHotRodServer((EmbeddedCacheManager) cacheContainer);
+ startTime = System.currentTimeMillis();
+ rcm = new RemoteCacheManager("localhost", hotrodServer.getPort());
+ remoteCache = rcm.getCache();
+ }
+
+ @AfterMethod
+ void tearDown() {
+ TestingUtil.killCacheManagers(cacheContainer);
+ killRemoteCacheManager(rcm);
+ killServers(hotrodServer);
+ }
+
+ public void testAllStatsArePresent() {
+ ServerStatistics serverStatistics = remoteCache.stats();
+ Map statsMap = serverStatistics.getStatsMap();
+ assertEquals(statsMap.get(ServerStatistics.STORES), "0");
+ assertEquals(statsMap.get(ServerStatistics.CURRENT_NR_OF_ENTRIES), "0");
+ assertEquals(statsMap.get(ServerStatistics.HITS),"0");
+ assertEquals(statsMap.get(ServerStatistics.MISSES),"0");
+ assertEquals(statsMap.get(ServerStatistics.REMOVE_HITS),"0");
+ assertEquals(statsMap.get(ServerStatistics.REMOVE_MISSES),"0");
+ assertEquals(statsMap.get(ServerStatistics.RETRIEVALS),"0");
+ assertEquals(statsMap.get(ServerStatistics.TOTAL_NR_OF_ENTRIES),"0");
+ assert 0 == remoteCache.size();
+ assert remoteCache.isEmpty();
+
+ Integer number = serverStatistics.getIntStatistic(ServerStatistics.TIME_SINCE_START);
+ assertTrue(number >= 0);
+ }
+
+ public void testStoresAndEntries() {
+ assert 0 == remoteCache.size();
+ assert remoteCache.isEmpty();
+ remoteCache.put("a","v");
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.STORES));
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.CURRENT_NR_OF_ENTRIES));
+ assert 1 == remoteCache.size();
+ assert !remoteCache.isEmpty();
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.TOTAL_NR_OF_ENTRIES));
+ remoteCache.put("a2","v2");
+ assertEquals((Integer)2, remoteCache.stats().getIntStatistic(ServerStatistics.STORES));
+ assertEquals((Integer)2, remoteCache.stats().getIntStatistic(ServerStatistics.CURRENT_NR_OF_ENTRIES));
+ assertEquals((Integer)2, remoteCache.stats().getIntStatistic(ServerStatistics.TOTAL_NR_OF_ENTRIES));
+ assert 2 == remoteCache.size();
+ assert !remoteCache.isEmpty();
+ remoteCache.put("a2","v3");
+ assertEquals((Integer)3, remoteCache.stats().getIntStatistic(ServerStatistics.STORES));
+ assertEquals((Integer)2, remoteCache.stats().getIntStatistic(ServerStatistics.CURRENT_NR_OF_ENTRIES));
+ assertEquals((Integer)3, remoteCache.stats().getIntStatistic(ServerStatistics.TOTAL_NR_OF_ENTRIES));
+ assert 2 == remoteCache.size();
+ assert !remoteCache.isEmpty();
+ }
+
+ public void testHitsAndMisses() {
+ remoteCache.get("a");
+ assertEquals((Integer)0, remoteCache.stats().getIntStatistic(ServerStatistics.HITS));
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.MISSES));
+ remoteCache.put("a","v");
+ assertEquals((Integer)0, remoteCache.stats().getIntStatistic(ServerStatistics.HITS));
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.MISSES));
+ remoteCache.get("a");
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.HITS));
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.MISSES));
+ remoteCache.get("a");
+ remoteCache.get("a");
+ remoteCache.get("a");
+ assertEquals((Integer)4, remoteCache.stats().getIntStatistic(ServerStatistics.HITS));
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.MISSES));
+ }
+
+ public void testRemoveHitsAndMisses() {
+ remoteCache.remove("a");
+ assertEquals((Integer)0, remoteCache.stats().getIntStatistic(ServerStatistics.REMOVE_HITS));
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.REMOVE_MISSES));
+ remoteCache.put("a","v");
+ remoteCache.remove("a");
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.REMOVE_HITS));
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.REMOVE_MISSES));
+ remoteCache.put("a","v");
+ remoteCache.put("b","v");
+ remoteCache.put("c","v");
+
+ remoteCache.remove("a");
+ remoteCache.remove("b");
+ remoteCache.remove("c");
+ assertEquals((Integer)4, remoteCache.stats().getIntStatistic(ServerStatistics.REMOVE_HITS));
+ assertEquals((Integer)1, remoteCache.stats().getIntStatistic(ServerStatistics.REMOVE_MISSES));
+ }
+
+ public void testNumberOfEntriesAfterClear() {
+ assertEquals((Integer)0, remoteCache.stats().getIntStatistic(ServerStatistics.CURRENT_NR_OF_ENTRIES));
+ remoteCache.put("k", "v");
+ remoteCache.put("k2", "v");
+ assertEquals((Integer)2, remoteCache.stats().getIntStatistic(ServerStatistics.CURRENT_NR_OF_ENTRIES));
+ remoteCache.clear();
+ assertEquals((Integer)0, remoteCache.stats().getIntStatistic(ServerStatistics.CURRENT_NR_OF_ENTRIES));
+ assertEquals((Integer)2, remoteCache.stats().getIntStatistic(ServerStatistics.TOTAL_NR_OF_ENTRIES));
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/PingOnStartupTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/PingOnStartupTest.java
new file mode 100644
index 000000000000..72a0bac1204d
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/PingOnStartupTest.java
@@ -0,0 +1,141 @@
+package org.infinispan.client.hotrod;
+
+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.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.TestingUtil;
+import org.testng.annotations.Test;
+
+import java.util.Properties;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.withRemoteCacheManager;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+
+/**
+ * Tests ping-on-startup logic whose objective is to retrieve the Hot Rod
+ * server topology before a client executes an operation against the server.
+ *
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(groups = "functional", testName = "client.hotrod.PingOnStartupTest")
+public class PingOnStartupTest extends MultiHotRodServersTest {
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ ConfigurationBuilder builder = hotRodCacheConfiguration(
+ getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false));
+ createHotRodServers(2, builder);
+ }
+
+ public void testTopologyFetched() {
+ Properties props = new Properties();
+ HotRodServer hotRodServer2 = server(1);
+ props.put("infinispan.client.hotrod.server_list",
+ "localhost:" + hotRodServer2.getPort() + ";localhost:" + hotRodServer2.getPort());
+ props.put("infinispan.client.hotrod.ping_on_startup", "true");
+
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() {
+ TcpTransportFactory tcpConnectionFactory = (TcpTransportFactory)
+ TestingUtil.extractField(rcm, "transportFactory");
+ for (int i = 0; i < 10; i++) {
+ if (tcpConnectionFactory.getServers().size() == 1) {
+ TestingUtil.sleepThread(1000);
+ } else {
+ break;
+ }
+ }
+ assertEquals(2, tcpConnectionFactory.getServers().size());
+ }
+ });
+ }
+
+ public void testTopologyNotFetched() {
+ 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", "false");
+
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() {
+ TcpTransportFactory tcpConnectionFactory = (TcpTransportFactory)
+ TestingUtil.extractField(rcm, "transportFactory");
+ assertEquals(1, tcpConnectionFactory.getServers().size());
+ }
+ });
+ }
+
+ public void testGetCacheWithPingOnStartupDisabledSingleNode() {
+ Properties props = new Properties();
+ props.put("infinispan.client.hotrod.server_list", "boomoo:12345");
+ props.put("infinispan.client.hotrod.ping_on_startup", "false");
+
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() {
+ rcm.getCache();
+ }
+ });
+ }
+
+ public void testGetCacheWithPingOnStartupDisabledMultipleNodes() {
+ 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", "false");
+
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() {
+ RemoteCache cache = rcm.getCache();
+ assertFalse(cache.containsKey("k"));
+ }
+ });
+ }
+
+ public void testGetCacheWorksIfNodeDown() {
+ 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");
+
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() {
+ rcm.getCache();
+ }
+ });
+ }
+
+ public void testGetCacheWorksIfNodeNotDown() {
+ 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");
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager(props)) {
+ @Override
+ public void call() {
+ rcm.getCache();
+ }
+ });
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteAsyncAPITest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteAsyncAPITest.java
new file mode 100644
index 000000000000..bc6f7241c73e
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteAsyncAPITest.java
@@ -0,0 +1,297 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.commons.util.concurrent.FutureListener;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.commons.util.concurrent.NotifyingFuture;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNotSame;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.Assert.assertNotEquals;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(groups = "functional", testName = "client.hotrod.RemoteAsyncAPITest")
+public class RemoteAsyncAPITest extends SingleCacheManagerTest {
+ private HotRodServer hotrodServer;
+ private RemoteCacheManager rcm;
+ private RemoteCache c;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ return TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration());
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ super.setup();
+ hotrodServer = TestHelper.startHotRodServer(cacheManager);
+ Properties props = new Properties();
+ props.put("infinispan.client.hotrod.server_list", "127.0.0.1:" + hotrodServer.getPort());
+ props.put("infinispan.client.hotrod.force_return_values","true");
+ props.put("testOnBorrow", "false");
+ rcm = new RemoteCacheManager(props);
+ c = rcm.getCache(true);
+ }
+
+ @AfterClass
+ @Override
+ protected void destroyAfterClass() {
+ super.destroyAfterClass();
+ killRemoteCacheManager(rcm);
+ killServers(hotrodServer);
+ }
+
+ public void testPutAsync() throws Exception {
+ // put
+ Future f = c.putAsync("k", "v");
+ testFuture(f, null);
+ testK("v");
+
+ f = c.putAsync("k", "v2");
+ testFuture(f, "v");
+ testK("v2");
+ }
+
+ public void testPutAsyncWithListener() throws Exception {
+ NotifyingFuture f = c.putAsync("k", "v");
+ testFutureWithListener(f, null);
+ testK("v");
+
+ f = c.putAsync("k", "v2");
+ testFutureWithListener(f, "v");
+ testK("v2");
+ }
+
+ public void testPutAllAsync() throws Exception {
+ Future f = c.putAllAsync(Collections.singletonMap("k", "v3"));
+ testFuture(f, null);
+ testK("v3");
+ }
+
+ public void testPutAllAsyncWithListener() throws Exception {
+ NotifyingFuture f = c.putAllAsync(Collections.singletonMap("k", "v3"));
+ testFutureWithListener(f, null);
+ testK("v3");
+ }
+
+ public void testPutIfAbsentAsync() throws Exception {
+ c.put("k", "v3");
+ testK("v3");
+
+ Future f = c.putIfAbsentAsync("k", "v4");
+ testFuture(f, "v3");
+ assertEquals("v3", c.remove("k"));
+
+ f = c.putIfAbsentAsync("k", "v5");
+ testFuture(f, null);
+ testK("v5");
+ }
+
+ public void testPutIfAbsentAsyncWithListener() throws Exception {
+ c.put("k", "v3");
+ testK("v3");
+
+ NotifyingFuture f = c.putIfAbsentAsync("k", "v4");
+ testFutureWithListener(f, "v3");
+ assertEquals("v3", c.remove("k"));
+
+ f = c.putIfAbsentAsync("k", "v5");
+ testFutureWithListener(f, null);
+ testK("v5");
+ }
+
+ public void testRemoveAsync() throws Exception {
+ c.put("k","v3");
+ testK("v3");
+
+ Future f = c.removeAsync("k");
+ testFuture(f, "v3");
+ testK(null);
+ }
+
+ public void testRemoveAsyncWithListener() throws Exception {
+ c.put("k","v3");
+ testK("v3");
+
+ NotifyingFuture f = c.removeAsync("k");
+ testFutureWithListener(f, "v3");
+ testK(null);
+ }
+
+ public void testGetAsync() throws Exception {
+ c.put("k", "v");
+ testK("v");
+
+ Future f = c.getAsync("k");
+ testFuture(f, "v");
+ testK("v");
+ }
+
+ public void testGetAsyncWithListener() throws Exception {
+ c.put("k", "v");
+ testK("v");
+
+ NotifyingFuture f = c.getAsync("k");
+ testFutureWithListener(f, "v");
+ }
+
+ public void testRemoveWithVersionAsync() throws Exception {
+ c.put("k","v4");
+ VersionedValue value = c.getVersioned("k");
+
+ Future f = c.removeWithVersionAsync("k", value.getVersion() + 1);
+ testFuture(f, false);
+ testK("v4");
+
+ f = c.removeWithVersionAsync("k", value.getVersion());
+ testFuture(f, true);
+ testK(null);
+ }
+
+ public void testRemoveWithVersionAsyncWithListener() throws Exception {
+ c.put("k","v4");
+ VersionedValue value = c.getVersioned("k");
+
+ NotifyingFuture f = c.removeWithVersionAsync("k", value.getVersion() + 1);
+ testFutureWithListener(f, false);
+ testK("v4");
+
+ f = c.removeWithVersionAsync("k", value.getVersion());
+ testFutureWithListener(f, true);
+ testK(null);
+ }
+
+ public void testReplaceAsync() throws Exception {
+ testK(null);
+ Future f = c.replaceAsync("k", "v5");
+ testFuture(f, null);
+ testK(null);
+
+ c.put("k", "v");
+ testK("v");
+ f = c.replaceAsync("k", "v5");
+ testFuture(f, "v");
+ testK("v5");
+ }
+
+ public void testReplaceAsyncWithListener() throws Exception {
+ testK(null);
+ NotifyingFuture f = c.replaceAsync("k", "v5");
+ testFutureWithListener(f, null);
+ testK(null);
+
+ c.put("k", "v");
+ testK("v");
+ f = c.replaceAsync("k", "v5");
+ testFutureWithListener(f, "v");
+ testK("v5");
+ }
+
+ public void testReplaceWithVersionAsync() throws Exception {
+ c.put("k", "v");
+ VersionedValue versioned1 = c.getVersioned("k");
+
+ Future f = c.replaceWithVersionAsync("k", "v2", versioned1.getVersion());
+ testFuture(f, true);
+
+ VersionedValue versioned2 = c.getVersioned("k");
+ assertNotEquals(versioned1.getVersion(), versioned2.getVersion());
+ assertEquals(versioned2.getValue(), "v2");
+
+ f = c.replaceWithVersionAsync("k", "v3", versioned1.getVersion());
+ testFuture(f, false);
+ testK("v2");
+ }
+
+ public void testReplaceWithVersionAsyncWithListener() throws Exception {
+ c.put("k", "v");
+ VersionedValue versioned1 = c.getVersioned("k");
+
+ NotifyingFuture f = c.replaceWithVersionAsync("k", "v2", versioned1.getVersion());
+ testFutureWithListener(f, true);
+
+ VersionedValue versioned2 = c.getVersioned("k");
+ assertNotEquals(versioned1.getVersion(), versioned2.getVersion());
+ assertEquals(versioned2.getValue(), "v2");
+
+ f = c.replaceWithVersionAsync("k", "v3", versioned1.getVersion());
+ testFutureWithListener(f, false);
+ testK("v2");
+ }
+
+ private void testK(T expected) {
+ assertEquals(expected, c.get("k"));
+ }
+
+ private void testFuture(Future f, T expected) throws ExecutionException, InterruptedException {
+ assertNotNull(f);
+ assertFalse(f.isCancelled());
+ T value = f.get();
+ assertEquals("Obtained " + value, expected, value);
+ assertTrue(f.isDone());
+ }
+
+ private void testFutureWithListener(NotifyingFuture f, T expected) throws InterruptedException {
+ assertNotNull(f);
+ AtomicReference ex = new AtomicReference();
+ CountDownLatch latch = new CountDownLatch(1);
+ f.attachListener(new TestingListener(expected, ex, latch));
+ if (!latch.await(5, TimeUnit.SECONDS)) {
+ fail("Not finished within 5 seconds");
+ }
+ if (ex.get() != null) {
+ throw new AssertionError(ex.get());
+ }
+ }
+
+ private static class TestingListener implements FutureListener {
+ private final T expected;
+ private final AtomicReference exception;
+ private final CountDownLatch latch;
+
+ private TestingListener(T expected, AtomicReference exception, CountDownLatch latch) {
+ this.expected = expected;
+ this.exception = exception;
+ this.latch = latch;
+ }
+
+ @Override
+ public void futureDone(Future future) {
+ try {
+ assertNotNull(future);
+ assertFalse(future.isCancelled());
+ assertTrue(future.isDone());
+ T value = future.get();
+ assertEquals("Obtained " + value, expected, value);
+ } catch (Throwable t) {
+ exception.set(t);
+ } finally {
+ latch.countDown();
+ }
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteCacheManagerTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteCacheManagerTest.java
new file mode 100644
index 000000000000..9cc5360e5aef
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RemoteCacheManagerTest.java
@@ -0,0 +1,140 @@
+package org.infinispan.client.hotrod;
+
+import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.assertFalse;
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.infinispan.client.hotrod.impl.ConfigurationProperties;
+import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.commons.marshall.jboss.GenericJBossMarshaller;
+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.Test;
+
+import java.net.URL;
+import java.util.Properties;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(testName = "client.hotrod.RemoteCacheManagerTest", groups = "functional" )
+public class RemoteCacheManagerTest extends SingleCacheManagerTest {
+
+ HotRodServer hotrodServer;
+ int port;
+ RemoteCacheManager remoteCacheManager;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ return TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration());
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ super.setup();
+ hotrodServer = TestHelper.startHotRodServer(cacheManager);
+ port = hotrodServer.getPort();
+ remoteCacheManager = null;
+ }
+
+ @AfterTest
+ public void release() {
+ try {
+ TestingUtil.killCacheManagers(cacheManager);
+ HotRodClientTestingUtil.killServers(hotrodServer);
+ HotRodClientTestingUtil.killRemoteCacheManager(remoteCacheManager);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void testNoArgConstructor() {
+ remoteCacheManager = new RemoteCacheManager();
+ assertTrue(remoteCacheManager.isStarted());
+ }
+
+ public void testBooleanConstructor() {
+ remoteCacheManager = new RemoteCacheManager(false);
+ assertFalse(remoteCacheManager.isStarted());
+ remoteCacheManager.start();
+ }
+
+ public void testConfigurationConstructor() {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder
+ .addServer()
+ .host("127.0.0.1")
+ .port(port);
+ remoteCacheManager = new RemoteCacheManager(builder.build());
+ assertTrue(remoteCacheManager.isStarted());
+ }
+
+ public void testUrlAndBooleanConstructor() throws Exception {
+ URL resource = Thread.currentThread().getContextClassLoader().getResource("empty-config.properties");
+ assert resource != null;
+ remoteCacheManager = new RemoteCacheManager(resource, false);
+ assert !remoteCacheManager.isStarted();
+ Properties properties = remoteCacheManager.getProperties();
+ properties.setProperty(ConfigurationProperties.SERVER_LIST, "127.0.0.1:" + port);
+ remoteCacheManager = new RemoteCacheManager(properties, false);
+ assert !remoteCacheManager.isStarted();
+ remoteCacheManager.start();
+ assertWorks(remoteCacheManager);
+ }
+
+ public void testPropertiesConstructor() {
+ Properties p = new Properties();
+ p.setProperty(ConfigurationProperties.SERVER_LIST, "127.0.0.1:" + port);
+ remoteCacheManager = new RemoteCacheManager(p);
+ assert remoteCacheManager.isStarted();
+ assertWorks(remoteCacheManager);
+ remoteCacheManager.stop();
+ }
+
+ public void testPropertiesAndBooleanConstructor() {
+ Properties p = new Properties();
+ p.setProperty(ConfigurationProperties.SERVER_LIST, "127.0.0.1:" + port);
+ remoteCacheManager = new RemoteCacheManager(p, false);
+ assert !remoteCacheManager.isStarted();
+ remoteCacheManager.start();
+ assertWorks(remoteCacheManager);
+ }
+
+ public void testStringAndBooleanConstructor() {
+ remoteCacheManager = new RemoteCacheManager("localhost:"+hotrodServer.getPort(), false);
+ assert !remoteCacheManager.isStarted();
+ remoteCacheManager.start();
+ assertWorks(remoteCacheManager);
+ }
+
+ public void testGetUndefinedCache() {
+ Properties p = new Properties();
+ p.setProperty(ConfigurationProperties.SERVER_LIST, "127.0.0.1:" + port);
+ remoteCacheManager = new RemoteCacheManager(p, false);
+ assert !remoteCacheManager.isStarted();
+ remoteCacheManager.start();
+ assert null == remoteCacheManager.getCache("Undefined1234");
+ }
+
+ private void assertWorks(RemoteCacheManager remoteCacheManager) {
+ RemoteCache cache = remoteCacheManager.getCache();
+ cache.put("aKey", "aValue");
+ assert cache.get("aKey").equals("aValue");
+ }
+
+ public void testMarshallerInstance() {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.addServer().host("127.0.0.1").port(port);
+ GenericJBossMarshaller marshaller = new GenericJBossMarshaller();
+ builder.marshaller(marshaller);
+ remoteCacheManager = new RemoteCacheManager(builder.build());
+ assertTrue(marshaller == remoteCacheManager.getMarshaller());
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ReplTopologyChangeTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ReplTopologyChangeTest.java
new file mode 100644
index 000000000000..ea8dc9a3fce0
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ReplTopologyChangeTest.java
@@ -0,0 +1,147 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.manager.CacheContainer;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Collection;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.assertEquals;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(testName = "client.hotrod.ReplTopologyChangeTest", groups = "functional")
+public class ReplTopologyChangeTest extends MultipleCacheManagersTest {
+
+ HotRodServer hotRodServer1;
+ HotRodServer hotRodServer2;
+ HotRodServer hotRodServer3 ;
+
+ RemoteCache remoteCache;
+ private RemoteCacheManager remoteCacheManager;
+ private TcpTransportFactory tcpConnectionFactory;
+ private ConfigurationBuilder config;
+
+ @Override
+ protected void assertSupportedConfig() {
+ }
+
+ @AfterMethod
+ @Override
+ protected void clearContent() throws Throwable {
+ }
+
+ @AfterClass
+ @Override
+ protected void destroy() {
+ super.destroy();
+ killServers(hotRodServer1, hotRodServer2);
+ killRemoteCacheManager(remoteCacheManager);
+ }
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ config = hotRodCacheConfiguration(getDefaultClusteredCacheConfig(getCacheMode(), false));
+ CacheContainer cm1 = TestCacheManagerFactory.createClusteredCacheManager(config);
+ CacheContainer cm2 = TestCacheManagerFactory.createClusteredCacheManager(config);
+ registerCacheManager(cm1);
+ registerCacheManager(cm2);
+ waitForClusterToForm();
+ }
+
+ @BeforeClass
+ @Override
+ public void createBeforeClass() throws Throwable {
+ super.createBeforeClass(); // Create cache managers
+ hotRodServer1 = TestHelper.startHotRodServer(manager(0));
+ hotRodServer2 = TestHelper.startHotRodServer(manager(1));
+
+ //Important: this only connects to one of the two servers!
+ remoteCacheManager = new RemoteCacheManager("localhost", hotRodServer2.getPort());
+ remoteCache = remoteCacheManager.getCache();
+
+ tcpConnectionFactory = (TcpTransportFactory) TestingUtil.extractField(remoteCacheManager, "transportFactory");
+ }
+
+ protected CacheMode getCacheMode() {
+ return CacheMode.REPL_SYNC;
+ }
+
+ public void testTwoMembers() {
+ InetSocketAddress server1Address = new InetSocketAddress("localhost", hotRodServer1.getPort());
+ expectTopologyChange(server1Address, true);
+ assertEquals(2, tcpConnectionFactory.getServers().size());
+ }
+
+ @Test(dependsOnMethods = "testTwoMembers")
+ public void testAddNewServer() {
+ CacheContainer cm3 = TestCacheManagerFactory.createClusteredCacheManager(config);
+ registerCacheManager(cm3);
+ hotRodServer3 = TestHelper.startHotRodServer(manager(2));
+ manager(2).getCache();
+
+ waitForClusterToForm();
+
+ try {
+ expectTopologyChange(new InetSocketAddress("localhost", hotRodServer3.getPort()), true);
+ assertEquals(3, tcpConnectionFactory.getServers().size());
+ } finally {
+ log.info("Members are: " + manager(0).getCache().getAdvancedCache().getRpcManager().getTransport().getMembers());
+ log.info("Members are: " + manager(1).getCache().getAdvancedCache().getRpcManager().getTransport().getMembers());
+ log.info("Members are: " + manager(2).getCache().getAdvancedCache().getRpcManager().getTransport().getMembers());
+ }
+ }
+
+ @Test(dependsOnMethods = "testAddNewServer")
+ public void testDropServer() {
+ hotRodServer3.stop();
+ manager(2).stop();
+ log.trace("Just stopped server 2");
+
+ waitForServerToDie(2);
+
+ InetSocketAddress server3Address = new InetSocketAddress("localhost", hotRodServer3.getPort());
+
+ try {
+ expectTopologyChange(server3Address, false);
+ assertEquals(2, tcpConnectionFactory.getServers().size());
+ } finally {
+ log.info("Members are: " + manager(0).getCache().getAdvancedCache().getRpcManager().getTransport().getMembers());
+ log.info("Members are: " + manager(1).getCache().getAdvancedCache().getRpcManager().getTransport().getMembers());
+ if (manager(2).getStatus() != ComponentStatus.RUNNING)
+ log.info("Members are: 0");
+ else
+ log.info("Members are: " + manager(2).getCache().getAdvancedCache().getRpcManager().getTransport().getMembers());
+ }
+ }
+
+ private void expectTopologyChange(InetSocketAddress server1Address, boolean added) {
+ for (int i = 0; i < 10; i++) {
+ remoteCache.put("k" + i, "v" + i);
+ if (added == tcpConnectionFactory.getServers().contains(server1Address)) break;
+ }
+ Collection addresses = tcpConnectionFactory.getServers();
+ assertEquals(server1Address + " not found in " + addresses, added, addresses.contains(server1Address));
+ }
+
+ protected void waitForServerToDie(int memberCount) {
+ TestingUtil.blockUntilViewReceived(manager(0).getCache(), memberCount, 30000, false);
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RoundRobinBalancingIntegrationTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RoundRobinBalancingIntegrationTest.java
new file mode 100644
index 000000000000..aa1d80372923
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RoundRobinBalancingIntegrationTest.java
@@ -0,0 +1,225 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.Cache;
+import org.infinispan.client.hotrod.impl.transport.tcp.RoundRobinBalancingStrategy;
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.Test;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.assertEquals;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(testName = "client.hotrod.RoundRobinBalancingIntegrationTest", groups="functional")
+public class RoundRobinBalancingIntegrationTest extends MultipleCacheManagersTest {
+
+ private static final Log log = LogFactory.getLog(RoundRobinBalancingIntegrationTest.class);
+
+ Cache c1;
+ Cache c2;
+ Cache c3;
+ Cache c4;
+
+ HotRodServer hotRodServer1;
+ HotRodServer hotRodServer2;
+
+ HotRodServer hotRodServer3;
+ HotRodServer hotRodServer4;
+
+ RemoteCache remoteCache;
+
+ private RemoteCacheManager remoteCacheManager;
+
+ @Override
+ protected void assertSupportedConfig() {
+ return;
+ }
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ c1 = TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration()).getCache();
+ c2 = TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration()).getCache();
+ c3 = TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration()).getCache();
+ registerCacheManager(c1.getCacheManager(), c2.getCacheManager(), c3.getCacheManager());
+
+ hotRodServer1 = TestHelper.startHotRodServer(c1.getCacheManager());
+ hotRodServer2 = TestHelper.startHotRodServer(c2.getCacheManager());
+ hotRodServer3 = TestHelper.startHotRodServer(c3.getCacheManager());
+
+ log.trace("Server 1 port: " + hotRodServer1.getPort());
+ log.trace("Server 2 port: " + hotRodServer2.getPort());
+ log.trace("Server 3 port: " + hotRodServer3.getPort());
+ String servers = TestHelper.getServersString(hotRodServer1, hotRodServer2, hotRodServer3);
+ log.trace("Server list is: " + servers);
+ remoteCacheManager = new RemoteCacheManager(servers);
+ remoteCache = remoteCacheManager.getCache();
+ }
+
+ @AfterTest
+ public void tearDown() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotRodServer1, hotRodServer2, hotRodServer3, hotRodServer4);
+ }
+
+ public void testRoundRobinLoadBalancing() {
+ remoteCache.put("k1", "v1");
+ remoteCache.put("k2", "v2");
+ remoteCache.put("k3", "v3");
+
+ assertEquals(1, c1.size());
+ assertEquals(1, c2.size());
+ assertEquals(1, c3.size());
+
+ assertEquals("v1", remoteCache.get("k1"));
+ assertEquals("v2", remoteCache.get("k2"));
+ assertEquals("v3", remoteCache.get("k3"));
+
+ remoteCache.put("k4", "v1");
+ remoteCache.put("k5", "v2");
+ remoteCache.put("k6", "v3");
+ remoteCache.put("k7", "v1");
+ remoteCache.put("k8", "v2");
+ remoteCache.put("k9", "v3");
+
+ assertEquals(3, c1.size());
+ assertEquals(3, c2.size());
+ assertEquals(3, c3.size());
+ }
+
+ @Test(dependsOnMethods = "testRoundRobinLoadBalancing")
+ public void testAddNewHotrodServer() {
+ c4 = TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration()).getCache();
+ hotRodServer4 = TestHelper.startHotRodServer(c4.getCacheManager());
+ registerCacheManager(c4.getCacheManager());
+
+ List serverAddresses = new ArrayList();
+ serverAddresses.add(new InetSocketAddress("localhost", hotRodServer1.getPort()));
+ serverAddresses.add(new InetSocketAddress("localhost", hotRodServer2.getPort()));
+ serverAddresses.add(new InetSocketAddress("localhost", hotRodServer3.getPort()));
+ serverAddresses.add(new InetSocketAddress("localhost", hotRodServer4.getPort()));
+
+ RoundRobinBalancingStrategy balancer = getBalancer();
+ balancer.setServers(serverAddresses);
+
+ remoteCache.put("k1", "v1");
+ remoteCache.put("k2", "v2");
+ remoteCache.put("k3", "v3");
+ remoteCache.put("k4", "v4");
+
+ assertEquals(1, c1.size());
+ assertEquals(1, c2.size());
+ assertEquals(1, c3.size());
+ assertEquals(1, c4.size());
+
+ assertEquals("v1", remoteCache.get("k1"));
+ assertEquals("v2", remoteCache.get("k2"));
+ assertEquals("v3", remoteCache.get("k3"));
+ assertEquals("v4", remoteCache.get("k4"));
+
+ remoteCache.put("k5", "v2");
+ remoteCache.put("k6", "v3");
+ remoteCache.put("k7", "v1");
+ remoteCache.put("k8", "v2");
+ remoteCache.put("k9", "v3");
+ remoteCache.put("k10", "v3");
+ remoteCache.put("k11", "v3");
+ remoteCache.put("k12", "v3");
+
+ assertEquals(3, c1.size());
+ assertEquals(3, c2.size());
+ assertEquals(3, c3.size());
+ assertEquals(3, c4.size());
+ }
+
+ @Test(dependsOnMethods = "testAddNewHotrodServer")
+ public void testStopServer() {
+ remoteCache.put("k1", "v1");
+ remoteCache.put("k2", "v2");
+ remoteCache.put("k3", "v3");
+ remoteCache.put("k4", "v4");
+
+ assertEquals(1, c1.size());
+ assertEquals(1, c2.size());
+ assertEquals(1, c3.size());
+ assertEquals(1, c4.size());
+
+ assertEquals("v1", remoteCache.get("k1"));
+ assertEquals("v2", remoteCache.get("k2"));
+ assertEquals("v3", remoteCache.get("k3"));
+ assertEquals("v4", remoteCache.get("k4"));
+
+ hotRodServer4.stop();
+
+ try {
+ remoteCache.put("k5", "v1");
+ remoteCache.put("k6", "v2");
+ remoteCache.put("k7", "v3");
+ remoteCache.put("k8", "v4");
+ } catch (Exception e) {
+ assert false : "exception should not happen even if the balancer redirects to failed node at the beggining";
+ }
+ }
+
+ @Test(dependsOnMethods = "testStopServer")
+ public void testRemoveServers() {
+ List serverAddresses = new ArrayList();
+ serverAddresses.add(new InetSocketAddress("localhost", hotRodServer1.getPort()));
+ serverAddresses.add(new InetSocketAddress("localhost", hotRodServer2.getPort()));
+
+ RoundRobinBalancingStrategy balancer = getBalancer();
+ balancer.setServers(serverAddresses);
+
+ remoteCache.put("k1", "v1");
+ remoteCache.put("k2", "v2");
+ remoteCache.put("k3", "v3");
+ remoteCache.put("k4", "v4");
+
+ assertEquals(2, c1.size());
+ assertEquals(2, c2.size());
+ assertEquals(0, c3.size());
+ assertEquals(0, c4.size());
+
+ assertEquals("v1", remoteCache.get("k1"));
+ assertEquals("v2", remoteCache.get("k2"));
+ assertEquals("v3", remoteCache.get("k3"));
+ assertEquals("v4", remoteCache.get("k4"));
+
+ remoteCache.put("k5", "v2");
+ remoteCache.put("k6", "v3");
+ remoteCache.put("k7", "v1");
+ remoteCache.put("k8", "v2");
+ remoteCache.put("k9", "v3");
+ remoteCache.put("k10", "v3");
+ remoteCache.put("k11", "v3");
+ remoteCache.put("k12", "v3");
+
+ assertEquals(6, c1.size());
+ assertEquals(6, c2.size());
+ assertEquals(0, c3.size());
+ assertEquals(0, c4.size());
+
+ }
+
+ private RoundRobinBalancingStrategy getBalancer() {
+ TcpTransportFactory transportFactory = (TcpTransportFactory) TestingUtil.extractField(remoteCache.getRemoteCacheManager(), "transportFactory");
+ return (RoundRobinBalancingStrategy) TestingUtil.extractField(transportFactory, "balancer");
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RoundRobinBalancingStrategyTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RoundRobinBalancingStrategyTest.java
new file mode 100644
index 000000000000..271cd6aac653
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/RoundRobinBalancingStrategyTest.java
@@ -0,0 +1,155 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.impl.transport.tcp.RoundRobinBalancingStrategy;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertNotSame;
+import static org.testng.AssertJUnit.assertTrue;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test (groups = "unit", testName = "client.hotrod.RoundRobinBalancingStrategyTest")
+public class RoundRobinBalancingStrategyTest {
+
+
+ SocketAddress addr1 = new InetSocketAddress("localhost",1111);
+ SocketAddress addr2 = new InetSocketAddress("localhost",2222);
+ SocketAddress addr3 = new InetSocketAddress("localhost",3333);
+ SocketAddress addr4 = new InetSocketAddress("localhost",4444);
+ private List defaultServers;
+ private RoundRobinBalancingStrategy strategy;
+
+ @BeforeMethod
+ public void setUp() {
+ strategy = new RoundRobinBalancingStrategy();
+ defaultServers = new ArrayList();
+ defaultServers.add(addr1);
+ defaultServers.add(addr2);
+ defaultServers.add(addr3);
+ strategy.setServers(defaultServers);
+ }
+
+ public void simpleTest() {
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ }
+
+ public void testAddServer() {
+ List newServers = new ArrayList(defaultServers);
+ newServers.add(addr4);
+ strategy.setServers(newServers);
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr4, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr4, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ }
+
+ public void testRemoveServer() {
+ List newServers = new ArrayList(defaultServers);
+ newServers.remove(addr3);
+ strategy.setServers(newServers);
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ }
+
+ public void testRemoveServerAfterActivity() {
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ List newServers = new ArrayList(defaultServers);
+ newServers.remove(addr3);
+ strategy.setServers(newServers);
+ // the next server index is reset to 0 because it would have been out of bounds
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ }
+
+ public void testAddServerAfterActivity() {
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ List newServers = new ArrayList(defaultServers);
+ newServers.add(addr4);
+ strategy.setServers(newServers);
+ // the next server index is still valid, so it is not reset
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr4, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr4, strategy.nextServer(null));
+ assertEquals(addr1, strategy.nextServer(null));
+ assertEquals(addr2, strategy.nextServer(null));
+ assertEquals(addr3, strategy.nextServer(null));
+ assertEquals(addr4, strategy.nextServer(null));
+ }
+
+ public void testFailedServers1() {
+ strategy.setServers(defaultServers);
+ Set failedServers = Collections.singleton(addr1);
+ // other servers should be available
+ final int LOOPS = 10;
+ int c1 = 0, c2 = 0;
+ for (int i = 0; i < LOOPS; ++i) {
+ SocketAddress server = strategy.nextServer(failedServers);
+ assertNotNull(server);
+ assertNotSame(addr1, server);
+ if (server.equals(addr2)) {
+ c1++;
+ } else if (server.equals(addr3)) {
+ c2++;
+ }
+ }
+ assertEquals(LOOPS, c1 + c2);
+ assertTrue(Math.abs(c1 - c2) <= 1);
+ }
+
+ public void testFailedServers2() {
+ strategy.setServers(defaultServers);
+ Set failedServers = new HashSet(defaultServers);
+ // with all servers failed, the behaviour should be the same
+ assertEquals(addr1, strategy.nextServer(failedServers));
+ assertEquals(addr2, strategy.nextServer(failedServers));
+ assertEquals(addr3, strategy.nextServer(failedServers));
+ assertEquals(addr1, strategy.nextServer(failedServers));
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerErrorTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerErrorTest.java
new file mode 100644
index 000000000000..4d0c6cf4b9e0
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerErrorTest.java
@@ -0,0 +1,94 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.exceptions.HotRodClientException;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
+import org.infinispan.notifications.cachelistener.event.CacheEntryEvent;
+import org.infinispan.remoting.transport.jgroups.SuspectException;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.*;
+import static org.infinispan.test.TestingUtil.k;
+import static org.infinispan.test.TestingUtil.v;
+
+/**
+ * Tests HotRod client and server behaivour when server throws a server error
+ *
+ * @author Galder Zamarreño
+ * @since 4.2
+ */
+@Test(groups = "functional", testName = "client.hotrod.ServerErrorTest")
+public class ServerErrorTest extends SingleCacheManagerTest {
+
+ private HotRodServer hotrodServer;
+ private RemoteCacheManager remoteCacheManager;
+ private RemoteCache remoteCache;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ cacheManager = TestCacheManagerFactory
+ .createCacheManager(hotRodCacheConfiguration());
+ hotrodServer = TestHelper.startHotRodServer(cacheManager);
+
+ remoteCacheManager = getRemoteCacheManager();
+ remoteCache = remoteCacheManager.getCache();
+
+ return cacheManager;
+ }
+
+ protected RemoteCacheManager getRemoteCacheManager() {
+ Properties config = new Properties();
+ config.put("infinispan.client.hotrod.server_list", "127.0.0.1:" + hotrodServer.getPort());
+ return new RemoteCacheManager(config);
+ }
+
+ @AfterClass
+ public void shutDownHotrod() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotrodServer);
+ }
+
+ public void testErrorWhileDoingPut(Method m) throws Exception {
+ cache.addListener(new ErrorInducingListener());
+ remoteCache = remoteCacheManager.getCache();
+
+ remoteCache.put(k(m), v(m));
+ assert remoteCache.get(k(m)).equals(v(m));
+
+ try {
+ remoteCache.put("FailFailFail", "whatever...");
+ } catch (HotRodClientException e) {
+ // ignore
+ }
+
+ try {
+ remoteCache.put(k(m, 2), v(m, 2));
+ assert remoteCache.get(k(m, 2)).equals(v(m, 2));
+ } catch (Exception e) {
+ log.error("Error sending request after server failure", e);
+ throw e;
+ }
+
+ }
+
+ @Listener
+ public static class ErrorInducingListener {
+ @CacheEntryCreated
+ @SuppressWarnings("unused")
+ public void entryCreated(CacheEntryEvent event) throws Exception {
+ if (event.isPre() && unmarshall(event.getKey()) == "FailFailFail") {
+ throw new SuspectException("Simulated suspicion");
+ }
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerRestartTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerRestartTest.java
new file mode 100644
index 000000000000..2450d56f7df9
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerRestartTest.java
@@ -0,0 +1,72 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.server.hotrod.configuration.HotRodServerConfigurationBuilder;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(testName = "client.hotrod.ServerRestartTest", groups = "functional")
+public class ServerRestartTest extends SingleCacheManagerTest {
+
+ private static final Log log = LogFactory.getLog(HotRodIntegrationTest.class);
+
+ private RemoteCache defaultRemote;
+ private RemoteCacheManager remoteCacheManager;
+
+ protected HotRodServer hotrodServer;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ return TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration());
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ super.setup();
+ hotrodServer = TestHelper.startHotRodServer(cacheManager);
+ log.info("Started server on port: " + hotrodServer.getPort());
+
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.addServer().host("127.0.0.1").port(hotrodServer.getPort()).connectionPool().timeBetweenEvictionRuns(2000);
+ remoteCacheManager = new RemoteCacheManager(builder.build());
+ defaultRemote = remoteCacheManager.getCache();
+ }
+
+ @AfterClass
+ public void testDestroyRemoteCacheFactory() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotrodServer);
+ }
+
+ public void testServerShutdown() throws Exception {
+ defaultRemote.put("k","v");
+ assert defaultRemote.get("k").equals("v");
+
+ int port = hotrodServer.getPort();
+ hotrodServer.stop();
+
+ HotRodServerConfigurationBuilder builder = new HotRodServerConfigurationBuilder();
+ builder.host("127.0.0.1").port(port).workerThreads(2).idleTimeout(20000).tcpNoDelay(true).sendBufSize(15000).recvBufSize(25000);
+ hotrodServer.start(builder.build(), cacheManager);
+
+ Thread.sleep(3000);
+
+ assert defaultRemote.get("k").equals("v");
+ defaultRemote.put("k","v");
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerShutdownTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerShutdownTest.java
new file mode 100644
index 000000000000..c9890362edb8
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/ServerShutdownTest.java
@@ -0,0 +1,70 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.test.RemoteCacheManagerCallable;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.CacheManagerCallable;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.withRemoteCacheManager;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.infinispan.test.TestingUtil.withCacheManager;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(testName = "client.hotrod.ServerShutdownTest", groups = "functional")
+public class ServerShutdownTest {
+
+ public void testServerShutdownWithConnectedClient() {
+ withCacheManager(new CacheManagerCallable(
+ TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration())) {
+ @Override
+ public void call() {
+ HotRodServer hotrodServer = TestHelper.startHotRodServer(cm);
+ try {
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager("localhost", hotrodServer.getPort())) {
+ @Override
+ public void call() {
+ RemoteCache remoteCache = rcm.getCache();
+ remoteCache.put("k","v");
+ assertEquals("v", remoteCache.get("k"));
+ }
+ });
+ } finally {
+ killServers(hotrodServer);
+ }
+ }
+ });
+ }
+
+ public void testServerShutdownWithoutConnectedClient() {
+ withCacheManager(new CacheManagerCallable(
+ TestCacheManagerFactory.createCacheManager(
+ hotRodCacheConfiguration())) {
+ @Override
+ public void call() {
+ HotRodServer hotrodServer = TestHelper.startHotRodServer(cm);
+ try {
+ withRemoteCacheManager(new RemoteCacheManagerCallable(
+ new RemoteCacheManager("localhost", hotrodServer.getPort())) {
+ @Override
+ public void call() {
+ RemoteCache remoteCache = rcm.getCache();
+ remoteCache.put("k","v");
+ assertEquals("v", remoteCache.get("k"));
+ }
+ });
+ } finally {
+ killServers(hotrodServer);
+ }
+ }
+ });
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SocketTimeoutErrorTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SocketTimeoutErrorTest.java
new file mode 100644
index 000000000000..5e6e741d5bdd
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SocketTimeoutErrorTest.java
@@ -0,0 +1,111 @@
+package org.infinispan.client.hotrod;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.test.TestingUtil.*;
+
+import java.lang.reflect.Method;
+import java.net.SocketTimeoutException;
+import java.util.Properties;
+
+import org.infinispan.client.hotrod.exceptions.HotRodClientException;
+import org.infinispan.client.hotrod.impl.ConfigurationProperties;
+import org.infinispan.commands.write.PutKeyValueCommand;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.context.InvocationContext;
+import org.infinispan.interceptors.EntryWrappingInterceptor;
+import org.infinispan.interceptors.base.CommandInterceptor;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.commons.marshall.Marshaller;
+import org.infinispan.marshall.core.JBossMarshaller;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+/**
+ * Tests the behaviour of the client upon a socket timeout exception
+ * and any invocation after that.
+ *
+ * @author Galder Zamarreño
+ * @since 4.2
+ */
+@Test(groups = "functional", testName = "client.hotrod.SocketTimeoutErrorTest")
+public class SocketTimeoutErrorTest extends SingleCacheManagerTest {
+
+ protected HotRodServer hotrodServer;
+ protected RemoteCacheManager remoteCacheManager;
+ protected RemoteCache remoteCache;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.customInterceptors().addInterceptor().interceptor(
+ new TimeoutInducingInterceptor()).after(EntryWrappingInterceptor.class);
+ return TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration(builder));
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ super.setup();
+ hotrodServer = TestHelper.startHotRodServer(cacheManager);
+ remoteCacheManager = new RemoteCacheManager(getClientProperties());
+ remoteCache = remoteCacheManager.getCache();
+ }
+
+ @Override
+ protected void teardown() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotrodServer);
+ super.teardown();
+ }
+
+ protected Properties getClientProperties() {
+ Properties props = new Properties();
+ props.put("infinispan.client.hotrod.server_list", "127.0.0.1:" + hotrodServer.getPort());
+ props.setProperty(ConfigurationProperties.SO_TIMEOUT, "3000");
+ props.setProperty("maxActive", "1");
+ props.setProperty("maxTotal", "1");
+ props.setProperty("maxIdle", "1");
+ return props;
+ }
+
+ public void testErrorWhileDoingPut(Method m) throws Exception {
+ remoteCache = remoteCacheManager.getCache();
+
+ remoteCache.put(k(m), v(m));
+ assert remoteCache.get(k(m)).equals(v(m));
+
+ try {
+ remoteCache.put("FailFailFail", "whatever...");
+ Assert.fail("No exception was thrown.");
+ } catch (HotRodClientException e) {
+ // ignore
+ assert e.getCause() instanceof SocketTimeoutException;
+ }
+
+ // What counts is that socket timeout exception kicks in, operations
+ // after that do not add anything to the socket timeout test
+ }
+
+ public static class TimeoutInducingInterceptor extends CommandInterceptor {
+
+ @Override
+ public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable {
+ if (unmarshall(command.getKey()).equals("FailFailFail")) {
+ Thread.sleep(6000);
+ }
+
+ return super.visitPutKeyValueCommand(ctx, command);
+ }
+
+ private String unmarshall(Object key) throws Exception {
+ Marshaller marshaller = new JBossMarshaller();
+ return (String) marshaller.objectFromByteBuffer((byte[]) key);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeAsyncExecutorFactory.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeAsyncExecutorFactory.java
new file mode 100644
index 000000000000..64c7a14324ba
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeAsyncExecutorFactory.java
@@ -0,0 +1,7 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.impl.async.DefaultAsyncExecutorFactory;
+
+public class SomeAsyncExecutorFactory extends DefaultAsyncExecutorFactory {
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeCustomConsistentHashV1.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeCustomConsistentHashV1.java
new file mode 100644
index 000000000000..e052a85189c0
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeCustomConsistentHashV1.java
@@ -0,0 +1,7 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.impl.consistenthash.ConsistentHashV1;
+
+public class SomeCustomConsistentHashV1 extends ConsistentHashV1 {
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeRequestBalancingStrategy.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeRequestBalancingStrategy.java
new file mode 100644
index 000000000000..72f94ecd9984
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeRequestBalancingStrategy.java
@@ -0,0 +1,7 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.impl.transport.tcp.RoundRobinBalancingStrategy;
+
+public class SomeRequestBalancingStrategy extends RoundRobinBalancingStrategy {
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeTransportfactory.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeTransportfactory.java
new file mode 100644
index 000000000000..450f4b32868d
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SomeTransportfactory.java
@@ -0,0 +1,7 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory;
+
+public class SomeTransportfactory extends TcpTransportFactory {
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SslTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SslTest.java
new file mode 100644
index 000000000000..c8984023f57f
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/SslTest.java
@@ -0,0 +1,110 @@
+package org.infinispan.client.hotrod;
+
+import java.net.SocketTimeoutException;
+
+import javax.net.ssl.SSLException;
+
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.infinispan.client.hotrod.exceptions.TransportException;
+import org.infinispan.client.hotrod.test.HotRodClientTestingUtil;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.server.hotrod.configuration.HotRodServerConfigurationBuilder;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
+
+/**
+ * @author Adrian Brock
+ * @author Tristan Tarrant
+ * @since 5.3
+ */
+@Test(testName = "client.hotrod.SslTest", groups = "functional")
+public class SslTest extends SingleCacheManagerTest {
+
+ private static final Log log = LogFactory.getLog(SslTest.class);
+
+ RemoteCache defaultRemote;
+ private RemoteCacheManager remoteCacheManager;
+
+ protected HotRodServer hotrodServer;
+
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ cacheManager = TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration());
+ cacheManager.getCache();
+
+ return cacheManager;
+ }
+
+ private void initServerAndClient(boolean sslServer, boolean sslClient) {
+ hotrodServer = new HotRodServer();
+ HotRodServerConfigurationBuilder serverBuilder = new HotRodServerConfigurationBuilder();
+
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ String keyStoreFileName = tccl.getResource("keystore.jks").getPath();
+ String trustStoreFileName = tccl.getResource("truststore.jks").getPath();
+ serverBuilder.ssl()
+ .enabled(sslServer)
+ .keyStoreFileName(keyStoreFileName)
+ .keyStorePassword("secret".toCharArray())
+ .trustStoreFileName(trustStoreFileName)
+ .trustStorePassword("secret".toCharArray());
+ hotrodServer.start(serverBuilder.build(), cacheManager);
+ log.info("Started server on port: " + hotrodServer.getPort());
+
+ ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
+ clientBuilder
+ .addServer()
+ .host("127.0.0.1")
+ .port(hotrodServer.getPort())
+ .socketTimeout(3000)
+ .connectionPool()
+ .maxActive(1)
+ .ssl()
+ .enabled(sslClient)
+ .keyStoreFileName(keyStoreFileName)
+ .keyStorePassword("secret".toCharArray())
+ .trustStoreFileName(trustStoreFileName)
+ .trustStorePassword("secret".toCharArray())
+ .connectionPool()
+ .timeBetweenEvictionRuns(2000);
+ remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
+ defaultRemote = remoteCacheManager.getCache();
+ }
+
+ @AfterMethod
+ public void testDestroyRemoteCacheFactory() {
+ HotRodClientTestingUtil.killRemoteCacheManager(remoteCacheManager);
+ HotRodClientTestingUtil.killServers(hotrodServer);
+ }
+
+ public void testSSLServerSSLClient() throws Exception {
+ initServerAndClient(true, true);
+ defaultRemote.put("k","v");
+ assert defaultRemote.get("k").equals("v");
+ }
+
+ @Test(expectedExceptions = TransportException.class)
+ public void testSSLServerPlainClient() throws Exception {
+ // The server just disconnect the client
+ initServerAndClient(true, false);
+ }
+
+ public void testPlainServerSSLClient() throws Exception {
+ try {
+ initServerAndClient(false, true);
+ fail("Expecting a SSLException");
+ } catch (TransportException e) {
+ assertTrue(e.getCause() instanceof SSLException);
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/TestHelper.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/TestHelper.java
new file mode 100644
index 000000000000..3f63d0e1d164
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/TestHelper.java
@@ -0,0 +1,68 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.server.hotrod.test.HotRodTestingUtil;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import io.netty.channel.ChannelException;
+
+import java.net.BindException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+public class TestHelper {
+
+ private static final Log log = LogFactory.getLog(TestHelper.class);
+
+ /**
+ * This needs to be different than the one used in the server tests in order to make sure that there's no clash.
+ */
+ private static final AtomicInteger uniquePort = new AtomicInteger(15232);
+
+ public static HotRodServer startHotRodServer(EmbeddedCacheManager cacheManager) {
+ // TODO: This is very rudimentary!! HotRodTestingUtil needs a more robust solution where ports are generated randomly and retries if already bound
+ HotRodServer server = null;
+ int maxTries = 10;
+ int currentTries = 0;
+ ChannelException lastException = null;
+ while (server == null && currentTries < maxTries) {
+ try {
+ server = HotRodTestingUtil.startHotRodServer(cacheManager, uniquePort.incrementAndGet());
+ } catch (ChannelException e) {
+ if (!(e.getCause() instanceof BindException)) {
+ throw e;
+ } else {
+ log.debug("Address already in use: [" + e.getMessage() + "], so let's try next port");
+ currentTries++;
+ lastException = e;
+ }
+ }
+ }
+ if (server == null && lastException != null)
+ throw lastException;
+
+ return server;
+ }
+
+ public static String getServersString(HotRodServer... servers) {
+ StringBuilder builder = new StringBuilder();
+ for (HotRodServer server : servers) {
+ builder.append("localhost").append(':').append(server.getPort()).append(";");
+ }
+ return builder.toString();
+ }
+
+ public static RemoteCacheManager getRemoteCacheManager(HotRodServer server) {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.addServer()
+ .host(server.getHost())
+ .port(server.getPort());
+ return new RemoteCacheManager(builder.build());
+
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/TransportObjectFactoryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/TransportObjectFactoryTest.java
new file mode 100644
index 000000000000..51206d451e39
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/TransportObjectFactoryTest.java
@@ -0,0 +1,36 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.client.hotrod.exceptions.TransportException;
+import org.infinispan.client.hotrod.impl.protocol.Codec;
+import org.infinispan.client.hotrod.impl.protocol.HeaderParams;
+import org.infinispan.client.hotrod.impl.transport.Transport;
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransport;
+import org.infinispan.client.hotrod.impl.transport.tcp.TransportObjectFactory;
+import org.testng.annotations.Test;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.testng.AssertJUnit.assertFalse;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+/**
+ * @author Mircea Markus
+ * @since 6.0
+ */
+@Test (groups = "unit", testName = "client.hotrod.TransportObjectFactoryTest")
+public class TransportObjectFactoryTest {
+
+ public void testValidate() {
+ Codec codec = mock(Codec.class);
+ TransportObjectFactory objectFactory = new TransportObjectFactory(codec, null,
+ new AtomicInteger(), false);
+ doThrow(new TransportException("induced!", null))
+ .when(codec).writeHeader(any(Transport.class), any(HeaderParams.class));
+
+ InetSocketAddress address = new InetSocketAddress(123);
+ assertFalse("Exception shouldn't be thrown here", objectFactory.validateObject(address, any(TcpTransport.class)));
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/WorkerThread.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/WorkerThread.java
new file mode 100644
index 000000000000..9f1b4f42197f
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/WorkerThread.java
@@ -0,0 +1,110 @@
+package org.infinispan.client.hotrod;
+
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import java.util.Random;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @author dberinde@redhat.com
+ * @since 4.1
+ */
+public class WorkerThread {
+
+ private static final AtomicInteger WORKER_INDEX = new AtomicInteger();
+
+ private static final Log log = LogFactory.getLog(WorkerThread.class);
+
+ private final RemoteCache remoteCache;
+ private volatile Future> future;
+
+ private final ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+ public Thread newThread(Runnable r) {
+ return new Thread(r, String.format("%s-Worker-%d",
+ Thread.currentThread().getName(), WORKER_INDEX.getAndIncrement()));
+ }
+ });
+
+ public WorkerThread(RemoteCache remoteCache) {
+ this.remoteCache = remoteCache;
+ }
+
+ private void stressInternal() throws Exception {
+ Random rnd = new Random();
+ while (!executor.isShutdown()) {
+ remoteCache.put(rnd.nextLong(), rnd.nextLong());
+ Thread.sleep(50);
+ }
+ }
+
+ /**
+ * Only returns when this thread added the given key value.
+ */
+ public String put(final String key, final String value) {
+ Future> result = executor.submit(new Callable() {
+ public Object call() {
+ return remoteCache.put(key, value);
+ }
+ });
+
+ try {
+ return (String) result.get();
+ } catch (InterruptedException e) {
+ throw new IllegalStateException();
+ } catch (ExecutionException e) {
+ throw new RuntimeException("Error during put", e.getCause());
+ }
+ }
+
+ /**
+ * Does a put on the worker thread.
+ * Doesn't wait for the put operation to finish. However, it will wait for the previous operation on this thread to finish.
+ */
+ public Future> putAsync(final String key, final String value) throws ExecutionException, InterruptedException {
+ if (future != null) {
+ future.get();
+ }
+ return executor.submit(new Callable() {
+ public Object call() throws Exception {
+ return remoteCache.put(key, value);
+ }
+ });
+ }
+
+ /**
+ * Starts doing cache put operations in a loop on the worker thread.
+ * Doesn't wait for the loop to finish - in fact the loop will finish only when the worker is stopped.
+ * However, it will wait for the previous operation on this thread to finish.
+ */
+ public Future> stress() throws InterruptedException, ExecutionException {
+ if (future != null) {
+ future.get();
+ }
+ return executor.submit(new Callable() {
+ public Object call() throws Exception {
+ stressInternal();
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Returns without waiting for the threads to finish.
+ */
+ public void stop() {
+ executor.shutdown();
+ }
+
+ /**
+ * Only returns when the last operation on this thread has finished.
+ */
+ public void awaitTermination() throws InterruptedException, ExecutionException {
+ executor.awaitTermination(1, TimeUnit.SECONDS);
+ if (future != null) {
+ future.get();
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/configuration/ConfigurationTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/configuration/ConfigurationTest.java
new file mode 100644
index 000000000000..a67f2068573f
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/configuration/ConfigurationTest.java
@@ -0,0 +1,119 @@
+package org.infinispan.client.hotrod.configuration;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import org.infinispan.client.hotrod.SomeAsyncExecutorFactory;
+import org.infinispan.client.hotrod.SomeCustomConsistentHashV1;
+import org.infinispan.client.hotrod.SomeRequestBalancingStrategy;
+import org.infinispan.client.hotrod.SomeTransportfactory;
+import org.infinispan.client.hotrod.impl.ConfigurationProperties;
+import org.infinispan.commons.CacheConfigurationException;
+import org.testng.annotations.Test;
+
+@Test(testName = "client.hotrod.configuration.ConfigurationTest", groups = "functional" )
+public class ConfigurationTest {
+
+ public void testConfiguration() {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder
+ .addServer()
+ .host("host1")
+ .port(11222)
+ .addServer()
+ .host("host2")
+ .port(11222)
+ .asyncExecutorFactory()
+ .factoryClass(SomeAsyncExecutorFactory.class)
+ .balancingStrategy(SomeRequestBalancingStrategy.class)
+ .connectionPool()
+ .maxActive(100)
+ .maxTotal(150)
+ .maxWait(1000)
+ .maxIdle(20)
+ .minIdle(10)
+ .exhaustedAction(ExhaustedAction.WAIT)
+ .numTestsPerEvictionRun(5)
+ .testOnBorrow(true)
+ .testOnReturn(true)
+ .testWhileIdle(false)
+ .minEvictableIdleTime(12000)
+ .timeBetweenEvictionRuns(15000)
+ .connectionTimeout(100)
+ .consistentHashImpl(1, SomeCustomConsistentHashV1.class)
+ .socketTimeout(100)
+ .tcpNoDelay(false)
+ .pingOnStartup(false)
+ .keySizeEstimate(128)
+ .valueSizeEstimate(1024)
+ .maxRetries(0)
+ .transportFactory(SomeTransportfactory.class);
+
+ Configuration configuration = builder.build();
+ validateConfiguration(configuration);
+
+ ConfigurationBuilder newBuilder = new ConfigurationBuilder();
+ newBuilder.read(configuration);
+ Configuration newConfiguration = newBuilder.build();
+ validateConfiguration(newConfiguration);
+ }
+
+ public void testParseServerAddresses() {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.addServers("1.1.1.1:9999");
+ builder.addServers("2.2.2.2");
+ builder.addServers("[fe80::290:bff:fe1b:5762]:7777");
+ builder.addServers("[ff01::1]");
+ builder.addServers("localhost");
+ builder.addServers("localhost:8382");
+ Configuration cfg = builder.build();
+ assertServer("1.1.1.1", 9999, cfg.servers().get(0));
+ assertServer("2.2.2.2", ConfigurationProperties.DEFAULT_HOTROD_PORT, cfg.servers().get(1));
+ assertServer("fe80::290:bff:fe1b:5762", 7777, cfg.servers().get(2));
+ assertServer("ff01::1", ConfigurationProperties.DEFAULT_HOTROD_PORT, cfg.servers().get(3));
+ assertServer("localhost", ConfigurationProperties.DEFAULT_HOTROD_PORT, cfg.servers().get(4));
+ assertServer("localhost", 8382, cfg.servers().get(5));
+ }
+
+ @Test(expectedExceptions = CacheConfigurationException.class,
+ expectedExceptionsMessageRegExp = "ISPN(\\d)*: Invalid max_retries \\(value=-1\\). " +
+ "Value should be greater or equal than zero.")
+ public void testNegativeRetriesPerServer() {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.maxRetries(-1);
+ builder.build();
+ }
+
+ private void assertServer(String host, int port, ServerConfiguration serverCfg) {
+ assertEquals(host, serverCfg.host());
+ assertEquals(port, serverCfg.port());
+ }
+
+ private void validateConfiguration(Configuration configuration) {
+ assertEquals(2, configuration.servers().size());
+ assertEquals(SomeAsyncExecutorFactory.class, configuration.asyncExecutorFactory().factoryClass());
+ assertEquals(SomeRequestBalancingStrategy.class, configuration.balancingStrategy());
+ assertEquals(SomeTransportfactory.class, configuration.transportFactory());
+ assertEquals(SomeCustomConsistentHashV1.class, configuration.consistentHashImpl(1));
+ assertEquals(100, configuration.connectionPool().maxActive());
+ assertEquals(150, configuration.connectionPool().maxTotal());
+ assertEquals(1000, configuration.connectionPool().maxWait());
+ assertEquals(20, configuration.connectionPool().maxIdle());
+ assertEquals(10, configuration.connectionPool().minIdle());
+ assertEquals(ExhaustedAction.WAIT, configuration.connectionPool().exhaustedAction());
+ assertEquals(5, configuration.connectionPool().numTestsPerEvictionRun());
+ assertEquals(15000, configuration.connectionPool().timeBetweenEvictionRuns());
+ assertEquals(12000, configuration.connectionPool().minEvictableIdleTime());
+ assertTrue(configuration.connectionPool().testOnBorrow());
+ assertTrue(configuration.connectionPool().testOnReturn());
+ assertFalse(configuration.connectionPool().testWhileIdle());
+ assertEquals(100, configuration.connectionTimeout());
+ assertEquals(100, configuration.socketTimeout());
+ assertFalse(configuration.tcpNoDelay());
+ assertFalse(configuration.pingOnStartup());
+ assertEquals(128, configuration.keySizeEstimate());
+ assertEquals(1024, configuration.valueSizeEstimate());
+ assertEquals(0, configuration.maxRetries());
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/ApacheAvroMarshallerTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/ApacheAvroMarshallerTest.java
new file mode 100644
index 000000000000..cc1a53daf381
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/ApacheAvroMarshallerTest.java
@@ -0,0 +1,152 @@
+package org.infinispan.client.hotrod.marshall;
+
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+@Test(groups = "functional", testName = "client.hotrod.marshall.ApacheAvroMarshallerTest")
+public class ApacheAvroMarshallerTest {
+
+ private final ApacheAvroMarshaller marshaller = new ApacheAvroMarshaller();
+
+ public void testStringMarshalling() {
+ String x = "Galder";
+ String y = (String) marshallUnmarshall(x);
+ assert y.equals(x);
+ }
+
+ public void testBooleanMarshalling() {
+ boolean x = true;
+ boolean y = ((Boolean) marshallUnmarshall(x)).booleanValue();
+ assert x == y;
+ assertEquality(new Boolean(false));
+ }
+
+ public void testIntegerMarshalling() {
+ int x = 99;
+ int y = ((Integer) marshallUnmarshall(x)).intValue();
+ assert x == y;
+ assertEquality(new Integer(12345));
+ }
+
+ public void testLongMarshalling() {
+ long x = 9223372036854775807L;
+ long y = ((Long) marshallUnmarshall(x)).longValue();
+ assert x == y;
+ assertEquality(new Long(72057594037927936L));
+ }
+
+ public void testFloatMarshalling() {
+ float x = 123.4f;
+ float y = ((Float) marshallUnmarshall(x)).floatValue();
+ assert x == y;
+ assertEquality(new Float(56789.9));
+ }
+
+ public void testDoubleMarshalling() {
+ double x = 1.234e2;
+ double y = ((Double) marshallUnmarshall(x)).doubleValue();
+ assert x == y;
+ assertEquality(new Double(5.678e9));
+ }
+
+ public void testNullMarshalling() {
+ assert null == marshallUnmarshall(null);
+ }
+
+ public void testBytesMarshalling() {
+ byte[] x = new byte[]{1, 2, 3, 4};
+ byte[] y = (byte[]) marshallUnmarshall(x);
+ assert Arrays.equals(x, y);
+ }
+
+ public void testStringArrayMarshalling() {
+ assertArrayEquality(new String[]{"Basque Country", "Spain", "UK", "Switzerland"});
+ }
+
+ public void testIntArrayMarshalling() {
+ assertArrayEquality(new Integer[]{1234, 5678, 9101112});
+ }
+
+ public void testLongArrayMarshalling() {
+ assertArrayEquality(new Long[]{9223372036854775807L, 72057594037927936L});
+ }
+
+ public void testBooleanArrayMarshalling() {
+ assertArrayEquality(new Boolean[] {true, false, true, true});
+ }
+
+ public void testFloatArrayMarshalling() {
+ assertArrayEquality(new Float[] {56789.9f, 1234.6f, 85894.303f, 67484.32f, 4732.4f});
+ }
+
+ public void testDoubleArrayMarshalling() {
+ assertArrayEquality(new Double[] {5.678e9, 1.623435e9, 5.654545e5, 9.6232323e1});
+ }
+
+ public void testListMarshalling() {
+ List cities = new ArrayList();
+ cities.add("algorta");
+ cities.add("neuchatel");
+ cities.add("ibiza");
+ assertEquality(cities);
+
+ List numbers = new ArrayList();
+ numbers.add(12);
+ numbers.add(3232412);
+ numbers.add(4345132);
+ numbers.add(898979);
+ assertEquality(numbers);
+
+ List testimony = new LinkedList();
+ testimony.add(false);
+ testimony.add(true);
+ testimony.add(true);
+ testimony.add(true);
+ assertEquality(testimony);
+ }
+
+ public void testMapMarshalling() {
+ Map numbers = new HashMap();
+ numbers.put(9223372036854775807L, 4732.4f);
+ numbers.put(72057594037927936L, 67484.32f);
+ numbers.put(7205759412424936L, 132367484.32f);
+ assertEquality(numbers);
+ }
+
+ public void testSetMarshalling() {
+ Set words = new HashSet();
+ words.add("cat");
+ words.add("dog");
+ words.add("perro");
+ words.add("txakur");
+ assertEquality(words);
+ }
+
+ private Object marshallUnmarshall(Object o) {
+ try {
+ byte[] buffer = marshaller.objectToByteBuffer(o);
+ return marshaller.objectFromByteBuffer(buffer);
+ } catch(Exception e) {
+ throw new RuntimeException("Error marshalling or unmarshalling", e);
+ }
+ }
+
+ private void assertArrayEquality(T[] x) {
+ T[] y = (T[]) ApacheAvroMarshallerTest.this.marshallUnmarshall(x);
+ assert Arrays.equals(x, y);
+ }
+
+ private void assertEquality(T x) {
+ T y = (T) ApacheAvroMarshallerTest.this.marshallUnmarshall(x);
+ assert x.equals(y);
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedAccount.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedAccount.java
new file mode 100644
index 000000000000..2dc90b65713f
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedAccount.java
@@ -0,0 +1,62 @@
+package org.infinispan.client.hotrod.marshall;
+
+import org.hibernate.search.annotations.Analyze;
+import org.hibernate.search.annotations.Field;
+import org.hibernate.search.annotations.Indexed;
+import org.hibernate.search.annotations.Store;
+
+import java.util.Date;
+
+/**
+ * A class similar to {@code org.infinispan.protostream.sampledomain.Account}, that maps to the same protobuf type,
+ * {@code sample_bank_account.Account}.
+ *
+ * @author anistor@redhat.com
+ * @since 6.0
+ */
+@Indexed
+public class EmbeddedAccount {
+
+ @Field(store = Store.YES, analyze = Analyze.NO)
+ private int id;
+
+ @Field(store = Store.YES, analyze = Analyze.NO)
+ private String description;
+
+ @Field(store = Store.YES, analyze = Analyze.NO)
+ private Date creationDate;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Date getCreationDate() {
+ return creationDate;
+ }
+
+ public void setCreationDate(Date creationDate) {
+ this.creationDate = creationDate;
+ }
+
+ @Override
+ public String toString() {
+ return "EmbeddedAccount{" +
+ "id=" + id +
+ ", description='" + description + '\'' +
+ ", creationDate='" + creationDate + '\'' +
+ "}";
+
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedAccountMarshaller.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedAccountMarshaller.java
new file mode 100644
index 000000000000..f2c28f7dd73a
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedAccountMarshaller.java
@@ -0,0 +1,42 @@
+package org.infinispan.client.hotrod.marshall;
+
+import org.infinispan.protostream.MessageMarshaller;
+
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * @author anistor@redhat.com
+ */
+public class EmbeddedAccountMarshaller implements MessageMarshaller {
+
+ @Override
+ public String getTypeName() {
+ return "sample_bank_account.Account";
+ }
+
+ @Override
+ public Class extends EmbeddedAccount> getJavaClass() {
+ return EmbeddedAccount.class;
+ }
+
+ @Override
+ public EmbeddedAccount readFrom(ProtoStreamReader reader) throws IOException {
+ int id = reader.readInt("id");
+ String description = reader.readString("description");
+ long creationDate = reader.readLong("creationDate");
+
+ EmbeddedAccount account = new EmbeddedAccount();
+ account.setId(id);
+ account.setDescription(description);
+ account.setCreationDate(new Date(creationDate));
+ return account;
+ }
+
+ @Override
+ public void writeTo(ProtoStreamWriter writer, EmbeddedAccount account) throws IOException {
+ writer.writeInt("id", account.getId());
+ writer.writeString("description", account.getDescription());
+ writer.writeLong("creationDate", account.getCreationDate().getTime());
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedCompatTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedCompatTest.java
new file mode 100644
index 000000000000..61b0d25238c9
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/EmbeddedCompatTest.java
@@ -0,0 +1,194 @@
+package org.infinispan.client.hotrod.marshall;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.Search;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.infinispan.commons.equivalence.AnyEquivalence;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.Account;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.CacheQuery;
+import org.infinispan.query.dsl.Query;
+import org.infinispan.query.dsl.QueryFactory;
+import org.infinispan.query.remote.CompatibilityProtoStreamMarshaller;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.Test;
+
+import java.util.Date;
+import java.util.List;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.junit.Assert.*;
+
+/**
+ * Tests compatibility between remote query and embedded mode.
+ *
+ * @author anistor@redhat.com
+ * @since 6.0
+ */
+@Test(testName = "client.hotrod.marshall.EmbeddedCompatTest", groups = "functional")
+@CleanupAfterMethod
+public class EmbeddedCompatTest extends SingleCacheManagerTest {
+
+ private HotRodServer hotRodServer;
+ private RemoteCacheManager remoteCacheManager;
+ private RemoteCache remoteCache;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ org.infinispan.configuration.cache.ConfigurationBuilder builder = hotRodCacheConfiguration();
+ builder.compatibility().enable().marshaller(new CompatibilityProtoStreamMarshaller());
+ builder.indexing().enable()
+ .addProperty("default.directory_provider", "ram")
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+
+ builder.dataContainer().keyEquivalence(AnyEquivalence.getInstance()); // TODO [anistor] hacks!
+ cacheManager = TestCacheManagerFactory.createCacheManager(builder);
+ cache = cacheManager.getCache();
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
+ clientBuilder.addServer().host("127.0.0.1").port(hotRodServer.getPort());
+ clientBuilder.marshaller(new ProtoStreamMarshaller());
+ remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
+
+ remoteCache = remoteCacheManager.getCache();
+
+ //initialize client-side serialization context
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager));
+
+ //initialize server-side serialization context
+ ProtobufMetadataManager protobufMetadataManager = cacheManager.getGlobalComponentRegistry().getComponent(ProtobufMetadataManager.class);
+ protobufMetadataManager.registerProtofile("/sample_bank_account/bank.protobin");
+ protobufMetadataManager.registerMarshaller(EmbeddedAccount.class, new EmbeddedAccountMarshaller());
+
+ return cacheManager;
+ }
+
+ @AfterTest
+ public void release() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotRodServer);
+ }
+
+ public void testPutAndGet() throws Exception {
+ Account account = createAccount();
+ remoteCache.put(1, account);
+
+ // try to get the object through the local cache interface and check it's the same object we put
+ assertEquals(1, cache.keySet().size());
+ Object key = cache.keySet().iterator().next();
+ Object localObject = cache.get(key);
+ assertNotNull(localObject);
+ assertTrue(localObject instanceof EmbeddedAccount);
+ assertEmbeddedAccount((EmbeddedAccount) localObject);
+
+ // get the object through the remote cache interface and check it's the same object we put
+ Account fromRemoteCache = remoteCache.get(1);
+ assertAccount(fromRemoteCache);
+ }
+
+ public void testPutAndGetForEmbeddedEntry() throws Exception {
+ EmbeddedAccount account = new EmbeddedAccount();
+ account.setId(1);
+ account.setDescription("test description");
+ account.setCreationDate(new Date(42));
+ cache.put(1, account);
+
+ // try to get the object through the local cache interface and check it's the same object we put
+ assertEquals(1, remoteCache.keySet().size());
+ Object key = remoteCache.keySet().iterator().next();
+ Object remoteObject = remoteCache.get(key);
+ assertNotNull(remoteObject);
+ assertTrue(remoteObject instanceof Account);
+ assertAccount((Account) remoteObject);
+
+ // get the object through the embedded cache interface and check it's the same object we put
+ EmbeddedAccount fromEmbeddedCache = (EmbeddedAccount) cache.get(1);
+ assertEmbeddedAccount(fromEmbeddedCache);
+ }
+
+ public void testRemoteQuery() throws Exception {
+ Account account = createAccount();
+ remoteCache.put(1, account);
+
+ // get account back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+ Query query = qf.from(Account.class)
+ .having("description").like("%test%").toBuilder()
+ .build();
+ List list = query.list();
+
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(Account.class, list.get(0).getClass());
+ assertAccount(list.get(0));
+ }
+
+ public void testRemoteQueryForEmbeddedEntry() throws Exception {
+ EmbeddedAccount account = new EmbeddedAccount();
+ account.setId(1);
+ account.setDescription("test description");
+ account.setCreationDate(new Date(42));
+ cache.put(1, account);
+
+ // get account back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+ Query query = qf.from(Account.class)
+ .having("description").like("%test%").toBuilder()
+ .build();
+ List list = query.list();
+
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(Account.class, list.get(0).getClass());
+ assertAccount(list.get(0));
+ }
+
+ public void testEmbeddedQuery() throws Exception {
+ Account account = createAccount();
+ remoteCache.put(1, account);
+
+ // get account back from local cache via query and check its attributes
+ org.apache.lucene.search.Query query = org.infinispan.query.Search.getSearchManager(cache)
+ .buildQueryBuilderForClass(EmbeddedAccount.class).get()
+ .keyword().wildcard().onField("description").matching("*test*").createQuery();
+ CacheQuery cacheQuery = org.infinispan.query.Search.getSearchManager(cache).getQuery(query);
+ List list = cacheQuery.list();
+
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(EmbeddedAccount.class, list.get(0).getClass());
+ assertEmbeddedAccount((EmbeddedAccount) list.get(0));
+ }
+
+ private Account createAccount() {
+ Account account = new Account();
+ account.setId(1);
+ account.setDescription("test description");
+ account.setCreationDate(new Date(42));
+ return account;
+ }
+
+ private void assertAccount(Account account) {
+ assertEquals(1, account.getId());
+ assertEquals("test description", account.getDescription());
+ assertEquals(42, account.getCreationDate().getTime());
+ }
+
+ private void assertEmbeddedAccount(EmbeddedAccount account) {
+ assertEquals(1, account.getId());
+ assertEquals("test description", account.getDescription());
+ assertEquals(42, account.getCreationDate().getTime());
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/ProtoStreamMarshallerTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/ProtoStreamMarshallerTest.java
new file mode 100644
index 000000000000..c7d33b96ec4c
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/marshall/ProtoStreamMarshallerTest.java
@@ -0,0 +1,113 @@
+package org.infinispan.client.hotrod.marshall;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.ProtobufUtil;
+import org.infinispan.protostream.sampledomain.Address;
+import org.infinispan.protostream.sampledomain.User;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.junit.Assert.*;
+
+/**
+ * Tests integration between HotRod client and ProtoStream marshalling library.
+ *
+ * @author anistor@redhat.com
+ * @since 6.0
+ */
+@Test(testName = "client.hotrod.marshall.ProtoStreamMarshallerTest", groups = "functional")
+@CleanupAfterMethod
+public class ProtoStreamMarshallerTest extends SingleCacheManagerTest {
+
+ private HotRodServer hotRodServer;
+ private RemoteCacheManager remoteCacheManager;
+ private RemoteCache remoteCache;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ cacheManager = TestCacheManagerFactory.createCacheManager(hotRodCacheConfiguration());
+ cache = cacheManager.getCache();
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
+ clientBuilder.addServer().host("127.0.0.1").port(hotRodServer.getPort());
+ clientBuilder.marshaller(new ProtoStreamMarshaller());
+ remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
+
+ remoteCache = remoteCacheManager.getCache();
+
+ //initialize client-side serialization context
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager));
+
+ return cacheManager;
+ }
+
+ @AfterTest
+ public void release() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotRodServer);
+ }
+
+ public void testPutAndGet() throws Exception {
+ User user = createUser();
+ remoteCache.put(1, user);
+
+ // try to get the object through the local cache interface and check it's the same object we put
+ assertEquals(1, cache.keySet().size());
+ byte[] key = (byte[]) cache.keySet().iterator().next();
+ Object localObject = cache.get(key);
+ assertNotNull(localObject);
+ assertTrue(localObject instanceof byte[]);
+ Object unmarshalledObject = ProtobufUtil.fromWrappedByteArray(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager), (byte[]) localObject);
+ assertTrue(unmarshalledObject instanceof User);
+ assertUser((User) unmarshalledObject);
+
+ // get the object through the remote cache interface and check it's the same object we put
+ User fromRemoteCache = remoteCache.get(1);
+ assertUser(fromRemoteCache);
+ }
+
+ private User createUser() {
+ User user = new User();
+ user.setId(1);
+ user.setName("Tom");
+ user.setSurname("Cat");
+ user.setGender(User.Gender.MALE);
+ user.setAccountIds(Collections.singletonList(12));
+ Address address = new Address();
+ address.setStreet("Dark Alley");
+ address.setPostCode("1234");
+ user.setAddresses(Collections.singletonList(address));
+ return user;
+ }
+
+ private void assertUser(User user) {
+ assertNotNull(user);
+ assertEquals(1, user.getId());
+ assertEquals("Tom", user.getName());
+ assertEquals("Cat", user.getSurname());
+ assertEquals(User.Gender.MALE, user.getGender());
+ assertNotNull(user.getAccountIds());
+ assertEquals(1, user.getAccountIds().size());
+ assertEquals(12, user.getAccountIds().get(0).intValue());
+ assertNotNull(user.getAddresses());
+ assertEquals(1, user.getAddresses().size());
+ assertEquals("Dark Alley", user.getAddresses().get(0).getStreet());
+ assertEquals("1234", user.getAddresses().get(0).getPostCode());
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryFileSystemTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryFileSystemTest.java
new file mode 100644
index 000000000000..a7f1cac4a25b
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryFileSystemTest.java
@@ -0,0 +1,52 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.junit.Assert;
+import org.testng.annotations.Test;
+
+import java.io.File;
+
+/**
+ * Tests verifying the functionality of Remote queries for HotRod using FileSystem as a directory provider.
+ *
+ * @author Anna Manukyan
+ */
+@Test(testName = "client.hotrod.query.HotRodQueryFileSystemTest", groups = "functional")
+@CleanupAfterMethod
+public class HotRodQueryFileSystemTest extends HotRodQueryTest {
+
+ private final String indexDirectory = TestingUtil.tmpDirectory(getClass());
+
+ @Override
+ protected ConfigurationBuilder getConfigurationBuilder() {
+ ConfigurationBuilder builder = super.getConfigurationBuilder();
+ builder.indexing().addProperty("default.indexBase", indexDirectory);
+ return builder;
+ }
+
+ @Override
+ protected String getLuceneDirectoryProvider() {
+ return "filesystem";
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ TestingUtil.recursiveFileRemove(indexDirectory);
+ boolean created = new File(indexDirectory).mkdirs();
+ Assert.assertTrue(created);
+ super.setup();
+ }
+
+ @Override
+ protected void teardown() {
+ try {
+ //first stop cache managers, then clear the index
+ super.teardown();
+ } finally {
+ //delete the index otherwise it will mess up the index for next tests
+ TestingUtil.recursiveFileRemove(indexDirectory);
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryIspnDirectoryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryIspnDirectoryTest.java
new file mode 100644
index 000000000000..d0abd3ffd3b4
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryIspnDirectoryTest.java
@@ -0,0 +1,20 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Test remote queries against Infinispan Directory provider.
+ *
+ * @author anistor@redhat.com
+ * @since 6.0
+ */
+@Test(testName = "client.hotrod.query.HotRodQueryIspnDirectoryTest", groups = "functional")
+@CleanupAfterMethod
+public class HotRodQueryIspnDirectoryTest extends HotRodQueryTest {
+
+ @Override
+ protected String getLuceneDirectoryProvider() {
+ return "infinispan";
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryTest.java
new file mode 100644
index 000000000000..bac804e1c0e5
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodQueryTest.java
@@ -0,0 +1,224 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.Search;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.commons.equivalence.ByteArrayEquivalence;
+import org.infinispan.commons.util.Util;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.configuration.global.GlobalConfigurationBuilder;
+import org.infinispan.jmx.PerThreadMBeanServerLookup;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.Address;
+import org.infinispan.protostream.sampledomain.User;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.dsl.Query;
+import org.infinispan.query.dsl.QueryFactory;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.Test;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author anistor@redhat.com
+ * @since 6.0
+ */
+@Test(testName = "client.hotrod.query.HotRodQueryTest", groups = "functional")
+@CleanupAfterMethod
+public class HotRodQueryTest extends SingleCacheManagerTest {
+
+ public static final String JMX_DOMAIN = ProtobufMetadataManager.class.getSimpleName();
+
+ public static final String TEST_CACHE_NAME = "userCache";
+
+ private HotRodServer hotRodServer;
+ private RemoteCacheManager remoteCacheManager;
+ private RemoteCache remoteCache;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder().nonClusteredDefault();
+ gcb.globalJmxStatistics()
+ .enable()
+ .allowDuplicateDomains(true)
+ .jmxDomain(JMX_DOMAIN)
+ .mBeanServerLookup(new PerThreadMBeanServerLookup());
+
+ ConfigurationBuilder builder = getConfigurationBuilder();
+
+ cacheManager = TestCacheManagerFactory.createCacheManager(gcb, new ConfigurationBuilder(), true);
+ cacheManager.defineConfiguration(TEST_CACHE_NAME, builder.build());
+ cache = cacheManager.getCache(TEST_CACHE_NAME);
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
+ clientBuilder.addServer().host("127.0.0.1").port(hotRodServer.getPort());
+ clientBuilder.marshaller(new ProtoStreamMarshaller());
+ remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
+
+ remoteCache = remoteCacheManager.getCache(TEST_CACHE_NAME);
+
+ ObjectName objName = new ObjectName(JMX_DOMAIN + ":type=RemoteQuery,name="
+ + ObjectName.quote("DefaultCacheManager")
+ + ",component=" + ProtobufMetadataManager.OBJECT_NAME);
+
+ //initialize server-side serialization context via JMX
+ byte[] descriptor = readClasspathResource("/sample_bank_account/bank.protobin");
+ MBeanServer mBeanServer = PerThreadMBeanServerLookup.getThreadMBeanServer();
+ mBeanServer.invoke(objName, "registerProtofile", new Object[]{descriptor}, new String[]{byte[].class.getName()});
+
+ //initialize client-side serialization context
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager));
+
+ return cacheManager;
+ }
+
+ protected ConfigurationBuilder getConfigurationBuilder() {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.dataContainer()
+ .keyEquivalence(ByteArrayEquivalence.INSTANCE)
+ .indexing().enable()
+ .addProperty("default.directory_provider", getLuceneDirectoryProvider())
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+ return builder;
+ }
+
+ protected String getLuceneDirectoryProvider() {
+ return "ram";
+ }
+
+ private byte[] readClasspathResource(String classPathResource) throws IOException {
+ InputStream is = getClass().getResourceAsStream(classPathResource);
+ try {
+ return Util.readStream(is);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ @AfterTest
+ public void release() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotRodServer);
+ }
+
+ public void testAttributeQuery() throws Exception {
+ remoteCache.put(1, createUser1());
+ remoteCache.put(2, createUser2());
+
+ // get user back from remote cache and check its attributes
+ User fromCache = remoteCache.get(1);
+ assertUser(fromCache);
+
+ // get user back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+ Query query = qf.from(User.class)
+ .having("name").eq("Tom").toBuilder()
+ .build();
+ List list = query.list();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(User.class, list.get(0).getClass());
+ assertUser(list.get(0));
+ }
+
+ public void testEmbeddedAttributeQuery() throws Exception {
+ remoteCache.put(1, createUser1());
+ remoteCache.put(2, createUser2());
+
+ // get user back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+ Query query = qf.from(User.class)
+ .having("addresses.postCode").eq("1234").toBuilder()
+ .build();
+ List list = query.list();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(User.class, list.get(0).getClass());
+ assertUser(list.get(0));
+ }
+
+ public void testProjections() throws Exception {
+ remoteCache.put(1, createUser1());
+ remoteCache.put(2, createUser2());
+
+ // get user back from remote cache and check its attributes
+ User fromCache = remoteCache.get(1);
+ assertUser(fromCache);
+
+ // get user back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+ Query query = qf.from(User.class)
+ .setProjection("name", "surname")
+ .having("name").eq("Tom").toBuilder()
+ .build();
+ List list = query.list();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(Object[].class, list.get(0).getClass());
+ assertEquals("Tom", list.get(0)[0]);
+ assertEquals("Cat", list.get(0)[1]);
+ }
+
+ private User createUser1() {
+ User user = new User();
+ user.setId(1);
+ user.setName("Tom");
+ user.setSurname("Cat");
+ user.setGender(User.Gender.MALE);
+ user.setAccountIds(Collections.singletonList(12));
+ Address address = new Address();
+ address.setStreet("Dark Alley");
+ address.setPostCode("1234");
+ user.setAddresses(Collections.singletonList(address));
+ return user;
+ }
+
+ private User createUser2() {
+ User user = new User();
+ user.setId(1);
+ user.setName("Adrian");
+ user.setSurname("Nistor");
+ user.setGender(User.Gender.MALE);
+ Address address = new Address();
+ address.setStreet("Old Street");
+ address.setPostCode("XYZ");
+ user.setAddresses(Collections.singletonList(address));
+ return user;
+ }
+
+ private void assertUser(User user) {
+ assertNotNull(user);
+ assertEquals(1, user.getId());
+ assertEquals("Tom", user.getName());
+ assertEquals("Cat", user.getSurname());
+ assertEquals(User.Gender.MALE, user.getGender());
+ assertNotNull(user.getAccountIds());
+ assertEquals(1, user.getAccountIds().size());
+ assertEquals(12, user.getAccountIds().get(0).intValue());
+ assertNotNull(user.getAddresses());
+ assertEquals(1, user.getAddresses().size());
+ assertEquals("Dark Alley", user.getAddresses().get(0).getStreet());
+ assertEquals("1234", user.getAddresses().get(0).getPostCode());
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodTunedQueryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodTunedQueryTest.java
new file mode 100644
index 000000000000..0624d95a7d0b
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/HotRodTunedQueryTest.java
@@ -0,0 +1,63 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.commons.equivalence.ByteArrayEquivalence;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.AssertJUnit.assertTrue;
+
+import java.io.File;
+
+/**
+ * Verifying that the tuned query configuration also works for Remote Queries.
+ *
+ * @author Anna Manukyan
+ */
+@Test(testName = "client.hotrod.query.HotRodTunedQueryTest", groups = "functional")
+@CleanupAfterMethod
+public class HotRodTunedQueryTest extends RemoteQueryDslConditionsTest {
+
+ private final String indexDirectory = TestingUtil.tmpDirectory(getClass());
+
+ @Override
+ protected ConfigurationBuilder getConfigurationBuilder() {
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.dataContainer()
+ .keyEquivalence(ByteArrayEquivalence.INSTANCE)
+ .valueEquivalence(ByteArrayEquivalence.INSTANCE)
+ .indexing().enable()
+ .indexLocalOnly(false)
+ .addProperty("default.indexmanager", "near-real-time")
+ .addProperty("default.indexBase", indexDirectory)
+ .addProperty("default.exclusive_index_use", "true")
+ .addProperty("default.indexwriter.merge_factor", "30")
+ .addProperty("default.indexwriter.merge_max_size", "4096")
+ .addProperty("default.indexwriter.ram_buffer_size", "220")
+ .addProperty("default.locking_strategy", "native")
+ .addProperty("default.sharding_strategy.nbr_of_shards", "6")
+ .addProperty("lucene_version", "LUCENE_36");
+
+ return builder;
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ TestingUtil.recursiveFileRemove(indexDirectory);
+ boolean created = new File(indexDirectory).mkdirs();
+ assertTrue(created);
+ super.setup();
+ }
+
+ @Override
+ protected void teardown() {
+ try {
+ //first stop cache managers, then clear the index
+ super.teardown();
+ } finally {
+ //delete the index otherwise it will mess up the index for next tests
+ TestingUtil.recursiveFileRemove(indexDirectory);
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerIspnDirQueryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerIspnDirQueryTest.java
new file mode 100644
index 000000000000..a9ae54867268
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerIspnDirQueryTest.java
@@ -0,0 +1,63 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.testng.annotations.Test;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+/**
+ * Verifying the functionality of Queries using ISPN directory_provider on clustered hotrod server configuration.
+ *
+ * @author Anna Manukyan
+ */
+@Test(testName = "client.hotrod.query.MultiHotRodServerIspnDirQueryTest", groups = "unstable", description = "Enable tests when ISPN-3672 is fixed. -- original group: functional")
+public class MultiHotRodServerIspnDirQueryTest extends MultiHotRodServerQueryTest {
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ ConfigurationBuilder defaultConfiguration = new ConfigurationBuilder();
+ ConfigurationBuilder builder = hotRodCacheConfiguration(getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false));
+ builder.indexing().enable().indexLocalOnly(false)
+ .addProperty("default.directory_provider", "infinispan")
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+
+ createHotRodServers(2, defaultConfiguration);
+
+ //initialize server-side serialization context
+ for (EmbeddedCacheManager cm : cacheManagers) {
+ cm.defineConfiguration("queryableCache", builder.build());
+
+ cm.getGlobalComponentRegistry().getComponent(ProtobufMetadataManager.class).registerProtofile("/sample_bank_account/bank.protobin");
+ }
+
+ //initialize client-side serialization context
+ for (RemoteCacheManager rcm : clients) {
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(rcm));
+ }
+
+ remoteCache0 = client(0).getCache("queryableCache");
+ remoteCache1 = client(1).getCache("queryableCache");
+ }
+
+ @Test(groups = "unstable")
+ public void testAttributeQuery() throws Exception {
+ super.testAttributeQuery();
+
+ }
+
+ @Test(groups = "unstable")
+ public void testEmbeddedAttributeQuery() throws Exception {
+ super.testEmbeddedAttributeQuery();
+ }
+
+ @Test(groups = "unstable")
+ public void testProjections() throws Exception {
+ super.testProjections();
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerIspnDirReplQueryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerIspnDirReplQueryTest.java
new file mode 100644
index 000000000000..d6e93975008d
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerIspnDirReplQueryTest.java
@@ -0,0 +1,66 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.testng.annotations.Test;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+/**
+ * Verifies the functionality of the Queries in case of REPL infinispan directory_provider for clustered Hotrod servers.
+ *
+ * @author Anna Manukyan
+ */
+@Test(testName = "client.hotrod.query.MultiHotRodServerIspnDirReplQueryTest", groups = "unstable", description = "Enable tests when ISPN-3672 is fixed. -- original group: functional")
+public class MultiHotRodServerIspnDirReplQueryTest extends MultiHotRodServerQueryTest {
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ ConfigurationBuilder defaultConfiguration = getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false);
+ ConfigurationBuilder builder = hotRodCacheConfiguration(getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false));
+ builder.indexing().enable().indexLocalOnly(true)
+ .addProperty("default.directory_provider", "infinispan")
+ .addProperty("default.exclusive_index_use", "false")
+ //.addProperty("default.indexmanager", "org.infinispan.query.indexmanager.InfinispanIndexManager")
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+
+ createHotRodServers(2, defaultConfiguration);
+
+ //initialize server-side serialization context
+ for (EmbeddedCacheManager cm : cacheManagers) {
+ cm.defineConfiguration("queryableCache", builder.build());
+
+ cm.getGlobalComponentRegistry().getComponent(ProtobufMetadataManager.class).registerProtofile("/sample_bank_account/bank.protobin");
+ }
+
+ //initialize client-side serialization context
+ for (RemoteCacheManager rcm : clients) {
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(rcm));
+ }
+
+ waitForClusterToForm();
+
+ remoteCache0 = client(0).getCache("queryableCache");
+ remoteCache1 = client(1).getCache("queryableCache");
+ }
+
+ @Test(groups = "unstable")
+ public void testAttributeQuery() throws Exception {
+ super.testAttributeQuery();
+ }
+
+ @Test(groups = "unstable")
+ public void testEmbeddedAttributeQuery() throws Exception {
+ super.testEmbeddedAttributeQuery();
+ }
+
+ @Test(groups = "unstable")
+ public void testProjections() throws Exception {
+ super.testProjections();
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerQueryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerQueryTest.java
new file mode 100644
index 000000000000..707d2241f909
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/MultiHotRodServerQueryTest.java
@@ -0,0 +1,163 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.Search;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.client.hotrod.test.MultiHotRodServersTest;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.Address;
+import org.infinispan.protostream.sampledomain.User;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.dsl.Query;
+import org.infinispan.query.dsl.QueryFactory;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author anistor@redhat.com
+ * @since 6.0
+ */
+@Test(testName = "client.hotrod.query.MultiHotRodServerQueryTest", groups = "functional")
+public class MultiHotRodServerQueryTest extends MultiHotRodServersTest {
+ protected RemoteCache remoteCache0, remoteCache1;
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ ConfigurationBuilder builder = hotRodCacheConfiguration(getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false));
+ builder.indexing().enable()
+ .addProperty("default.directory_provider", "ram")
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+
+ createHotRodServers(2, builder);
+
+ //initialize server-side serialization context
+ for (EmbeddedCacheManager cm : cacheManagers) {
+ cm.getGlobalComponentRegistry().getComponent(ProtobufMetadataManager.class).registerProtofile("/sample_bank_account/bank.protobin");
+ }
+
+ //initialize client-side serialization context
+ for (RemoteCacheManager rcm : clients) {
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(rcm));
+ }
+
+ remoteCache0 = client(0).getCache();
+ remoteCache1 = client(1).getCache();
+ }
+
+ @Override
+ protected org.infinispan.client.hotrod.configuration.ConfigurationBuilder createHotRodClientConfigurationBuilder(int serverPort) {
+ return super.createHotRodClientConfigurationBuilder(serverPort)
+ .marshaller(new ProtoStreamMarshaller());
+ }
+
+ public void testAttributeQuery() throws Exception {
+ remoteCache0.put(1, createUser1());
+ remoteCache1.put(2, createUser2());
+
+ // get user back from remote cache and check its attributes
+ User fromCache = remoteCache0.get(1);
+ assertNotNull(fromCache);
+ assertUser(fromCache);
+
+ // get user back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache1);
+ Query query = qf.from(User.class)
+ .having("name").eq("Tom").toBuilder()
+ .build();
+ List list = query.list();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(User.class, list.get(0).getClass());
+ assertUser(list.get(0));
+ }
+
+ public void testEmbeddedAttributeQuery() throws Exception {
+ remoteCache0.put(1, createUser1());
+ remoteCache1.put(2, createUser2());
+
+ // get user back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache1);
+ Query query = qf.from(User.class)
+ .having("addresses.postCode").eq("1234").toBuilder()
+ .build();
+ List list = query.list();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(User.class, list.get(0).getClass());
+ assertUser(list.get(0));
+ }
+
+ public void testProjections() throws Exception {
+ remoteCache0.put(1, createUser1());
+ remoteCache1.put(2, createUser2());
+
+ // get user back from remote cache and check its attributes
+ User fromCache = remoteCache0.get(1);
+ assertUser(fromCache);
+
+ // get user back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache1);
+ Query query = qf.from(User.class)
+ .setProjection("name", "surname")
+ .having("name").eq("Tom").toBuilder()
+ .build();
+ List list = query.list();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(Object[].class, list.get(0).getClass());
+ assertEquals("Tom", list.get(0)[0]);
+ assertEquals("Cat", list.get(0)[1]);
+ }
+
+ private User createUser1() {
+ User user = new User();
+ user.setId(1);
+ user.setName("Tom");
+ user.setSurname("Cat");
+ user.setGender(User.Gender.MALE);
+ user.setAccountIds(Collections.singletonList(12));
+ Address address = new Address();
+ address.setStreet("Dark Alley");
+ address.setPostCode("1234");
+ user.setAddresses(Collections.singletonList(address));
+ return user;
+ }
+
+ private User createUser2() {
+ User user = new User();
+ user.setId(2);
+ user.setName("Adrian");
+ user.setSurname("Nistor");
+ user.setGender(User.Gender.MALE);
+ Address address = new Address();
+ address.setStreet("Old Street");
+ address.setPostCode("XYZ");
+ user.setAddresses(Collections.singletonList(address));
+ return user;
+ }
+
+ private void assertUser(User user) {
+ assertNotNull(user);
+ assertEquals(1, user.getId());
+ assertEquals("Tom", user.getName());
+ assertEquals("Cat", user.getSurname());
+ assertEquals(User.Gender.MALE, user.getGender());
+ assertNotNull(user.getAccountIds());
+ assertEquals(1, user.getAccountIds().size());
+ assertEquals(12, user.getAccountIds().get(0).intValue());
+ assertNotNull(user.getAddresses());
+ assertEquals(1, user.getAddresses().size());
+ assertEquals("Dark Alley", user.getAddresses().get(0).getStreet());
+ assertEquals("1234", user.getAddresses().get(0).getPostCode());
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsFilestoreTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsFilestoreTest.java
new file mode 100644
index 000000000000..89387c4fa169
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsFilestoreTest.java
@@ -0,0 +1,58 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.testng.annotations.Test;
+
+import java.io.File;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.assertTrue;
+
+/**
+ * Verifying the functionality of Remote Queries for filesystem directory provider.
+ *
+ * @author Anna Manukyan
+ */
+@Test(testName = "client.hotrod.query.RemoteQueryDslConditionsFilestoreTest", groups = "functional")
+@CleanupAfterMethod
+public class RemoteQueryDslConditionsFilestoreTest extends RemoteQueryDslConditionsTest {
+
+ private final String indexDirectory = TestingUtil.tmpDirectory(getClass());
+
+ @Override
+ protected ConfigurationBuilder getConfigurationBuilder() {
+ ConfigurationBuilder builder = hotRodCacheConfiguration();
+ builder.indexing().enable()
+ .addProperty("default.directory_provider", getLuceneDirectoryProvider())
+ .addProperty("default.indexBase", indexDirectory)
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+
+ return builder;
+ }
+
+ @Override
+ public String getLuceneDirectoryProvider() {
+ return "filesystem";
+ }
+
+ @Override
+ protected void setup() throws Exception {
+ TestingUtil.recursiveFileRemove(indexDirectory);
+ boolean created = new File(indexDirectory).mkdirs();
+ assertTrue(created);
+ super.setup();
+ }
+
+ @Override
+ protected void teardown() {
+ try {
+ //first stop cache managers, then clear the index
+ super.teardown();
+ } finally {
+ //delete the index otherwise it will mess up the index for next tests
+ TestingUtil.recursiveFileRemove(indexDirectory);
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsIspnDirTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsIspnDirTest.java
new file mode 100644
index 000000000000..62d8426fae9c
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsIspnDirTest.java
@@ -0,0 +1,58 @@
+package org.infinispan.client.hotrod.query;
+
+import org.hibernate.search.infinispan.InfinispanIntegration;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.Test;
+
+/**
+ * Verifying the functionality of remote queries for infinispan directory_provider.
+ *
+ * @author Anna Manukyan
+ */
+@Test(testName = "client.hotrod.query.RemoteQueryDslConditionsIspnDirTest", groups = "functional")
+@CleanupAfterMethod
+public class RemoteQueryDslConditionsIspnDirTest extends RemoteQueryDslConditionsTest {
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ ConfigurationBuilder builder = getConfigurationBuilder();
+
+ cacheManager = TestCacheManagerFactory.createCacheManager(builder);
+
+ ConfigurationBuilder defaultCacheConfiguration = new ConfigurationBuilder();
+ cacheManager.defineConfiguration(InfinispanIntegration.DEFAULT_INDEXESDATA_CACHENAME, defaultCacheConfiguration.build());
+ cacheManager.defineConfiguration(InfinispanIntegration.DEFAULT_LOCKING_CACHENAME, defaultCacheConfiguration.build());
+ cacheManager.defineConfiguration(InfinispanIntegration.DEFAULT_INDEXESMETADATA_CACHENAME, defaultCacheConfiguration.build());
+
+ cache = cacheManager.getCache();
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
+ clientBuilder.addServer().host("127.0.0.1").port(hotRodServer.getPort());
+ clientBuilder.marshaller(new ProtoStreamMarshaller());
+ remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
+ remoteCache = remoteCacheManager.getCache();
+
+ //initialize server-side serialization context
+ cacheManager.getGlobalComponentRegistry().getComponent(ProtobufMetadataManager.class).registerProtofile("/sample_bank_account/bank.protobin");
+
+ //initialize client-side serialization context
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager));
+
+ return cacheManager;
+ }
+
+ @Override
+ public String getLuceneDirectoryProvider() {
+ return "infinispan";
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsTest.java
new file mode 100644
index 000000000000..bf92f2690ebb
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslConditionsTest.java
@@ -0,0 +1,1269 @@
+package org.infinispan.client.hotrod.query;
+
+import org.hibernate.search.engine.spi.SearchFactoryImplementor;
+import org.hibernate.search.indexes.spi.IndexManager;
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.Search;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.Account;
+import org.infinispan.protostream.sampledomain.Address;
+import org.infinispan.protostream.sampledomain.Transaction;
+import org.infinispan.protostream.sampledomain.User;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.dsl.FilterConditionEndContext;
+import org.infinispan.query.dsl.Query;
+import org.infinispan.query.dsl.QueryFactory;
+import org.infinispan.query.dsl.SortOrder;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.infinispan.query.remote.indexing.ProtobufValueWrapper;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.junit.Assert.*;
+
+
+//todo [anistor] unify embedded and remote query tests
+
+/**
+ * Test for query conditions (filtering). Exercises the whole query DSL on the sample domain model.
+ *
+ * @author anistor@redhat.com
+ * @since 6.0
+ */
+@Test(groups = "functional", testName = "client.hotrod.query.RemoteQueryDslConditionsTest")
+@CleanupAfterMethod
+public class RemoteQueryDslConditionsTest extends SingleCacheManagerTest {
+
+ protected final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+
+ protected HotRodServer hotRodServer;
+ protected RemoteCacheManager remoteCacheManager;
+ protected RemoteCache remoteCache;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ ConfigurationBuilder builder = getConfigurationBuilder();
+
+ cacheManager = TestCacheManagerFactory.createCacheManager(builder);
+ cache = cacheManager.getCache();
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
+ clientBuilder.addServer().host("127.0.0.1").port(hotRodServer.getPort());
+ clientBuilder.marshaller(new ProtoStreamMarshaller());
+ remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
+ remoteCache = remoteCacheManager.getCache();
+
+ //initialize server-side serialization context
+ cacheManager.getGlobalComponentRegistry().getComponent(ProtobufMetadataManager.class).registerProtofile("/sample_bank_account/bank.protobin");
+
+ //initialize client-side serialization context
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager));
+
+ return cacheManager;
+ }
+
+ protected ConfigurationBuilder getConfigurationBuilder() {
+ ConfigurationBuilder builder = hotRodCacheConfiguration();
+ builder.indexing().enable()
+ .addProperty("default.directory_provider", getLuceneDirectoryProvider())
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+
+ return builder;
+ }
+
+ public String getLuceneDirectoryProvider() {
+ return "ram";
+ }
+
+ @AfterMethod(alwaysRun = true)
+ public void release() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotRodServer);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ protected void populateCache() throws Exception {
+ // create the test objects
+ User user1 = new User();
+ user1.setId(1);
+ user1.setName("John");
+ user1.setSurname("Doe");
+ user1.setGender(User.Gender.MALE);
+ user1.setAge(22);
+ user1.setAccountIds(Arrays.asList(1, 2));
+
+ Address address1 = new Address();
+ address1.setStreet("Main Street");
+ address1.setPostCode("X1234");
+ user1.setAddresses(Collections.singletonList(address1));
+
+ User user2 = new User();
+ user2.setId(2);
+ user2.setName("Spider");
+ user2.setSurname("Man");
+ user2.setGender(User.Gender.MALE);
+ user2.setAccountIds(Collections.singletonList(3));
+
+ Address address2 = new Address();
+ address2.setStreet("Old Street");
+ address2.setPostCode("Y12");
+ Address address3 = new Address();
+ address3.setStreet("Bond Street");
+ address3.setPostCode("ZZ");
+ user2.setAddresses(Arrays.asList(address2, address3));
+
+ User user3 = new User();
+ user3.setId(3);
+ user3.setName("Spider");
+ user3.setSurname("Woman");
+ user3.setGender(User.Gender.FEMALE);
+ user3.setAccountIds(Collections.emptyList());
+
+ Account account1 = new Account();
+ account1.setId(1);
+ account1.setDescription("John Doe's first bank account");
+ account1.setCreationDate(DATE_FORMAT.parse("2013-01-03"));
+
+ Account account2 = new Account();
+ account2.setId(2);
+ account2.setDescription("John Doe's second bank account");
+ account2.setCreationDate(DATE_FORMAT.parse("2013-01-04"));
+
+ Account account3 = new Account();
+ account3.setId(3);
+ account3.setCreationDate(DATE_FORMAT.parse("2013-01-20"));
+
+ Transaction transaction0 = new Transaction();
+ transaction0.setId(0);
+ transaction0.setDescription("Birthday present");
+ transaction0.setAccountId(1);
+ transaction0.setAmount(1800);
+ transaction0.setDate(DATE_FORMAT.parse("2012-09-07"));
+ transaction0.setDebit(false);
+
+ Transaction transaction1 = new Transaction();
+ transaction1.setId(1);
+ transaction1.setDescription("Feb. rent payment");
+ transaction1.setAccountId(1);
+ transaction1.setAmount(1500);
+ transaction1.setDate(DATE_FORMAT.parse("2013-01-05"));
+ transaction1.setDebit(true);
+
+ Transaction transaction2 = new Transaction();
+ transaction2.setId(2);
+ transaction2.setDescription("Starbucks");
+ transaction2.setAccountId(1);
+ transaction2.setAmount(23);
+ transaction2.setDate(DATE_FORMAT.parse("2013-01-09"));
+ transaction2.setDebit(true);
+
+ Transaction transaction3 = new Transaction();
+ transaction3.setId(3);
+ transaction3.setDescription("Hotel");
+ transaction3.setAccountId(2);
+ transaction3.setAmount(45);
+ transaction3.setDate(DATE_FORMAT.parse("2013-02-27"));
+ transaction3.setDebit(true);
+
+ Transaction transaction4 = new Transaction();
+ transaction4.setId(4);
+ transaction4.setDescription("Last january");
+ transaction4.setAccountId(2);
+ transaction4.setAmount(95);
+ transaction4.setDate(DATE_FORMAT.parse("2013-01-31"));
+ transaction4.setDebit(true);
+
+ Transaction transaction5 = new Transaction();
+ transaction5.setId(5);
+ transaction5.setDescription("Popcorn");
+ transaction5.setAccountId(2);
+ transaction5.setAmount(5);
+ transaction5.setDate(DATE_FORMAT.parse("2013-01-01"));
+ transaction5.setDebit(true);
+
+ // persist and index the test objects
+ // we put all of them in the same cache for the sake of simplicity
+ remoteCache.put("user_" + user1.getId(), user1);
+ remoteCache.put("user_" + user2.getId(), user2);
+ remoteCache.put("user_" + user3.getId(), user3);
+ remoteCache.put("account_" + account1.getId(), account1);
+ remoteCache.put("account_" + account2.getId(), account2);
+ remoteCache.put("account_" + account3.getId(), account3);
+ remoteCache.put("transaction_" + transaction0.getId(), transaction0);
+ remoteCache.put("transaction_" + transaction1.getId(), transaction1);
+ remoteCache.put("transaction_" + transaction2.getId(), transaction2);
+ remoteCache.put("transaction_" + transaction3.getId(), transaction3);
+ remoteCache.put("transaction_" + transaction4.getId(), transaction4);
+ remoteCache.put("transaction_" + transaction5.getId(), transaction5);
+
+ SearchFactoryImplementor searchFactory = (SearchFactoryImplementor) org.infinispan.query.Search.getSearchManager(cache).getSearchFactory();
+ Collection indexManagers = searchFactory.getIndexManagerHolder().getIndexManagers();
+
+ for(IndexManager manager : indexManagers) {
+ assertNotNull(manager);
+ assertTrue(manager.getIndexName().contains(ProtobufValueWrapper.class.getName()));
+ }
+ }
+
+ public void testEq1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("name").eq("John")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals("John", list.get(0).getName());
+ assertEquals("Doe", list.get(0).getSurname());
+ }
+
+ public void testEq() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("name").eq("Jacob")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(0, list.size());
+ }
+
+ public void testEqInNested1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all users in a given post code
+ Query q = qf.from(User.class)
+ .having("addresses.postCode").eq("X1234")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals("X1234", list.get(0).getAddresses().get(0).getPostCode());
+ }
+
+ public void testEqInNested2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("addresses.postCode").eq("Y12")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(2, list.get(0).getAddresses().size());
+ }
+
+ public void testLike() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all rent payments made from a given account
+ Query q = qf.from(Transaction.class)
+ .having("description").like("%rent%")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(1, list.get(0).getAccountId());
+ assertEquals(1500, list.get(0).getAmount(), 0);
+ }
+
+ public void testBetween1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all the transactions that happened in January 2013
+ Query q = qf.from(Transaction.class)
+ .having("date").between(DATE_FORMAT.parse("2013-01-01").getTime(), DATE_FORMAT.parse("2013-01-31").getTime())
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(4, list.size());
+ for (Transaction t : list) {
+ assertTrue(t.getDate() <= DATE_FORMAT.parse("2013-01-31").getTime());
+ assertTrue(t.getDate() >= DATE_FORMAT.parse("2013-01-01").getTime());
+ }
+ }
+
+ public void testBetween2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all the transactions that happened in January 2013
+ Query q = qf.from(Transaction.class)
+ .having("date").between(DATE_FORMAT.parse("2013-01-01").getTime(), DATE_FORMAT.parse("2013-01-31").getTime()).includeUpper(false)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ for (Transaction t : list) {
+ assertTrue(t.getDate() < DATE_FORMAT.parse("2013-01-31").getTime());
+ assertTrue(t.getDate() >= DATE_FORMAT.parse("2013-01-01").getTime());
+ }
+ }
+
+ public void testBetween3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all the transactions that happened in January 2013
+ Query q = qf.from(Transaction.class)
+ .having("date").between(DATE_FORMAT.parse("2013-01-01").getTime(), DATE_FORMAT.parse("2013-01-31").getTime()).includeLower(false)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ for (Transaction t : list) {
+ assertTrue(t.getDate() <= DATE_FORMAT.parse("2013-01-31").getTime());
+ assertTrue(t.getDate() > DATE_FORMAT.parse("2013-01-01").getTime());
+ }
+ }
+
+ public void testGt() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all the transactions greater than a given amount
+ Query q = qf.from(Transaction.class)
+ .having("amount").gt(1500)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertTrue(list.get(0).getAmount() > 1500);
+ }
+
+ public void testGte() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(Transaction.class)
+ .having("amount").gte(1500)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ for (Transaction t : list) {
+ assertTrue(t.getAmount() >= 1500);
+ }
+ }
+
+ public void testLt() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(Transaction.class)
+ .having("amount").lt(1500)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(4, list.size());
+ for (Transaction t : list) {
+ assertTrue(t.getAmount() < 1500);
+ }
+ }
+
+ public void testLte() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(Transaction.class)
+ .having("amount").lte(1500)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(5, list.size());
+ for (Transaction t : list) {
+ assertTrue(t.getAmount() <= 1500);
+ }
+ }
+
+ public void testAnd1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("name").eq("Spider")
+ .and().having("surname").eq("Man")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(2, list.get(0).getId());
+ }
+
+ public void testAnd2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("name").eq("Spider")
+ .and(qf.having("surname").eq("Man"))
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(2, list.get(0).getId());
+ }
+
+ public void testAnd3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("gender").eq(User.Gender.MALE)
+ .and().having("gender").eq(User.Gender.FEMALE)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(0, list.size());
+ }
+
+ public void testAnd4() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ //test for parenthesis, "and" should have higher priority
+ Query q = qf.from(User.class)
+ .having("name").eq("Spider")
+ .or(qf.having("name").eq("John"))
+ .and(qf.having("surname").eq("Man"))
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ }
+
+ public void testOr1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("surname").eq("Man")
+ .or().having("surname").eq("Woman")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ for (User u : list) {
+ assertEquals("Spider", u.getName());
+ }
+ }
+
+ public void testOr2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("surname").eq("Man")
+ .or(qf.having("surname").eq("Woman"))
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ for (User u : list) {
+ assertEquals("Spider", u.getName());
+ }
+ }
+
+ public void testOr3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("gender").eq(User.Gender.MALE)
+ .or().having("gender").eq(User.Gender.FEMALE)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ }
+
+ public void testNot1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().having("name").eq("Spider")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals("John", list.get(0).getName());
+ }
+
+ public void testNot2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().not().having("surname").eq("Doe")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals("John", list.get(0).getName());
+ }
+
+ public void testNot3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // NOT should have higher priority than AND
+ Query q = qf.from(User.class)
+ .not().having("name").eq("John")
+ .and().having("surname").eq("Man")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals("Spider", list.get(0).getName());
+ }
+
+ public void testNot4() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // NOT should have higher priority than AND
+ Query q = qf.from(User.class)
+ .having("surname").eq("Man")
+ .and().not().having("name").eq("John")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals("Spider", list.get(0).getName());
+ }
+
+ public void testNot5() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // NOT should have higher priority than OR
+ Query q = qf.from(User.class)
+ .not().having("name").eq("Spider")
+ .or().having("surname").eq("Man")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ for (User u : list) {
+ assertFalse("Woman".equals(u.getSurname()));
+ }
+ }
+
+ public void testNot6() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // QueryFactory.not() test
+ Query q = qf.from(User.class)
+ .not(qf.not(qf.having("gender").eq(User.Gender.FEMALE)))
+ .toBuilder()
+ .build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertTrue(list.get(0).getSurname().equals("Woman"));
+ }
+
+ public void testNot7() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("gender").eq(User.Gender.FEMALE)
+ .and().not(qf.having("name").eq("Spider"))
+ .toBuilder().build();
+
+ List list = q.list();
+ assertTrue(list.isEmpty());
+ }
+
+ public void testEmptyQuery() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class).build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ }
+
+ public void testIsNull() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("addresses").isNull()
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(3, list.get(0).getId());
+ }
+
+ public void testContains1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("accountIds").contains(2)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(1, list.get(0).getId());
+ }
+
+ public void testContains2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("accountIds").contains(42)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(0, list.size());
+ }
+
+ public void testContainsAll1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("accountIds").containsAll(1, 2)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(1, list.get(0).getId());
+ }
+
+ public void testContainsAll2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("accountIds").containsAll(Collections.singleton(1))
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(1, list.get(0).getId());
+ }
+
+ public void testContainsAll3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("accountIds").containsAll(1, 2, 3)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(0, list.size());
+ }
+
+ public void testContainsAll4() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("accountIds").containsAll(Collections.emptySet())
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ }
+
+ public void testContainsAny1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .orderBy("id", SortOrder.ASC)
+ .having("accountIds").containsAny(2, 3)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertEquals(1, list.get(0).getId());
+ assertEquals(2, list.get(1).getId());
+ }
+
+ public void testContainsAny2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("accountIds").containsAny(4, 5)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(0, list.size());
+ }
+
+ public void testContainsAny3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("accountIds").containsAny(Collections.emptySet())
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ }
+
+ public void testIn1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ List ids = Arrays.asList(1, 3);
+ Query q = qf.from(User.class)
+ .having("id").in(ids)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ for (User u : list) {
+ assertTrue(ids.contains(u.getId()));
+ }
+ }
+
+ public void testIn2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("id").in(4)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(0, list.size());
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testIn3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ qf.from(User.class).having("id").in(Collections.emptySet());
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testIn4() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Collection collection = null;
+ qf.from(User.class).having("id").in(collection);
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testIn5() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Object[] array = null;
+ qf.from(User.class).having("id").in(array);
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testIn6() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Object[] array = new Object[0];
+ qf.from(User.class).having("id").in(array);
+ }
+
+ public void testSampleDomainQuery1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all male users
+ Query q = qf.from(User.class)
+ .having("gender").eq(User.Gender.MALE)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertEquals("John", list.get(0).getName());
+ assertEquals("Spider", list.get(1).getName());
+ }
+
+ public void testSampleDomainQuery2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all male users, but this time retrieved in a twisted manner
+ Query q = qf.from(User.class)
+ .not(qf.having("gender").eq(User.Gender.FEMALE))
+ .and(qf.not().not(qf.having("gender").eq(User.Gender.MALE)))
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertEquals("John", list.get(0).getName());
+ assertEquals("Spider", list.get(1).getName());
+ }
+
+ @Test(enabled = false, description = "String literal escaping is not properly done yet, see ISPN-4045") //todo [anistor] fix disabled test
+ public void testStringEscape() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all transactions that have a given description. the description contains characters that need to be escaped.
+ Query q = qf.from(Account.class)
+ .having("description").eq("John Doe's first bank account")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(2, list.get(0).getId());
+ }
+
+ public void testSampleDomainQuery3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all male users
+ Query q = qf.from(User.class)
+ .having("gender").eq(User.Gender.MALE)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertEquals("John", list.get(0).getName());
+ assertEquals("Spider", list.get(1).getName());
+ }
+
+ public void testSampleDomainQuery4() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all users ordered descendingly by name
+ Query q = qf.from(User.class)
+ .orderBy("name", SortOrder.DESC)
+ .build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ assertEquals("Spider", list.get(0).getName());
+ assertEquals("Spider", list.get(1).getName());
+ assertEquals("John", list.get(2).getName());
+ }
+
+ public void testSampleDomainQuery5() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // name projection of all users ordered descendingly by name
+ Query q = qf.from(User.class)
+ .orderBy("name", SortOrder.DESC)
+ .setProjection("name")
+ .build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ assertEquals(1, list.get(0).length);
+ assertEquals(1, list.get(1).length);
+ assertEquals(1, list.get(2).length);
+ assertEquals("Spider", list.get(0)[0]);
+ assertEquals("Spider", list.get(1)[0]);
+ assertEquals("John", list.get(2)[0]);
+ }
+
+ public void testSampleDomainQuery6() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all users with a given name and surname
+ Query q = qf.from(User.class)
+ .having("name").eq("John")
+ .and().having("surname").eq("Doe")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals("John", list.get(0).getName());
+ assertEquals("Doe", list.get(0).getSurname());
+ }
+
+ public void testSampleDomainQuery7() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all rent payments made from a given account
+ Query q = qf.from(Transaction.class)
+ .having("accountId").eq(1)
+ .and().having("description").like("%rent%")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(1, list.get(0).getId());
+ assertEquals(1, list.get(0).getAccountId());
+ assertTrue(list.get(0).getDescription().contains("rent"));
+ }
+
+ public void testSampleDomainQuery8() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all the transactions that happened in January 2013
+ Query q = qf.from(Transaction.class)
+ .orderBy("date", SortOrder.ASC)
+ .having("date").between(DATE_FORMAT.parse("2013-01-01").getTime(), DATE_FORMAT.parse("2013-01-31").getTime())
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(4, list.size());
+
+ assertTrue(list.get(0).getDate() == DATE_FORMAT.parse("2013-01-01").getTime());
+ assertTrue(list.get(1).getDate() > DATE_FORMAT.parse("2013-01-01").getTime());
+ assertTrue(list.get(1).getDate() < DATE_FORMAT.parse("2013-01-31").getTime());
+ assertTrue(list.get(2).getDate() < DATE_FORMAT.parse("2013-01-31").getTime());
+ assertTrue(list.get(2).getDate() > DATE_FORMAT.parse("2013-01-01").getTime());
+ assertTrue(list.get(3).getDate() == DATE_FORMAT.parse("2013-01-31").getTime());
+ }
+
+ public void testSampleDomainQuery9() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all the transactions that happened in January 2013, projected by date field only
+ Query q = qf.from(Transaction.class)
+ .setProjection("date")
+ .having("date").between(DATE_FORMAT.parse("2013-01-01").getTime(), DATE_FORMAT.parse("2013-01-31").getTime())
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(4, list.size());
+ assertEquals(1, list.get(0).length);
+ assertEquals(1, list.get(1).length);
+ assertEquals(1, list.get(2).length);
+ assertEquals(1, list.get(3).length);
+
+ for (int i = 0; i < 4; i++) {
+ Long d = (Long) list.get(i)[0];
+ assertTrue(d <= DATE_FORMAT.parse("2013-01-31").getTime());
+ assertTrue(d >= DATE_FORMAT.parse("2013-01-01").getTime());
+ }
+ }
+
+ public void testSampleDomainQuery10() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all the transactions for a an account having amount greater than a given amount
+ Query q = qf.from(Transaction.class)
+ .having("accountId").eq(2)
+ .and().having("amount").gt(40)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertTrue(list.get(0).getAmount() > 40);
+ assertTrue(list.get(1).getAmount() > 40);
+ }
+
+ public void testSampleDomainQuery11() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("name").eq("John")
+ .and().having("addresses.postCode").eq("X1234")
+ .and(qf.having("accountIds").eq(1))
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals("Doe", list.get(0).getSurname());
+ }
+
+ public void testSampleDomainQuery12() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all the transactions that represents credits to the account
+ Query q = qf.from(Transaction.class)
+ .having("accountId").eq(1)
+ .and()
+ .not().having("isDebit").eq(true).toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertFalse(list.get(0).isDebit());
+ }
+
+ public void testSampleDomainQuery13() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // the user that has the bank account with id 3
+ Query q = qf.from(User.class)
+ .having("accountIds").contains(3).toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(2, list.get(0).getId());
+ assertTrue(list.get(0).getAccountIds().contains(3));
+ }
+
+ public void testSampleDomainQuery14() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // the user that has all the specified bank accounts
+ Query q = qf.from(User.class)
+ .having("accountIds").containsAll(2, 1).toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(1, list.get(0).getId());
+ assertTrue(list.get(0).getAccountIds().contains(1));
+ assertTrue(list.get(0).getAccountIds().contains(2));
+ }
+
+ public void testSampleDomainQuery15() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // the user that has at least one of the specified accounts
+ Query q = qf.from(User.class)
+ .having("accountIds").containsAny(1, 3).toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertTrue(Arrays.asList(1, 2).contains(list.get(0).getId()));
+ assertTrue(Arrays.asList(1, 2).contains(list.get(1).getId()));
+ }
+
+ public void testSampleDomainQuery16() throws Exception {
+ for (int i = 0; i < 50; i++) {
+ Transaction transaction = new Transaction();
+ transaction.setId(50 + i);
+ transaction.setDescription("Expensive shoes " + i);
+ transaction.setAccountId(2);
+ transaction.setAmount(100 + i);
+ transaction.setDate(DATE_FORMAT.parse("2013-08-20"));
+ transaction.setDebit(true);
+ remoteCache.put("transaction_" + transaction.getId(), transaction);
+ }
+
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // third batch of 10 transactions for a given account
+ Query q = qf.from(Transaction.class)
+ .startOffset(20).maxResults(10)
+ .orderBy("id", SortOrder.ASC)
+ .having("accountId").eq(2).and().having("description").like("Expensive%")
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(50, q.getResultSize());
+ assertEquals(10, list.size());
+ for (int i = 0; i < 10; i++) {
+ assertEquals("Expensive shoes " + (20 + i), list.get(i).getDescription());
+ }
+ }
+
+ public void testSampleDomainQuery17() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all accounts for a user. first get the user by id and then get his account.
+ Query q1 = qf.from(User.class)
+ .having("id").eq(1).toBuilder().build();
+
+ List users = q1.list();
+ Query q2 = qf.from(Account.class)
+ .orderBy("description", SortOrder.ASC)
+ .having("id").in(users.get(0).getAccountIds()).toBuilder().build();
+
+ List list = q2.list();
+ assertEquals(2, list.size());
+ assertEquals("John Doe's first bank account", list.get(0).getDescription());
+ assertEquals("John Doe's second bank account", list.get(1).getDescription());
+ }
+
+ public void testSampleDomainQuery18() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ // all transactions of account with id 2 which have an amount larger than 1600 or their description contains the word 'rent'
+ Query q = qf.from(Transaction.class)
+ .having("accountId").eq(1)
+ .and(qf.having("amount").gt(1600)
+ .or().having("description").like("%rent%")).toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertEquals("Birthday present", list.get(0).getDescription());
+ assertEquals("Feb. rent payment", list.get(1).getDescription());
+ }
+
+ public void testProjectionOnOptionalField() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .setProjection("id", "addresses.postCode")
+ .orderBy("id", SortOrder.ASC)
+ .build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ assertEquals(1, list.get(0)[0]);
+ assertEquals("X1234", list.get(0)[1]);
+ assertEquals(2, list.get(1)[0]);
+ assertEquals("Y12", list.get(1)[1]);
+ assertEquals(3, list.get(2)[0]);
+ assertNull(list.get(2)[1]);
+ }
+
+ @Test(enabled = false, description = "Nulls not correctly indexed for numeric properties, see ISPN-4046") //todo [anistor] fix disabled test
+ public void testNullOnIntegerField() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("age").isNull()
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ }
+
+ public void testSampleDomainQuery19() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("addresses.postCode").in("X1234", "ZZ").toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertTrue(Arrays.asList(1, 2).contains(list.get(0).getId()));
+ assertTrue(Arrays.asList(1, 2).contains(list.get(1).getId()));
+ }
+
+ public void testSampleDomainQuery20() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().having("addresses.postCode").in("X1234").toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertTrue(Arrays.asList(2, 3).contains(list.get(0).getId()));
+ assertTrue(Arrays.asList(2, 3).contains(list.get(1).getId()));
+ }
+
+ public void testSampleDomainQuery21() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().having("addresses").isNull().toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertTrue(Arrays.asList(1, 2).contains(list.get(0).getId()));
+ assertTrue(Arrays.asList(1, 2).contains(list.get(1).getId()));
+ }
+
+ public void testSampleDomainQuery22() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().having("addresses.postCode").like("%123%").toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertTrue(Arrays.asList(2, 3).contains(list.get(0).getId()));
+ assertTrue(Arrays.asList(2, 3).contains(list.get(1).getId()));
+ }
+
+ public void testSampleDomainQuery23() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().having("id").between(1, 2)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(1, list.size());
+ assertEquals(3, list.get(0).getId());
+ }
+
+ public void testSampleDomainQuery24() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().having("id").between(1, 2).includeLower(false)
+ .toBuilder().build();
+
+ List list = q.list();
+
+ assertEquals(2, list.size());
+ assertTrue(Arrays.asList(1, 3).contains(list.get(0).getId()));
+ assertTrue(Arrays.asList(1, 3).contains(list.get(1).getId()));
+ }
+
+ public void testSampleDomainQuery25() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().having("id").between(1, 2).includeUpper(false)
+ .toBuilder().build();
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ assertTrue(Arrays.asList(2, 3).contains(list.get(0).getId()));
+ assertTrue(Arrays.asList(2, 3).contains(list.get(1).getId()));
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testWrongQueryBuilding1() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.not().having("name").eq("John").toBuilder().build();
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testWrongQueryBuilding2() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("name").eq("John").toBuilder()
+ .having("surname").eq("Man").toBuilder()
+ .build();
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testWrongQueryBuilding3() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not().having("name").eq("John").toBuilder()
+ .not().having("surname").eq("Man").toBuilder()
+ .build();
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testWrongQueryBuilding4() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not(qf.having("name").eq("John")).toBuilder()
+ .not(qf.having("surname").eq("Man")).toBuilder()
+ .build();
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testWrongQueryBuilding5() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .not(qf.having("name").eq("John")).toBuilder()
+ .not(qf.having("surname").eq("Man")).toBuilder()
+ .build();
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testWrongQueryBuilding6() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .having("gender").eq(null)
+ .toBuilder().build();
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testWrongQueryBuilding7() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ FilterConditionEndContext q1 = qf.from(User.class)
+ .having("gender");
+
+ q1.eq(User.Gender.MALE);
+ q1.eq(User.Gender.FEMALE);
+ }
+
+ public void testDefaultValue() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(Account.class).orderBy("description", SortOrder.ASC).build();
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ assertEquals("Checking account", list.get(0).getDescription());
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslIterationTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslIterationTest.java
new file mode 100644
index 000000000000..83465f239b2e
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryDslIterationTest.java
@@ -0,0 +1,206 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.Search;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.User;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.dsl.Query;
+import org.infinispan.query.dsl.QueryFactory;
+import org.infinispan.query.dsl.SortOrder;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.AssertJUnit.*;
+
+/**
+ * Test for orderBy, max results, start offset and projections.
+ *
+ * @author rvansa@redhat.com
+ * @author anistor@redhat.com
+ * @since 7.0
+ */
+@Test(groups = "functional", testName = "client.hotrod.query.RemoteQueryDslIterationTest")
+public class RemoteQueryDslIterationTest extends SingleCacheManagerTest {
+
+ protected HotRodServer hotRodServer;
+ protected RemoteCacheManager remoteCacheManager;
+ protected RemoteCache remoteCache;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ ConfigurationBuilder builder = getConfigurationBuilder();
+
+ cacheManager = TestCacheManagerFactory.createCacheManager(builder);
+ cache = cacheManager.getCache();
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
+ clientBuilder.addServer().host("127.0.0.1").port(hotRodServer.getPort());
+ clientBuilder.marshaller(new ProtoStreamMarshaller());
+ remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
+ remoteCache = remoteCacheManager.getCache();
+
+ //initialize server-side serialization context
+ cacheManager.getGlobalComponentRegistry().getComponent(ProtobufMetadataManager.class).registerProtofile("/sample_bank_account/bank.protobin");
+
+ //initialize client-side serialization context
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager));
+
+ return cacheManager;
+ }
+
+ protected ConfigurationBuilder getConfigurationBuilder() {
+ ConfigurationBuilder builder = hotRodCacheConfiguration();
+ builder.indexing().enable()
+ .addProperty("default.directory_provider", getLuceneDirectoryProvider())
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+
+ return builder;
+ }
+
+ protected String getLuceneDirectoryProvider() {
+ return "ram";
+ }
+
+ @AfterTest
+ public void release() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotRodServer);
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ protected void populateCache() throws Exception {
+ User user1 = new User();
+ user1.setId(1);
+ user1.setName("John");
+ user1.setSurname("White");
+
+ User user2 = new User();
+ user2.setId(2);
+ user2.setName("Jack");
+ user2.setSurname("Black");
+
+ User user3 = new User();
+ user3.setId(3);
+ user3.setName("John");
+ user3.setSurname("Brown");
+
+ User user4 = new User();
+ user4.setId(4);
+ user4.setName("Michael");
+ user4.setSurname("Black");
+
+ remoteCache.put("user_" + user1.getId(), user1);
+ remoteCache.put("user_" + user2.getId(), user2);
+ remoteCache.put("user_" + user3.getId(), user3);
+ remoteCache.put("user_" + user4.getId(), user4);
+ }
+
+ public void testOrderByAsc() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .orderBy("name", SortOrder.ASC).build();
+
+ assertEquals(4, q.getResultSize());
+
+ List list = q.list();
+ assertEquals(4, list.size());
+ checkNameOrder(list, true);
+ }
+
+ public void testOrderByDesc() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .orderBy("surname", SortOrder.DESC).build();
+
+ assertEquals(4, q.getResultSize());
+
+ List list = q.list();
+ assertEquals(4, list.size());
+ checkSurnameOrder(list, false);
+ }
+
+ public void testMaxResults() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .orderBy("name", SortOrder.ASC).maxResults(2).build();
+
+ assertEquals(4, q.getResultSize());
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ checkNameOrder(list, true);
+ }
+
+ public void testStartOffset() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .orderBy("name", SortOrder.ASC).startOffset(2).build();
+
+ assertEquals(4, q.getResultSize());
+
+ List list = q.list();
+ assertEquals(2, list.size());
+ checkNameOrder(list, true);
+ }
+
+ public void testProjection() throws Exception {
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+
+ Query q = qf.from(User.class)
+ .setProjection("id", "name").maxResults(3).build();
+
+ assertEquals(4, q.getResultSize());
+
+ List list = q.list();
+ assertEquals(3, list.size());
+ for (Object[] u : list) {
+ assertNotNull(u[1]);
+ assertTrue(u[0] instanceof Integer);
+ }
+ }
+
+ private void checkNameOrder(List list, boolean isAsc) {
+ String prevName = null;
+ for (User u : list) {
+ assertNotNull(u.getName());
+ if (prevName != null) {
+ int comp = u.getName().compareTo(prevName);
+ assertTrue(isAsc ? comp >= 0 : comp <= 0);
+ }
+ prevName = u.getName();
+ }
+ }
+
+ private void checkSurnameOrder(List list, boolean isAsc) {
+ String prevSurname = null;
+ for (User u : list) {
+ assertNotNull(u.getSurname());
+ if (prevSurname != null) {
+ int comp = u.getSurname().compareTo(prevSurname);
+ assertTrue(isAsc ? comp >= 0 : comp <= 0);
+ }
+ prevSurname = u.getSurname();
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryJmxTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryJmxTest.java
new file mode 100644
index 000000000000..ec2735988684
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/query/RemoteQueryJmxTest.java
@@ -0,0 +1,196 @@
+package org.infinispan.client.hotrod.query;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.Search;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
+import org.infinispan.commons.CacheException;
+import org.infinispan.commons.equivalence.ByteArrayEquivalence;
+import org.infinispan.commons.util.Util;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.configuration.global.GlobalConfigurationBuilder;
+import org.infinispan.jmx.PerThreadMBeanServerLookup;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.protostream.sampledomain.Address;
+import org.infinispan.protostream.sampledomain.User;
+import org.infinispan.protostream.sampledomain.marshallers.MarshallerRegistration;
+import org.infinispan.query.dsl.Query;
+import org.infinispan.query.dsl.QueryFactory;
+import org.infinispan.query.remote.ProtobufMetadataManager;
+import org.infinispan.query.remote.ProtobufMetadataManagerMBean;
+import org.infinispan.query.remote.indexing.ProtobufValueWrapper;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.CleanupAfterMethod;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.Test;
+import org.infinispan.server.hotrod.HotRodServer;
+
+import javax.management.Attribute;
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killRemoteCacheManager;
+import static org.infinispan.client.hotrod.test.HotRodClientTestingUtil.killServers;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Testing the functionality of JMX operations for the Remote Queries.
+ *
+ * @author Anna Manukyan
+ */
+@Test(testName = "client.hotrod.query.RemoteQueryJmxTest", groups = "functional")
+@CleanupAfterMethod
+public class RemoteQueryJmxTest extends SingleCacheManagerTest {
+ public static final String JMX_DOMAIN = ProtobufMetadataManager.class.getSimpleName();
+
+ public static final String TEST_CACHE_NAME = "userCache";
+
+ private HotRodServer hotRodServer;
+ private RemoteCacheManager remoteCacheManager;
+ private RemoteCache remoteCache;
+ private MBeanServer server = null;
+
+ @Override
+ protected EmbeddedCacheManager createCacheManager() throws Exception {
+ GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder().nonClusteredDefault();
+ gcb.globalJmxStatistics()
+ .enable()
+ .allowDuplicateDomains(true)
+ .jmxDomain(JMX_DOMAIN)
+ .mBeanServerLookup(new PerThreadMBeanServerLookup());
+
+ ConfigurationBuilder builder = new ConfigurationBuilder();
+ builder.dataContainer()
+ .keyEquivalence(ByteArrayEquivalence.INSTANCE)
+ .valueEquivalence(ByteArrayEquivalence.INSTANCE)
+ .indexing().enable()
+ .indexLocalOnly(false)
+ .addProperty("default.directory_provider", getLuceneDirectoryProvider())
+ .addProperty("lucene_version", "LUCENE_CURRENT");
+
+ cacheManager = TestCacheManagerFactory.createCacheManager(gcb, builder, true);
+ cacheManager.defineConfiguration(TEST_CACHE_NAME, builder.build());
+ cache = cacheManager.getCache(TEST_CACHE_NAME);
+
+ hotRodServer = TestHelper.startHotRodServer(cacheManager);
+
+ org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
+ clientBuilder.addServer().host("127.0.0.1").port(hotRodServer.getPort());
+ clientBuilder.marshaller(new ProtoStreamMarshaller());
+ remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
+
+ remoteCache = remoteCacheManager.getCache(TEST_CACHE_NAME);
+
+ ObjectName objName = new ObjectName(JMX_DOMAIN + ":type=RemoteQuery,name="
+ + ObjectName.quote("DefaultCacheManager")
+ + ",component=" + ProtobufMetadataManager.OBJECT_NAME);
+
+ byte[] descriptor = readClasspathResource("/sample_bank_account/bank.protobin");
+ MBeanServer mBeanServer = PerThreadMBeanServerLookup.getThreadMBeanServer();
+ ProtobufMetadataManagerMBean protobufMetadataManagerMBean = JMX.newMBeanProxy(mBeanServer, objName, ProtobufMetadataManagerMBean.class);
+ protobufMetadataManagerMBean.registerProtofile(descriptor);
+
+ //initialize client-side serialization context
+ MarshallerRegistration.registerMarshallers(ProtoStreamMarshaller.getSerializationContext(remoteCacheManager));
+ server = PerThreadMBeanServerLookup.getThreadMBeanServer();
+
+ return cacheManager;
+ }
+
+ private byte[] readClasspathResource(String classPathResource) throws IOException {
+ InputStream is = getClass().getResourceAsStream(classPathResource);
+ try {
+ return Util.readStream(is);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ protected String getLuceneDirectoryProvider() {
+ return "ram";
+ }
+
+ @AfterTest
+ public void release() {
+ killRemoteCacheManager(remoteCacheManager);
+ killServers(hotRodServer);
+ }
+
+ public void testQueryStatsMBean() throws Exception {
+ ObjectName name = getQueryStatsObjectName(JMX_DOMAIN, TEST_CACHE_NAME);
+ assertTrue(server.isRegistered(name));
+ assertFalse((Boolean) server.getAttribute(name, "StatisticsEnabled"));
+ server.setAttribute(name, new Attribute("StatisticsEnabled", true));
+ assertTrue((Boolean) server.getAttribute(name, "StatisticsEnabled"));
+ }
+
+ public void testEmbeddedAttributeQuery() throws Exception {
+ ObjectName name = getQueryStatsObjectName(JMX_DOMAIN, TEST_CACHE_NAME);
+
+ log.tracef("StatisticsEnabled=%s", server.getAttribute(name, "StatisticsEnabled"));
+
+ server.setAttribute(name, new Attribute("StatisticsEnabled", true));
+
+ remoteCache.put(1, createUser(1));
+ remoteCache.put(2, createUser(2));
+
+ // get user back from remote cache via query and check its attributes
+ QueryFactory qf = Search.getQueryFactory(remoteCache);
+ Query query = qf.from(User.class)
+ .having("addresses.postCode").eq("1231").toBuilder()
+ .build();
+ List list = query.list();
+ assertNotNull(list);
+ assertEquals(1, list.size());
+ assertEquals(User.class, list.get(0).getClass());
+ assertEquals("Tom1", list.get(0).getName());
+
+ assertEquals(2, server.invoke(name, "getNumberOfIndexedEntities",
+ new Object[]{ProtobufValueWrapper.class.getCanonicalName()},
+ new String[]{String.class.getCanonicalName()}));
+
+ Set classNames = (Set) server.getAttribute(name, "IndexedClassNames");
+ assertEquals(1, classNames.size());
+ assertTrue("The set should contain the ProtobufValueWrapper class name.", classNames.contains(ProtobufValueWrapper.class.getCanonicalName()));
+ assertTrue("The query execution total time should be > 0.", (Long) server.getAttribute(name, "SearchQueryTotalTime") > 0);
+ assertEquals((long) 1, server.getAttribute(name, "SearchQueryExecutionCount"));
+ }
+
+ private User createUser(int id) {
+ User user = new User();
+ user.setId(id);
+ user.setName("Tom" + id);
+ user.setSurname("Cat" + id);
+ user.setGender(User.Gender.MALE);
+ user.setAccountIds(Collections.singletonList(12));
+ Address address = new Address();
+ address.setStreet("Dark Alley");
+ address.setPostCode("123" + id);
+ user.setAddresses(Collections.singletonList(address));
+ return user;
+ }
+
+ private ObjectName getQueryStatsObjectName(String jmxDomain, String cacheName) {
+ String cacheManagerName = cacheManager.getCacheManagerConfiguration().globalJmxStatistics().cacheManagerName();
+ try {
+ return new ObjectName(jmxDomain + ":type=Query,manager=" + ObjectName.quote(cacheManagerName)
+ + ",cache=" + ObjectName.quote(cacheName) + ",component=Statistics");
+ } catch (MalformedObjectNameException e) {
+ throw new CacheException("Malformed object name", e);
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/AbstractRetryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/AbstractRetryTest.java
new file mode 100644
index 000000000000..426b56d4f693
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/AbstractRetryTest.java
@@ -0,0 +1,109 @@
+package org.infinispan.client.hotrod.retry;
+
+import org.infinispan.client.hotrod.HitsAwareCacheManagersTest;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.client.hotrod.impl.RemoteCacheImpl;
+import org.infinispan.client.hotrod.impl.transport.tcp.RoundRobinBalancingStrategy;
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.TestingUtil;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.AfterMethod;
+
+import java.util.Properties;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+public abstract class AbstractRetryTest extends HitsAwareCacheManagersTest {
+
+ protected HotRodServer hotRodServer1;
+ protected HotRodServer hotRodServer2;
+ protected HotRodServer hotRodServer3;
+
+ RemoteCacheImpl remoteCache;
+ protected RemoteCacheManager remoteCacheManager;
+ protected TcpTransportFactory tcpConnectionFactory;
+ protected ConfigurationBuilder config;
+ protected RoundRobinBalancingStrategy strategy;
+
+ public AbstractRetryTest() {
+ cleanup = CleanupPhase.AFTER_METHOD;
+ }
+
+ @Override
+ protected void assertSupportedConfig() {
+ }
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ assert cleanupAfterMethod();
+
+ config = hotRodCacheConfiguration(getCacheConfig());
+ EmbeddedCacheManager cm1 = TestCacheManagerFactory.createClusteredCacheManager(config);
+ EmbeddedCacheManager cm2 = TestCacheManagerFactory.createClusteredCacheManager(config);
+ EmbeddedCacheManager cm3 = TestCacheManagerFactory.createClusteredCacheManager(config);
+ registerCacheManager(cm1);
+ registerCacheManager(cm2);
+ registerCacheManager(cm3);
+
+ hotRodServer1 = TestHelper.startHotRodServer(manager(0));
+ hrServ2CacheManager.put(getAddress(hotRodServer1), cm1);
+ hotRodServer2 = TestHelper.startHotRodServer(manager(1));
+ hrServ2CacheManager.put(getAddress(hotRodServer2), cm2);
+ hotRodServer3 = TestHelper.startHotRodServer(manager(2));
+ hrServ2CacheManager.put(getAddress(hotRodServer3), cm3);
+
+ waitForClusterToForm();
+
+ Properties clientConfig = new Properties();
+ clientConfig.put("infinispan.client.hotrod.server_list", "localhost:" + hotRodServer2.getPort());
+ clientConfig.put("infinispan.client.hotrod.force_return_values", "true");
+ clientConfig.put("infinispan.client.hotrod.connect_timeout", "5");
+ clientConfig.put("maxActive",1); //this ensures that only one server is active at a time
+
+ remoteCacheManager = new RemoteCacheManager(clientConfig);
+ remoteCache = (RemoteCacheImpl) remoteCacheManager.getCache();
+ tcpConnectionFactory = (TcpTransportFactory) TestingUtil.extractField(remoteCacheManager, "transportFactory");
+ strategy = (RoundRobinBalancingStrategy) tcpConnectionFactory.getBalancer();
+ addInterceptors();
+
+ assert super.cacheManagers.size() == 3;
+ }
+
+ @AfterMethod(alwaysRun = true)
+ @Override
+ protected void clearContent() throws Throwable {
+ // Since cleanup happens after method,
+ // make sure the rest of components are also cleaned up.
+ try {
+ if (remoteCache != null) remoteCache.stop();
+ } finally {
+ try {
+ if (remoteCacheManager != null) remoteCacheManager.stop();
+ } finally {
+ try {
+ if (hotRodServer1 != null) hotRodServer1.stop();
+ } finally {
+ try {
+ if (hotRodServer2 != null) hotRodServer2.stop();
+ } finally {
+ try {
+ if (hotRodServer3 != null) hotRodServer3.stop();
+ } finally {
+ super.clearContent(); // Now stop the cache managers
+ }
+ }
+ }
+ }
+ }
+ }
+
+ protected abstract ConfigurationBuilder getCacheConfig();
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/DistributionRetryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/DistributionRetryTest.java
new file mode 100644
index 000000000000..89dd3f0940b7
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/DistributionRetryTest.java
@@ -0,0 +1,159 @@
+package org.infinispan.client.hotrod.retry;
+
+import org.infinispan.Cache;
+import org.infinispan.affinity.KeyAffinityService;
+import org.infinispan.affinity.KeyAffinityServiceFactory;
+import org.infinispan.affinity.KeyGenerator;
+import org.infinispan.client.hotrod.VersionedValue;
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransport;
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.commons.marshall.Marshaller;
+import org.infinispan.marshall.core.JBossMarshaller;
+import org.infinispan.remoting.transport.Address;
+import org.infinispan.test.TestingUtil;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.Random;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test(testName = "client.hotrod.retry.DistributionRetryTest", groups = "functional")
+public class DistributionRetryTest extends AbstractRetryTest {
+
+ @Override
+ protected ConfigurationBuilder getCacheConfig() {
+ ConfigurationBuilder builder = hotRodCacheConfiguration(
+ getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false));
+ builder.clustering().hash().numOwners(1);
+ return builder;
+ }
+
+ public void testGet() throws Exception {
+ log.info("Starting actual test");
+ Object key = generateKeyAndShutdownServer();
+ //now make sure that next call won't fail
+ resetStats();
+ assertEquals(remoteCache.get(key), "v");
+ }
+
+ public void testPut() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ log.info("Here it starts");
+ assertEquals(remoteCache.put(key, "v0"), "v");
+ }
+
+ public void testRemove() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ assertEquals("v", remoteCache.remove(key));
+ }
+
+ public void testContains() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ resetStats();
+ assertEquals(true, remoteCache.containsKey(key));
+ }
+
+ public void testGetWithVersion() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ resetStats();
+ VersionedValue value = remoteCache.getVersioned(key);
+ assertEquals("v", value.getValue());
+ }
+
+ public void testPutIfAbsent() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ assertEquals(null, remoteCache.putIfAbsent("noSuchKey", "someValue"));
+ assertEquals("someValue", remoteCache.get("noSuchKey"));
+ }
+
+ public void testReplace() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ assertEquals("v", remoteCache.replace(key, "v2"));
+ }
+
+ public void testReplaceIfUnmodified() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ assertEquals(false, remoteCache.replaceWithVersion(key, "v2", 12));
+ }
+
+ public void testRemoveIfUnmodified() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ resetStats();
+ assertEquals(false, remoteCache.removeWithVersion(key, 12));
+ }
+
+ public void testClear() throws Exception {
+ Object key = generateKeyAndShutdownServer();
+ resetStats();
+ remoteCache.clear();
+ assertEquals(false, remoteCache.containsKey(key));
+ }
+
+ private Object generateKeyAndShutdownServer() throws IOException, ClassNotFoundException, InterruptedException {
+ resetStats();
+ Cache cache = manager(1).getCache();
+ ExecutorService ex = Executors.newSingleThreadExecutor();
+ KeyAffinityService kaf = KeyAffinityServiceFactory.newKeyAffinityService(cache, ex, new ByteKeyGenerator(), 2, true);
+ Address address = cache.getAdvancedCache().getRpcManager().getTransport().getAddress();
+ byte[] keyBytes = (byte[]) kaf.getKeyForAddress(address);
+ String key = ByteKeyGenerator.getStringObject(keyBytes);
+ ex.shutdownNow();
+ kaf.stop();
+
+ remoteCache.put(key, "v");
+ assertOnlyServerHit(getAddress(hotRodServer2));
+ TcpTransportFactory tcpTp = (TcpTransportFactory) TestingUtil.extractField(remoteCacheManager, "transportFactory");
+
+ Marshaller sm = new JBossMarshaller();
+ TcpTransport transport = (TcpTransport) tcpTp.getTransport(sm.objectToByteBuffer(key, 64), null);
+ try {
+ assertEquals(transport.getServerAddress(), new InetSocketAddress("localhost", hotRodServer2.getPort()));
+ } finally {
+ tcpTp.releaseTransport(transport);
+ }
+
+
+ log.info("About to stop Hot Rod server 2");
+ hotRodServer2.stop();
+
+
+ return key;
+ }
+
+ public static class ByteKeyGenerator implements KeyGenerator {
+ Random r = new Random();
+ @Override
+ public Object getKey() {
+ String result = String.valueOf(r.nextLong());
+ Marshaller sm = new JBossMarshaller();
+ try {
+ return sm.objectToByteBuffer(result, 64);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String getStringObject(byte[] bytes) {
+ try {
+ Marshaller sm = new JBossMarshaller();
+ return (String) sm.objectFromByteBuffer(bytes);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/ReplicationRetryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/ReplicationRetryTest.java
new file mode 100644
index 000000000000..8691a39fb708
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/ReplicationRetryTest.java
@@ -0,0 +1,141 @@
+package org.infinispan.client.hotrod.retry;
+
+import static org.testng.Assert.assertEquals;
+
+import java.net.SocketAddress;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.infinispan.client.hotrod.VersionedValue;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.testng.annotations.Test;
+
+/**
+ * @author Mircea.Markus@jboss.com
+ * @since 4.1
+ */
+@Test (testName = "client.hotrod.retry.ReplicationRetryTest", groups = "functional")
+public class ReplicationRetryTest extends AbstractRetryTest {
+
+ public void testGet() {
+ validateSequenceAndStopServer();
+ //now make sure that next call won't fail
+ resetStats();
+ for (int i = 0; i < 100; i++) {
+ assert remoteCache.get("k").equals("v");
+ }
+ }
+
+ public void testPut() {
+
+ validateSequenceAndStopServer();
+ resetStats();
+
+ assertEquals(remoteCache.put("k", "v0"), "v");
+ for (int i = 1; i < 100; i++) {
+ assertEquals("v" + (i-1), remoteCache.put("k", "v"+i));
+ }
+ }
+
+ public void testRemove() {
+ validateSequenceAndStopServer();
+ resetStats();
+
+ assertEquals("v", remoteCache.remove("k"));
+ }
+
+ public void testContains() {
+ validateSequenceAndStopServer();
+ resetStats();
+ assertEquals(true, remoteCache.containsKey("k"));
+ }
+
+ public void testGetWithVersion() {
+ validateSequenceAndStopServer();
+ resetStats();
+ VersionedValue value = remoteCache.getVersioned("k");
+ assertEquals("v", value.getValue());
+ }
+
+ public void testPutIfAbsent() {
+ validateSequenceAndStopServer();
+ resetStats();
+ assertEquals(null, remoteCache.putIfAbsent("noSuchKey", "someValue"));
+ assertEquals("someValue", remoteCache.get("noSuchKey"));
+ }
+
+ public void testReplace() {
+ validateSequenceAndStopServer();
+ resetStats();
+ assertEquals("v", remoteCache.replace("k", "v2"));
+ }
+
+ public void testReplaceIfUnmodified() {
+ validateSequenceAndStopServer();
+ resetStats();
+ assertEquals(false, remoteCache.replaceWithVersion("k", "v2", 12));
+ }
+
+ public void testRemoveIfUnmodified() {
+ validateSequenceAndStopServer();
+ resetStats();
+ assertEquals(false, remoteCache.removeWithVersion("k", 12));
+ }
+
+ public void testClear() {
+ validateSequenceAndStopServer();
+ resetStats();
+ remoteCache.clear();
+ assertEquals(false, remoteCache.containsKey("k"));
+ }
+
+ public void testBulkGet() {
+ validateSequenceAndStopServer();
+ resetStats();
+ Map map = remoteCache.getBulk();
+ assertEquals(3, map.size());
+ }
+
+ private void validateSequenceAndStopServer() {
+ resetStats();
+ assertNoHits();
+ SocketAddress expectedServer = strategy.getServers()[strategy.getNextPosition()];
+ assertNoHits();
+ remoteCache.put("k","v");
+
+ assert strategy.getServers().length == 3;
+ assertOnlyServerHit(expectedServer);
+
+ resetStats();
+ expectedServer = strategy.getServers()[strategy.getNextPosition()];
+ remoteCache.put("k2","v2");
+ assertOnlyServerHit(expectedServer);
+
+ resetStats();
+ expectedServer = strategy.getServers()[strategy.getNextPosition()];
+ remoteCache.put("k3","v3");
+ assertOnlyServerHit(expectedServer);
+
+ resetStats();
+ expectedServer = strategy.getServers()[strategy.getNextPosition()];
+ assertEquals("v", remoteCache.put("k","v"));
+ assertOnlyServerHit(expectedServer);
+
+ //this would be the next server to be shutdown
+ expectedServer = strategy.getServers()[strategy.getNextPosition()];
+ HotRodServer toStop = addr2hrServer.get(expectedServer);
+ toStop.stop();
+ for (Iterator ecmIt = cacheManagers.iterator(); ecmIt.hasNext();) {
+ if (ecmIt.next().getAddress().equals(expectedServer)) ecmIt.remove();
+ }
+ waitForClusterToForm();
+ }
+
+ @Override
+ protected ConfigurationBuilder getCacheConfig() {
+ return getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false);
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/RetryOnFailureUnitTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/RetryOnFailureUnitTest.java
new file mode 100644
index 000000000000..9cf3eea815fb
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/RetryOnFailureUnitTest.java
@@ -0,0 +1,106 @@
+package org.infinispan.client.hotrod.retry;
+
+import org.infinispan.client.hotrod.exceptions.HotRodClientException;
+import org.infinispan.client.hotrod.exceptions.RemoteNodeSuspectException;
+import org.infinispan.client.hotrod.exceptions.TransportException;
+import org.infinispan.client.hotrod.impl.ConfigurationProperties;
+import org.infinispan.client.hotrod.impl.operations.RetryOnFailureOperation;
+import org.infinispan.client.hotrod.impl.transport.Transport;
+import org.infinispan.client.hotrod.impl.transport.TransportFactory;
+import org.mockito.Mockito;
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+import java.net.SocketAddress;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+/**
+ * Tests the number of retries.
+ *
+ * @author Pedro Ruivo
+ * @since 7.0
+ */
+@Test(groups = "unit", testName = "client.hotrod.retry.RetryOnFailureUnitTest")
+public class RetryOnFailureUnitTest {
+
+ public void testNoRetryOnTransportFailure() {
+ doRetryTest(0, true);
+ }
+
+ public void testNoRetryOnExecuteFailure() {
+ doRetryTest(0, false);
+ }
+
+ public void testSingleRetryOnTransportFailure() {
+ doRetryTest(1, true);
+ }
+
+ public void testSingleRetryOnExecuteFailure() {
+ doRetryTest(1, false);
+ }
+
+ public void testMultipleRetryOnTransportFailure() {
+ doRetryTest(ConfigurationProperties.DEFAULT_MAX_RETRIES, true);
+ }
+
+ public void testMultipleRetryOnExecuteFailure() {
+ doRetryTest(ConfigurationProperties.DEFAULT_MAX_RETRIES, false);
+ }
+
+ private void doRetryTest(int maxRetry, boolean failOnTransport) {
+ TransportFactory mockTransport = Mockito.mock(TransportFactory.class);
+ Mockito.when(mockTransport.getMaxRetries()).thenReturn(maxRetry);
+ MockOperation mockOperation = new MockOperation(mockTransport, failOnTransport);
+ try {
+ mockOperation.execute();
+ AssertJUnit.fail("Exception expected!");
+ } catch (HotRodClientException expected) {
+ //ignore
+ }
+ if (failOnTransport) {
+ assertEquals("Wrong getTransport() invocation.", maxRetry + 1, mockOperation.transportInvocationCount.get());
+ assertEquals("Wrong execute() invocation.", 0, mockOperation.executeInvocationCount.get());
+ } else {
+ assertEquals("Wrong getTransport() invocation.", maxRetry + 1, mockOperation.transportInvocationCount.get());
+ assertEquals("Wrong execute() invocation.", maxRetry + 1, mockOperation.executeInvocationCount.get());
+ }
+ }
+
+ private class MockOperation extends RetryOnFailureOperation {
+
+ private final AtomicInteger transportInvocationCount;
+ private final AtomicInteger executeInvocationCount;
+ private final boolean failOnTransport;
+
+ public MockOperation(TransportFactory transportFactory, boolean failOnTransport) {
+ super(null, transportFactory, null, null, null);
+ this.failOnTransport = failOnTransport;
+ transportInvocationCount = new AtomicInteger(0);
+ executeInvocationCount = new AtomicInteger(0);
+ }
+
+ @Override
+ protected Transport getTransport(int retryCount, Set failedServers) {
+ transportInvocationCount.incrementAndGet();
+ if (failOnTransport) {
+ throw new TransportException("Induced Failure", null);
+ }
+ //we can return null since it is not used
+ return null;
+ }
+
+ @Override
+ protected Void executeOperation(Transport transport) {
+ executeInvocationCount.incrementAndGet();
+ if (!failOnTransport) {
+ throw new RemoteNodeSuspectException("Induced Failure", 1L, (short) 1);
+ }
+ //we can return null since it is not used
+ return null;
+ }
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/ServerFailureRetryTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/ServerFailureRetryTest.java
new file mode 100644
index 000000000000..434ac57426fe
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/retry/ServerFailureRetryTest.java
@@ -0,0 +1,54 @@
+package org.infinispan.client.hotrod.retry;
+
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
+import org.infinispan.notifications.cachelistener.event.CacheEntryEvent;
+import org.infinispan.remoting.transport.jgroups.SuspectException;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Method;
+
+import static org.infinispan.server.hotrod.test.HotRodTestingUtil.hotRodCacheConfiguration;
+import static org.infinispan.test.TestingUtil.k;
+import static org.infinispan.test.TestingUtil.v;
+
+/**
+ * Test different server error situations and check how clients behave under
+ * those circumstances. Also verify whether failover is happening accordingly.
+ *
+ * @author Galder Zamarreño
+ * @since 4.2
+ */
+@Test(groups = "functional", testName = "client.hotrod.retry.ServerFailureRetryTest")
+public class ServerFailureRetryTest extends AbstractRetryTest {
+
+ @Override
+ protected ConfigurationBuilder getCacheConfig() {
+ return hotRodCacheConfiguration(
+ getDefaultClusteredCacheConfig(CacheMode.REPL_SYNC, false));
+ }
+
+ public void testRetryWithSuspectException(Method m) {
+ ErrorInducingListener listener = new ErrorInducingListener();
+ manager(0).getCache().addListener(listener);
+ try {
+ remoteCache.put(k(m), v(m));
+ } finally {
+ manager(0).getCache().removeListener(listener);
+ }
+ }
+
+ @Listener
+ public static class ErrorInducingListener {
+ boolean induceError = true;
+
+ @CacheEntryCreated
+ public void entryCreated(CacheEntryEvent event) throws Exception {
+ if (!event.isPre() && event.isOriginLocal() && induceError) {
+ throw new SuspectException("Simulated suspicion");
+ }
+ }
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/stress/ClientConsistentHashPerfTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/stress/ClientConsistentHashPerfTest.java
new file mode 100644
index 000000000000..7ec44604f783
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/stress/ClientConsistentHashPerfTest.java
@@ -0,0 +1,63 @@
+package org.infinispan.client.hotrod.stress;
+
+import java.net.SocketAddress;
+
+import org.infinispan.client.hotrod.RemoteCache;
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.impl.consistenthash.ConsistentHash;
+import org.infinispan.client.hotrod.impl.transport.tcp.TcpTransportFactory;
+import org.infinispan.client.hotrod.test.MultiHotRodServersTest;
+import org.infinispan.configuration.cache.CacheMode;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.test.TestingUtil;
+import org.testng.annotations.Test;
+
+/**
+ * Test the performance of ConsistentHashV1/V2.
+ *
+ * @author Dan Berindei
+ * @since 5.3
+ */
+@Test(groups = "profiling", testName = "client.hotrod.stress.ClientConsistentHashPerfTest")
+public class ClientConsistentHashPerfTest extends MultiHotRodServersTest {
+
+ private static final int NUM_SERVERS = 64;
+ private static final int ITERATIONS = 10000000;
+ private static final int NUM_KEYS = 100000;
+
+ @Override
+ protected void createCacheManagers() throws Throwable {
+ ConfigurationBuilder config = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false);
+ createHotRodServers(NUM_SERVERS, config);
+ }
+
+ public void testConsistentHashPerf() throws Exception {
+ RemoteCacheManager rcm = client(0);
+ RemoteCache cache = rcm.getCache();
+ // This will initialize the consistent hash
+ cache.put("k", "v");
+
+ TcpTransportFactory transportFactory = (TcpTransportFactory) TestingUtil.extractField(rcm, "transportFactory");
+ ConsistentHash ch = transportFactory.getConsistentHash();
+ byte[][] keys = new byte[NUM_KEYS][];
+
+ for (int i = 0; i < NUM_KEYS; i++) {
+ keys[i] = String.valueOf(i).getBytes("UTF-8");
+ }
+
+ SocketAddress aServer = null;
+ // warm-up
+ for (int i = 0; i < ITERATIONS/10; i++) {
+ SocketAddress server = ch.getServer(keys[i % keys.length]);
+ if (server != null) aServer = server;
+ }
+
+ long startNanos = System.nanoTime();
+ for (int i = 0; i < ITERATIONS; i++) {
+ SocketAddress server = ch.getServer(keys[i % keys.length]);
+ if (server != null) aServer = server;
+ }
+ double duration = System.nanoTime() - startNanos;
+ log.infof("Test took %.3f s, average CH lookup was %.3f ns", duration / 1000000000L, duration / ITERATIONS);
+ }
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/HotRodClientTestingUtil.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/HotRodClientTestingUtil.java
new file mode 100644
index 000000000000..6be9e73a5996
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/HotRodClientTestingUtil.java
@@ -0,0 +1,84 @@
+package org.infinispan.client.hotrod.test;
+
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.logging.Log;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.util.logging.LogFactory;
+
+/**
+ * Utility methods for the Hot Rod client
+ *
+ * @author Galder Zamarreño
+ * @since 5.1
+ */
+public class HotRodClientTestingUtil {
+
+ 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();
+ } catch (Throwable t) {
+ log.warn("Error stopping remote cache manager", t);
+ }
+ }
+
+ /**
+ * Kills a group of remote cache managers.
+ *
+ * @param rcm
+ * the remote cache manager instances to kill
+ */
+ public static void killRemoteCacheManagers(RemoteCacheManager... rcms) {
+ if (rcms != null) {
+ for (RemoteCacheManager rcm : rcms) {
+ try {
+ if (rcm != null)
+ rcm.stop();
+ } catch (Throwable t) {
+ log.warn("Error stopping remote cache manager", t);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * 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) {
+ try {
+ if (server != null) server.stop();
+ } catch (Throwable t) {
+ log.warn("Error stopping Hot Rod server", t);
+ }
+ }
+ }
+ }
+
+ /**
+ * 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) {
+ try {
+ c.call();
+ } finally {
+ killRemoteCacheManager(c.rcm);
+ }
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/MultiHotRodServersTest.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/MultiHotRodServersTest.java
new file mode 100644
index 000000000000..965bb165e039
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/MultiHotRodServersTest.java
@@ -0,0 +1,91 @@
+package org.infinispan.client.hotrod.test;
+
+import org.infinispan.client.hotrod.RemoteCacheManager;
+import org.infinispan.client.hotrod.TestHelper;
+import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.lifecycle.ComponentStatus;
+import org.infinispan.manager.EmbeddedCacheManager;
+import org.infinispan.server.hotrod.HotRodServer;
+import org.infinispan.test.MultipleCacheManagersTest;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.infinispan.test.TestingUtil.blockUntilCacheStatusAchieved;
+import static org.infinispan.test.TestingUtil.blockUntilViewReceived;
+
+/**
+ * Base test class for Hot Rod tests.
+ *
+ * @author Galder Zamarreño
+ * @since 5.0
+ */
+public abstract class MultiHotRodServersTest extends MultipleCacheManagersTest {
+
+ protected List servers = new ArrayList();
+ protected List clients = new ArrayList();
+
+ protected void createHotRodServers(int num, ConfigurationBuilder defaultBuilder) {
+ // Start Hot Rod servers
+ for (int i = 0; i < num; i++) addHotRodServer(defaultBuilder);
+ // Verify that default caches should be started
+ for (int i = 0; i < num; i++) assert manager(i).getCache() != null;
+ // Block until views have been received
+ blockUntilViewReceived(manager(0).getCache(), num);
+ // Verify that caches running
+ for (int i = 0; i < num; i++) {
+ blockUntilCacheStatusAchieved(
+ manager(i).getCache(), ComponentStatus.RUNNING, 10000);
+ }
+
+ for (int i = 0; i < num; i++) {
+ clients.add(new RemoteCacheManager(createHotRodClientConfigurationBuilder(server(i).getPort()).build()));
+ }
+ }
+
+ protected org.infinispan.client.hotrod.configuration.ConfigurationBuilder createHotRodClientConfigurationBuilder(int serverPort) {
+ org.infinispan.client.hotrod.configuration.ConfigurationBuilder clientBuilder = new org.infinispan.client.hotrod.configuration.ConfigurationBuilder();
+ clientBuilder.addServer()
+ .host("localhost")
+ .port(serverPort)
+ .pingOnStartup(false);
+ return clientBuilder;
+ }
+
+ @AfterMethod(alwaysRun = true)
+ protected void clearContent() throws Throwable {
+ // Do not clear content to allow servers
+ // to stop gracefully and catch any issues there.
+ }
+
+ @AfterClass(alwaysRun = true)
+ @Override
+ protected void destroy() {
+ // Correct order is to stop servers first
+ try {
+ for (HotRodServer server : servers)
+ HotRodClientTestingUtil.killServers(server);
+ } finally {
+ // And then the caches and cache managers
+ super.destroy();
+ }
+ }
+
+ private HotRodServer addHotRodServer(ConfigurationBuilder builder) {
+ EmbeddedCacheManager cm = addClusterEnabledCacheManager(builder);
+ HotRodServer server = TestHelper.startHotRodServer(cm);
+ servers.add(server);
+ return server;
+ }
+
+ protected HotRodServer server(int i) {
+ return servers.get(i);
+ }
+
+ protected RemoteCacheManager client(int i) {
+ return clients.get(i);
+ }
+
+}
diff --git a/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/RemoteCacheManagerCallable.java b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/RemoteCacheManagerCallable.java
new file mode 100644
index 000000000000..92951347c4f4
--- /dev/null
+++ b/client/hotrod-client/src/test/java/org/infinispan/client/hotrod/test/RemoteCacheManagerCallable.java
@@ -0,0 +1,23 @@
+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() {
+ // No-op
+ }
+
+}
diff --git a/core/src/main/java/org/infinispan/container/DataContainer.java b/core/src/main/java/org/infinispan/container/DataContainer.java
index ec1149bac317..bb05ca9326fa 100755
--- a/core/src/main/java/org/infinispan/container/DataContainer.java
+++ b/core/src/main/java/org/infinispan/container/DataContainer.java
@@ -39,12 +39,10 @@ public interface DataContainer extends Iterable {
* while iterating through the data container using methods like {@link #keySet()}
* to avoid changing the underlying collection's order.
*
- *
- *
- * @param key key under which entry is stored
+ * @param k key under which entry is stored
* @return entry, if it exists, or null if not
*/
- InternalCacheEntry peek(Object key);
+ InternalCacheEntry peek(Object k);
/**
* Puts an entry in the cache along with metadata adding information such
@@ -84,13 +82,11 @@ public interface DataContainer extends Iterable {
/**
* Returns a set of keys in the container. When iterating through the container using this method,
- * clients should never call get() method but instead peek(), in order to avoid
+ * clients should never call {@link #get()} method but instead {@link #peek()}, in order to avoid
* changing the order of the underlying collection as a side of effect of iterating through it.
*
* @return a set of keys
*/
- //@org.jetbrains.annotations.NotNull
- ///@org.jetbrains.annotations.NotNull
Set keySet();
/**
diff --git a/core/src/main/java/org/infinispan/container/DefaultDataContainer.java b/core/src/main/java/org/infinispan/container/DefaultDataContainer.java
index 98ad3cece004..7997330d0cbb 100644
--- a/core/src/main/java/org/infinispan/container/DefaultDataContainer.java
+++ b/core/src/main/java/org/infinispan/container/DefaultDataContainer.java
@@ -376,7 +376,7 @@ public void executeTask(final AdvancedCacheLoader.KeyFilter filter, final
ParallelIterableMap map = (ParallelIterableMap) entries;
map.forEach(512, new ParallelIterableMap.KeyValueAction() {
@Override
- public void apply(Object key, InternalCacheEntry value) {
+ public void apply(Object key, InternalCacheEntry value) {
if (filter.shouldLoadKey((K)key)) {
action.apply((K)key, value);
}
diff --git a/core/src/test/java/org/infinispan/configuration/QueryableDataContainer.java b/core/src/test/java/org/infinispan/configuration/QueryableDataContainer.java
index bc78e44d5e05..8b61ca99ba29 100644
--- a/core/src/test/java/org/infinispan/configuration/QueryableDataContainer.java
+++ b/core/src/test/java/org/infinispan/configuration/QueryableDataContainer.java
@@ -45,9 +45,9 @@ public InternalCacheEntry get(Object k) {
}
@Override
- public InternalCacheEntry peek(Object key) {
- loggedOperations.add("peek(" + key + ")" );
- return delegate.peek(key);
+ public InternalCacheEntry peek(Object k) {
+ loggedOperations.add("peek(" + k + ")" );
+ return delegate.peek(k);
}
@Override
diff --git a/core/src/test/java/org/infinispan/eviction/ManualEvictionWithSizeBasedAndConcurrentOperationsInPrimaryOwnerTest.java b/core/src/test/java/org/infinispan/eviction/ManualEvictionWithSizeBasedAndConcurrentOperationsInPrimaryOwnerTest.java
index 6dce11d05713..475fef0e6d72 100644
--- a/core/src/test/java/org/infinispan/eviction/ManualEvictionWithSizeBasedAndConcurrentOperationsInPrimaryOwnerTest.java
+++ b/core/src/test/java/org/infinispan/eviction/ManualEvictionWithSizeBasedAndConcurrentOperationsInPrimaryOwnerTest.java
@@ -433,8 +433,8 @@ public InternalCacheEntry get(Object k) {
}
@Override
- public InternalCacheEntry peek(Object key) {
- return delegate.peek(key);
+ public InternalCacheEntry peek(Object k) {
+ return delegate.peek(k);
}
@Override
diff --git a/jcache/src/main/java/org/infinispan/jcache/JCacheEntry.java b/jcache/src/main/java/org/infinispan/jcache/JCacheEntry.java
index b882a352f240..7a6f47ce9d23 100644
--- a/jcache/src/main/java/org/infinispan/jcache/JCacheEntry.java
+++ b/jcache/src/main/java/org/infinispan/jcache/JCacheEntry.java
@@ -40,4 +40,3 @@ public T unwrap(Class clazz) {
}
}
-
diff --git a/maven-settings.xml b/maven-settings.xml
deleted file mode 100644
index 154fd3505e19..000000000000
--- a/maven-settings.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
- org.jboss.maven.plugins
-
-
-
-
-
-
-
-
-
- jboss-public-repository
-
-
- jboss-public-repository-group
- JBoss Public Maven Repository Group
- https://repository.jboss.org/nexus/content/groups/public-jboss/
- default
-
- true
- never
-
-
- true
- never
-
-
-
-
-
- jboss-public-repository-group
- JBoss Public Maven Repository Group
- https://repository.jboss.org/nexus/content/groups/public-jboss/
- default
-
- true
- never
-
-
- true
- never
-
-
-
-
-
-
-
- redhat-earlyaccess-repository
-
-
- redhat-earlyaccess-repository-group
- Red Hat early access repository
- http://maven.repository.redhat.com/earlyaccess/all/
- default
-
- true
- never
-
-
- true
- never
-
-
-
-
-
-
-
-
- jboss-public-repository
- redhat-earlyaccess-repository
-
-
-
-
diff --git a/maven-settings.xml.redhat b/maven-settings.xml.redhat
index 154fd3505e19..8bd8b00d258d 100644
--- a/maven-settings.xml.redhat
+++ b/maven-settings.xml.redhat
@@ -6,39 +6,7 @@
org.jboss.maven.plugins
-
-
-
-
-
-
jboss-public-repository
diff --git a/off-heap/pom.xml.off-heap b/off-heap/pom.xml.off-heap
new file mode 100644
index 000000000000..0fe221ea5a17
--- /dev/null
+++ b/off-heap/pom.xml.off-heap
@@ -0,0 +1,294 @@
+
+
+ 4.0.0
+
+
+ org.infinispan
+ infinispan-parent
+ 7.0.0-SNAPSHOT
+ parent/pom.xml
+
+
+ infinispan
+
+ Infinispan Distribution
+ Builds the complete Infinispan distribution bundles
+ pom
+
+
+ bom
+ checkstyle
+ parent
+ commons
+ core
+ extended-statistics
+ tools
+ query
+ query-dsl
+ remote-query/remote-query-client
+ remote-query/remote-query-server
+ tree
+ lucene
+ lucene/lucene-directory
+ lucene/lucene-v4
+ lucene/lucene-v3
+ persistence
+ persistence/jdbc
+ persistence/remote
+ persistence/cli
+ persistence/leveldb
+ persistence/rest
+ server
+ server/core
+ server/memcached
+ server/hotrod
+ server/websocket
+ server/rest
+ client/hotrod-client
+
+ spring
+ cli/cli-server
+ cli/cli-client
+ demos/gui
+ demos/ec2
+ demos/distexec
+ demos/ec2-ui
+ demos/directory
+ demos/lucene-directory-demo
+ demos/gridfs-webdav
+ demos/nearcache
+ demos/nearcache-client
+ cdi/extension
+ as-modules
+ integrationtests/luceneintegration
+ integrationtests/as-integration
+ integrationtests/compatibility-mode-it
+ integrationtests/cdi-jcache-it
+ jcache
+ server/integration
+ off-heap
+
+
+
+
+ distribution
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ javadoc
+ prepare-package
+
+ aggregate
+
+
+ true
+
+ ${basedir}/src/javadoc/stylesheet.css
+ ${basedir}/src/javadoc
+ true
+
+ http://docs.oracle.com/javase/6/docs/api/
+ http://docs.oracle.com/javaee/5/api/
+
+
+
+
+
+
+
+
+
+ minimal-distribution
+
+ false
+
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+ build-test-jar
+ none
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ assemble
+ package
+
+ single
+
+
+
+
+
+ src/main/resources/assemblies/all.xml
+
+ ${project.artifactId}-${project.version}
+ ${buildDirectory}/distribution
+ ${buildDirectory}/assembly/work
+
+
+
+
+
+
+
+
+ jmxdoc
+
+ false
+
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ org.infinispan.tools.doclet.jmx.JmxDoclet
+
+ org.infinispan
+ infinispan-tools
+ ${project.version}
+
+
+
+
+
+ javadoc
+ package
+
+ aggregate
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+
+
+ xsdocgen
+ package
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.infinispan
+ infinispan-tools
+ ${project.version}
+
+
+
+
+
+
+
+
diff --git a/remote-query/remote-query-server/src/main/java/org/infinispan/query/remote/QueryFacadeImpl.java b/remote-query/remote-query-server/src/main/java/org/infinispan/query/remote/QueryFacadeImpl.java
index 192d0d408d40..34d9f7c949ef 100644
--- a/remote-query/remote-query-server/src/main/java/org/infinispan/query/remote/QueryFacadeImpl.java
+++ b/remote-query/remote-query-server/src/main/java/org/infinispan/query/remote/QueryFacadeImpl.java
@@ -32,7 +32,7 @@
import org.infinispan.query.remote.search.NullEncodingFloatNumericFieldBridge;
import org.infinispan.query.remote.search.NullEncodingIntegerNumericFieldBridge;
import org.infinispan.query.remote.search.NullEncodingLongNumericFieldBridge;
-//import org.infinispan.server.core.QueryFacade;
+import org.infinispan.server.core.QueryFacade;
import java.io.IOException;
import java.util.ArrayList;
@@ -42,7 +42,7 @@
* @author anistor@redhat.com
* @since 6.0
*/
-public class QueryFacadeImpl /* implements QueryFacade */ {
+public class QueryFacadeImpl implements QueryFacade {
/**
* A special hidden Lucene document field that holds the actual protobuf type name.
@@ -55,7 +55,7 @@ public class QueryFacadeImpl /* implements QueryFacade */ {
*/
public static final String NULL_TOKEN = "_null_";
- //@Override
+ @Override
public byte[] query(AdvancedCache cache, byte[] query) {
if (!cache.getCacheConfiguration().indexing().enabled()) {
throw new CacheException("Indexing is not enabled for cache " + cache.getName());
diff --git a/remote-query/remote-query-server/src/test/java/org/infinispan/query/remote/QueryFacadeImplTest.java b/remote-query/remote-query-server/src/test/java/org/infinispan/query/remote/QueryFacadeImplTest.java
index 8f72a8783998..1881f012d52d 100644
--- a/remote-query/remote-query-server/src/test/java/org/infinispan/query/remote/QueryFacadeImplTest.java
+++ b/remote-query/remote-query-server/src/test/java/org/infinispan/query/remote/QueryFacadeImplTest.java
@@ -1,6 +1,6 @@
package org.infinispan.query.remote;
-//import org.infinispan.server.core.QueryFacade;
+import org.infinispan.server.core.QueryFacade;
import org.testng.annotations.Test;
import java.util.ArrayList;
@@ -18,7 +18,7 @@ public class QueryFacadeImplTest {
/**
* Test there is exactly one loadable provider.
-
+ */
public void testProvider() {
List implementations = new ArrayList();
for (QueryFacade impl : ServiceLoader.load(QueryFacade.class)) {
@@ -28,5 +28,4 @@ public void testProvider() {
assertEquals(1, implementations.size());
assertEquals(QueryFacadeImpl.class, implementations.get(0).getClass());
}
- */
}