From 7bcac324f7f2fade31f1741948ee783d1402a796 Mon Sep 17 00:00:00 2001 From: Vittorio Rigamonti Date: Fri, 3 Aug 2018 16:56:42 +0200 Subject: [PATCH 1/6] HRCPP-465 Transactions implementation --- src/Infinispan.HotRod/Config/Configuration.cs | 18 +++++++++++++++ .../Config/ConfigurationBuilder.cs | 7 +++++- src/Infinispan.HotRod/RemoteCacheManager.cs | 9 ++++++++ src/Infinispan.HotRod/SWIG/Configuration.cs | 2 ++ .../SWIG/ConfigurationBuilder.cs | 1 + .../SWIG/RemoteCacheManager.cs | 1 + .../SWIG/TransactionManager.cs | 23 +++++++++++++++++++ swig/hotrod_arch.i | 23 +++++++++++++++++++ swig/hotrodcs.i | 12 ++++++++++ 9 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/Infinispan.HotRod/SWIG/TransactionManager.cs diff --git a/src/Infinispan.HotRod/Config/Configuration.cs b/src/Infinispan.HotRod/Config/Configuration.cs index 82832ebc..a0d1245f 100644 --- a/src/Infinispan.HotRod/Config/Configuration.cs +++ b/src/Infinispan.HotRod/Config/Configuration.cs @@ -130,5 +130,23 @@ public IMarshaller Marshaller() { return marshaller; } + + /// + /// Check if this configuration enables transactional operation + /// + /// + public bool IsTransactional() + { + return config.isTransactional(); + } + + /// + /// Enable disable transactional operations + /// + /// true enables transactional operations + public void SetTransactional(bool t) + { + config.setTransactional(t); + } } } \ No newline at end of file diff --git a/src/Infinispan.HotRod/Config/ConfigurationBuilder.cs b/src/Infinispan.HotRod/Config/ConfigurationBuilder.cs index c057c144..763c4707 100644 --- a/src/Infinispan.HotRod/Config/ConfigurationBuilder.cs +++ b/src/Infinispan.HotRod/Config/ConfigurationBuilder.cs @@ -135,7 +135,12 @@ public ConfigurationBuilder Marshaller(IMarshaller marshaller) this.marshaller = marshaller; return this; } - + + public ConfigurationBuilder Transactional(bool t) + { + builder.SetTransactional(t); + return this; + } } #pragma warning restore 1591 } diff --git a/src/Infinispan.HotRod/RemoteCacheManager.cs b/src/Infinispan.HotRod/RemoteCacheManager.cs index 67562582..53d33a1c 100644 --- a/src/Infinispan.HotRod/RemoteCacheManager.cs +++ b/src/Infinispan.HotRod/RemoteCacheManager.cs @@ -256,5 +256,14 @@ public ISet GetCacheNames() { return manager.GetCacheNames(); } + + /// + /// Return the transaction manager + /// + /// + public Infinispan.HotRod.SWIG.TransactionManager GetTransactionManager() + { + return manager.GetTransactionManager(); + } } } diff --git a/src/Infinispan.HotRod/SWIG/Configuration.cs b/src/Infinispan.HotRod/SWIG/Configuration.cs index bd282c50..52d3a2c1 100644 --- a/src/Infinispan.HotRod/SWIG/Configuration.cs +++ b/src/Infinispan.HotRod/SWIG/Configuration.cs @@ -21,5 +21,7 @@ internal interface Configuration IList Servers(); Dictionary> GetServersMapConfiguration(); + bool isTransactional(); + void setTransactional(bool t); } } \ No newline at end of file diff --git a/src/Infinispan.HotRod/SWIG/ConfigurationBuilder.cs b/src/Infinispan.HotRod/SWIG/ConfigurationBuilder.cs index 60f99263..5fb4c0cd 100644 --- a/src/Infinispan.HotRod/SWIG/ConfigurationBuilder.cs +++ b/src/Infinispan.HotRod/SWIG/ConfigurationBuilder.cs @@ -28,5 +28,6 @@ internal interface ConfigurationBuilder ConfigurationBuilder ValueSizeEstimate(int valueSizeEstimate); ConfigurationBuilder MaxRetries(int maxRetries); ConfigurationBuilder BalancingStrategyProducer(Infinispan.HotRod.Config.FailOverRequestBalancingStrategyProducerDelegate bsp); + ConfigurationBuilder SetTransactional(bool t); } } diff --git a/src/Infinispan.HotRod/SWIG/RemoteCacheManager.cs b/src/Infinispan.HotRod/SWIG/RemoteCacheManager.cs index 8e46721b..d7176298 100644 --- a/src/Infinispan.HotRod/SWIG/RemoteCacheManager.cs +++ b/src/Infinispan.HotRod/SWIG/RemoteCacheManager.cs @@ -16,5 +16,6 @@ internal interface RemoteCacheManager RemoteCounterManager GetCounterManager(); Infinispan.HotRod.SWIGGen.RemoteCacheManagerAdmin administration(); System.Collections.Generic.ISet GetCacheNames(); + TransactionManager GetTransactionManager(); } } diff --git a/src/Infinispan.HotRod/SWIG/TransactionManager.cs b/src/Infinispan.HotRod/SWIG/TransactionManager.cs new file mode 100644 index 00000000..c1e535a3 --- /dev/null +++ b/src/Infinispan.HotRod/SWIG/TransactionManager.cs @@ -0,0 +1,23 @@ +using System; + +namespace Infinispan.HotRod.SWIG +{ + /// + /// This class contains method to start commit and rollback a transaction + /// + public interface TransactionManager + { + /// + /// Begin a transaction + /// + void Begin(); + /// + /// Commit a transaction + /// + void Commit(); + /// + /// Rollback a transaction + /// + void Rollback(); + } +} diff --git a/swig/hotrod_arch.i b/swig/hotrod_arch.i index f807ea99..ede832f5 100644 --- a/swig/hotrod_arch.i +++ b/swig/hotrod_arch.i @@ -74,6 +74,10 @@ return this; } + public Infinispan.HotRod.SWIG.ConfigurationBuilder SetTransactional(bool t) { + return setTransactional(t); + } + %} %typemap(csinterfaces_derived) infinispan::hotrod::ServerConfigurationBuilder "IDisposable, Infinispan.HotRod.SWIG.ServerConfigurationBuilder" @@ -351,12 +355,26 @@ public System.Collections.Generic.Dictionary "IDisposable, Infinispan.HotRod.SWIG.RemoteByteArrayCache" %typemap(csinterfaces) infinispan::hotrod::RemoteCacheManager "IDisposable, Infinispan.HotRod.SWIG.RemoteCacheManager" +%typemap(csinterfaces) infinispan::hotrod::TransactionManager "IDisposable, Infinispan.HotRod.SWIG.TransactionManager" %typemap(csinterfaces) infinispan::hotrod::RemoteCounterManager "IDisposable, Infinispan.HotRod.RemoteCounterManager" %typemap(csinterfaces) infinispan::hotrod::Counter "IDisposable, Infinispan.HotRod.Counter" %typemap(csinterfaces_derived) infinispan::hotrod::StrongCounter "IDisposable, Infinispan.HotRod.StrongCounter" %typemap(csinterfaces_derived) infinispan::hotrod::WeakCounter "IDisposable, Infinispan.HotRod.WeakCounter" %typemap(csinterfaces) infinispan::hotrod::CounterConfiguration "IDisposable, Infinispan.HotRod.ICounterConfiguration" +%typemap(cscode) infinispan::hotrod::TransactionManager %{ + public void Begin() { + begin(); + } + + public void Commit() { + commit(); + } + + public void Rollback() { + rollback(); + } +%} %typemap(cscode) infinispan::hotrod::RemoteCacheManager %{ public void Start() { start(); @@ -409,6 +427,11 @@ public System.Collections.Generic.Dictionary #include #include +#include +#include #include #include #include @@ -69,6 +73,7 @@ namespace org { namespace infinispan { namespace query { namespace remote { name %typemap(csclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "internal class" %typemap(csclassmodifiers) enum SWIGTYPE "internal enum" + /* Force a common interface between the 32 and 64 bit wrapper code. */ %include "hotrod_arch.i" @@ -179,6 +184,11 @@ static int getpath(void *context, const char ** path) { %ignore infinispan::hotrod::event::ClientCacheEntryCustomEvent; %ignore infinispan::hotrod::event::DotNetClientListener::getFailoverFunction; %ignore getBalancingStrategy; +%ignore infinispan::hotrod::TransactionContext; +%ignore infinispan::hotrod::SynchronizationAdapter; +%ignore infinispan::hotrod::XID; +%ignore infinispan::hotrod::TransactionTable; + %include "infinispan/hotrod/ClientEvent.h" %include "infinispan/hotrod/ClientListener.h" @@ -202,6 +212,8 @@ static int getpath(void *context, const char ** path) { %include "infinispan/hotrod/RemoteCacheBase.h" %include "infinispan/hotrod/RemoteCache.h" +%include "infinispan/hotrod/TransactionManager.h" +%include "infinispan/hotrod/Transactions.h" %include "infinispan/hotrod/RemoteCacheManager.h" %include "infinispan/hotrod/CounterConfiguration.h" %include "infinispan/hotrod/CounterEvent.h" From 9fe78b3e6e3d1345d7561ba7230d2bae6d5a7225 Mon Sep 17 00:00:00 2001 From: Vittorio Rigamonti Date: Fri, 3 Aug 2018 16:58:54 +0200 Subject: [PATCH 2/6] HRCPP-465 Transactions test --- CMakeLists.txt | 1 + Jenkinsfile | 6 +- .../TransactionTest.cs | 307 ++++++++++++++++++ test/resources/standalone.xml | 302 +++++++++++++++++ 4 files changed, 613 insertions(+), 3 deletions(-) create mode 100644 test/Infinispan.HotRod.Tests/TransactionTest.cs create mode 100644 test/resources/standalone.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index de64a068..3929a945 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -416,6 +416,7 @@ if (NOT DEFINED ENABLE_CSHARP_TESTING OR ENABLE_CSHARP_TESTING) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/resources/standalone-hotrod-ssl.xml DESTINATION "${JBOSS_HOME}/standalone/configuration") file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/resources/clustered-sasl-cs.xml DESTINATION "${JBOSS_HOME}/standalone/configuration") file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/resources/clustered.xml DESTINATION "${JBOSS_HOME}/standalone/configuration") + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/resources/standalone.xml DESTINATION "${JBOSS_HOME}/standalone/configuration") file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/resources/certificates/keystore.jks DESTINATION "${JBOSS_HOME}/standalone/configuration") file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/resources/certificates/truststore.jks DESTINATION "${JBOSS_HOME}/standalone/configuration") file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/resources/certificates/keystore_server_sni1_rsa.jks DESTINATION "${JBOSS_HOME}/standalone/configuration") diff --git a/Jenkinsfile b/Jenkinsfile index f9d734ce..6e894604 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,7 +11,7 @@ pipeline { cppTag = '8.1.0.Final' CMAKE_HOME = 'C:\\\\PROGRA~2\\\\CMake\\\\bin' generator = '"Visual Studio 14 2015 Win64"' - INFINISPAN_VERSION = '9.2.3.Final' + INFINISPAN_VERSION = '9.3.1.Final' JAVA_HOME = 'C:\\\\PROGRA~1\\\\JAVA\\\\JDK18~1.0_7' M2_HOME = 'C:\\\\APACHE~1.9' MVN_PROGRAM = 'C:\\\\APACHE~1.9\\\\BIN\\\\MVN.BAT' @@ -57,8 +57,8 @@ pipeline { GOOGLE_PROTOBUF_NUPKG = 'C:\\\\Users\\\\Administrator' HOTROD_SNK = 'c:\\\\data\\\\hotrod_cs.key' IKVM_CUSTOM_BIN_PATH = 'C:\\\\Users\\\\Administrator\\\\ikvm-8.1.5717.0\\\\bin' - INFINISPAN_VERSION = '9.2.3.Final' - JBOSS_HOME = 'Y:\\\\cpp-client\\\\infinispan-server-9.2.3.Final' + INFINISPAN_VERSION = '9.3.1.Final' + JBOSS_HOME = 'Y:\\\\cpp-client\\\\infinispan-server-9.3.1.Final' JAVA_HOME = 'C:\\\\PROGRA~1\\\\JAVA\\\\JDK18~1.0_7' M2_HOME = 'C:\\\\APACHE~1.9' MAVEN_OPTS = '"-Dmaven.multiModuleProjectDirectory=C:\\\\APACHE~1.9"' diff --git a/test/Infinispan.HotRod.Tests/TransactionTest.cs b/test/Infinispan.HotRod.Tests/TransactionTest.cs new file mode 100644 index 00000000..4caec3c4 --- /dev/null +++ b/test/Infinispan.HotRod.Tests/TransactionTest.cs @@ -0,0 +1,307 @@ +using Infinispan.HotRod.Config; +using Infinispan.HotRod.Exceptions; +using System.Collections.Generic; +using System.Threading.Tasks; +using NUnit.Framework; +using Infinispan.HotRod.Tests.Util; + + +namespace Infinispan.HotRod.Tests.StandaloneXml +{ + [TestFixture] + [Category("standalone_xml")] + [Category("DefaultTestSuite")] + public class TransactionTest + { + RemoteCacheManager remoteManager; + RemoteCacheManager nonTxRemoteManager; + + IMarshaller marshaller; + IMarshaller nonTxMarshaller; + + HotRodServer server1; + HotRodServer server2; + + private void InitializeRemoteCacheManager(bool started) + { + ConfigurationBuilder conf = new ConfigurationBuilder(); + conf.AddServer().Host("127.0.0.1").Port(11222); + conf.ConnectionTimeout(90000).SocketTimeout(6000).Transactional(true); + conf.ProtocolVersion("2.7"); + marshaller = new JBasicMarshaller(); + conf.Marshaller(marshaller); + remoteManager = new RemoteCacheManager(conf.Build(), started); + } + + private void InitializeNonTxRemoteCacheManager(bool started) + { + ConfigurationBuilder conf = new ConfigurationBuilder(); + conf.AddServer().Host("127.0.0.1").Port(11222); + conf.ConnectionTimeout(90000).SocketTimeout(6000); + conf.ProtocolVersion("2.7"); + nonTxMarshaller = new JBasicMarshaller(); + conf.Marshaller(marshaller); + nonTxRemoteManager = new RemoteCacheManager(conf.Build(), started); + } + + + [Test] + public void ReadCommitted() + { + InitializeRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string v1 = "boron"; + + cache.Clear(); + + txManager.Begin(); + cache.Put(k1, v1); + // Check the correct value from the tx context + string rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + txManager.Commit(); + // Check the correct value from remote cache + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + } + + [Test] + public void ReadRollbackOnNotExistent() + { + InitializeRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string v1 = "boron"; + + cache.Clear(); + + txManager.Begin(); + cache.Put(k1, v1); + // Check the correct value from the tx context + string rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + txManager.Rollback(); + // Check the correct value from remote cache + rv1 = cache.Get(k1); + Assert.IsNull(rv1); + } + + // Client must read last value both during the tx (from the context) + // and after the commit (from the cache) + [Test] + public void ChangeExistentAndCommit() + { + InitializeRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string v0 = "carbon"; + string v1 = "boron"; + + cache.Clear(); + cache.Put(k1, v0); + txManager.Begin(); + cache.Put(k1, v1); + // Check the correct value from the tx context + string rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + txManager.Commit(); + // Check the correct value from remote cache + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + } + + // Client must read last value during the tx (from the context) + // and the old value from the cache after the rollback + [Test] + public void ReadRollbackOnExistent() + { + InitializeRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string oldv = "oxygen"; + string v1 = "boron"; + + cache.Clear(); + + string oldrv1 = cache.Put(k1, oldv); + Assert.IsNull(oldrv1); + + txManager.Begin(); + oldrv1 = cache.Put(k1, v1); + Assert.AreEqual(oldrv1, oldv); + // Check the correct value from the tx context + string rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + txManager.Rollback(); + // Check the correct value from remote cache + rv1 = cache.Get(k1); + Assert.AreEqual(oldrv1, oldv); + } + + // Client must read last value during the tx (from the context) + [Test] + public void ReadInTransactionContext() + { + InitializeRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string v1 = "boron"; + + cache.Clear(); + + txManager.Begin(); + + string oldv1 = cache.Put(k1, v1); + // Check the correct value from the tx context + string rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + cache.Remove(k1); + rv1 = cache.Get(k1); + Assert.IsNull(rv1); + txManager.Rollback(); + } + + // TX Client must read last value during the tx (from the context) + // NONTX client must read old value from the cache + [Test] + public void ReadCommittedAndNonTxRead() + { + InitializeRemoteCacheManager(true); + InitializeNonTxRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + IRemoteCache nonTxCache = nonTxRemoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string v1 = "boron"; + + cache.Clear(); + + txManager.Begin(); + + cache.Put(k1, v1); + // Check the correct value from the tx context + string rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + + string nontxrv1 = nonTxCache.Get(k1); + Assert.IsNull(nontxrv1); + txManager.Commit(); + // Check the correct value from remote cache + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + nontxrv1 = nonTxCache.Get(k1); + Assert.AreEqual(nontxrv1, v1); + } + + // NONTX client must put/get values from the cache + [Test] + public void PutAndReadWithNonTxCache() + { + InitializeRemoteCacheManager(true); + InitializeNonTxRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + IRemoteCache nonTxCache = nonTxRemoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string v1 = "boron"; + + cache.Clear(); + + txManager.Begin(); + string oldv1 = nonTxCache.Put(k1, v1); + // Check the correct value from the tx context + string rv1 = nonTxCache.Get(k1); + Assert.AreEqual(rv1, v1); + rv1 = cache.Remove(k1); + rv1 = cache.Get(k1); + Assert.IsNull(rv1); + txManager.Rollback(); + + rv1 = nonTxCache.Get(k1); + Assert.AreEqual(rv1, v1); + } + + // NONTX client must put/get values from the cache + [Test] + public void RepeatableGetForTxClient() + { + InitializeRemoteCacheManager(true); + InitializeNonTxRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + IRemoteCache nonTxCache = nonTxRemoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string v1 = "boron"; + string v2 = "helium"; + + cache.Clear(); + + txManager.Begin(); + + string oldv1 = nonTxCache.Put(k1, v1); + // Check the correct value from the tx context + string rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + + // This goes to the server + oldv1 = nonTxCache.Put(k1, v2); + + // But this values comes from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + + cache.Remove(k1); + rv1 = cache.Get(k1); + Assert.IsNull(rv1); + txManager.Rollback(); + + rv1 = nonTxCache.Get(k1); + Assert.AreEqual(rv1, v2); + } + // NONTX client must put/get values from the cache + [Test] + public void ConflictsAndFail() + { + InitializeRemoteCacheManager(true); + InitializeNonTxRemoteCacheManager(true); + IRemoteCache cache = remoteManager.GetCache("non_xa", true); + IRemoteCache nonTxCache = nonTxRemoteManager.GetCache("non_xa", true); + var txManager = remoteManager.GetTransactionManager(); + + string k1 = "key13"; + string v1 = "boron"; + string k2 = "key14"; + string v2 = "helium"; + + string vx = "calcium"; + + cache.Clear(); + + txManager.Begin(); + + string oldv1 = cache.Put(k1, v1); + string oldv2 = cache.Put(k2, v2); + // Check the correct value from the tx context + string rv1 = nonTxCache.Put(k1, vx); + Assert.IsNull(rv1); + txManager.Commit(); + Assert.AreEqual(cache.Get(k1), vx); + Assert.IsNull(cache.Get(k2)); + } + + } +} diff --git a/test/resources/standalone.xml b/test/resources/standalone.xml new file mode 100644 index 00000000..c8ebff96 --- /dev/null +++ b/test/resources/standalone.xml @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f62516ab8fa2bdbdab630ea71ffe5150664148a8 Mon Sep 17 00:00:00 2001 From: Vittorio Rigamonti Date: Fri, 3 Aug 2018 17:00:04 +0200 Subject: [PATCH 3/6] fixed permission for supervisor --- test/resources/clustered-sasl-cs.xml | 2 +- test/resources/standalone-hotrod-ssl.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/resources/clustered-sasl-cs.xml b/test/resources/clustered-sasl-cs.xml index 43efa238..5597d17c 100644 --- a/test/resources/clustered-sasl-cs.xml +++ b/test/resources/clustered-sasl-cs.xml @@ -176,7 +176,7 @@ - + diff --git a/test/resources/standalone-hotrod-ssl.xml b/test/resources/standalone-hotrod-ssl.xml index adde4922..872a34e7 100644 --- a/test/resources/standalone-hotrod-ssl.xml +++ b/test/resources/standalone-hotrod-ssl.xml @@ -174,7 +174,7 @@ - + From acff70e37c82562df24f29679e224a3b419e4eaa Mon Sep 17 00:00:00 2001 From: Vittorio Rigamonti Date: Fri, 3 Aug 2018 17:00:45 +0200 Subject: [PATCH 4/6] ignoring two tests due to ISPN-9409 --- test/Infinispan.HotRod.Tests/RemoteEventTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/Infinispan.HotRod.Tests/RemoteEventTest.cs b/test/Infinispan.HotRod.Tests/RemoteEventTest.cs index e3e0e0b9..a533d18e 100644 --- a/test/Infinispan.HotRod.Tests/RemoteEventTest.cs +++ b/test/Infinispan.HotRod.Tests/RemoteEventTest.cs @@ -139,6 +139,7 @@ public void ConditionalEventsTest() } [Test] + [Ignore("ISPN-9409")] public void CustomEventsTest() { LoggingEventListener listener = new LoggingEventListener(); @@ -169,6 +170,7 @@ public void CustomEventsTest() } [Test] + [Ignore("ISPN-9409")] public void FilterEventsTest() { LoggingEventListener listener = new LoggingEventListener(); From 11b63e5cfead398aa9dce6a9a03abf0a9813001c Mon Sep 17 00:00:00 2001 From: Vittorio Rigamonti Date: Fri, 3 Aug 2018 18:19:54 +0200 Subject: [PATCH 5/6] point to the correct swig.exe --- CMakeLists.txt | 2 +- Jenkinsfile | 7 +++---- build.bat | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3929a945..726cfa68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,7 @@ if (WIN32) add_custom_target( swig ALL - COMMAND cmake -G "${CMAKE_GENERATOR}" "-DHOTRODCPP_HOME=${NATIVE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/swig" + COMMAND cmake -G "${CMAKE_GENERATOR}" "-DHOTRODCPP_HOME=${NATIVE_DIR}" "-DSWIG_DIR=${SWIG_DIR}" "-DSWIG_EXECUTABLE=${SWIG_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/swig" COMMAND cmake --build . --config "${CMAKE_CFG_INTDIR}" WORKING_DIRECTORY "${SWIG_BUILD}" DEPENDS ${PROTO_SRCS} ${TEST_PROTO_SRCS} diff --git a/Jenkinsfile b/Jenkinsfile index 6e894604..fad39d43 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -19,15 +19,14 @@ pipeline { PROTOBUF_LIBRARY = 'C:\\\\protobuf-2.6.1-pack\\\\lib\\\\libprotobuf-static.lib' PROTOBUF_PROTOC_EXECUTABLE = 'C:\\\\protobuf-2.6.1-pack\\\\bin\\\\protoc.exe' PROTOBUF_PROTOC_LIBRARY = 'C:\\\\protobuf-2.6.1-pack\\\\lib\\\\libprotoc.lib' - SWIG_DIR = 'C:\\\\PROGRA~1\\\\SWIGWI~1.12' - SWIG_EXECUTABLE = 'C:\\\\PROGRA~1\\\\SWIGWI~1.12\\\\SWIG.EXE' + SWIG_DIR = 'C:\\\\PROGRA~1\\\\SWIGWI~2.12' + SWIG_EXECUTABLE = 'C:\\\\PROGRA~1\\\\SWIGWI~2.12\\\\SWIG.EXE' test32 = 'empty' test64 = 'empty' version_1major = '8' version_2minor = '1' version_3micro = '0' version_4qualifier = 'Final' - HOTROD_LOG_LEVEL = 'TRACE' } steps { dir('cpp-client') { @@ -72,7 +71,7 @@ pipeline { PROTOBUF_PROTOC_EXECUTABLE = 'C:\\\\protobuf-2.6.1-pack\\\\bin\\\\protoc.exe' PROTOBUF_PROTOC_EXECUTABLE_CS = 'C:\\\\Users\\\\Administrator\\\\Google.Protobuf.Tools.3.4.0\\\\tools\\\\windows_x64\\\\protoc.exe' PROTOBUF_PROTOC_LIBRARY = 'C:\\\\protobuf-2.6.1-pack\\\\lib\\\\libprotoc.lib' - SWIG_DIR = 'C:\\\\PROGRA~1\\\\SWIGWI~1.12' + SWIG_DIR = 'C:\\\\PROGRA~1\\\\SWIGWI~2.12' SWIG_EXECUTABLE = 'C:\\\\PROGRA~1\\\\SWIGWI~2.12\\\\SWIG.EXE' test32 = 'skip' test64 = 'run' diff --git a/build.bat b/build.bat index f413aad6..edcd12a4 100644 --- a/build.bat +++ b/build.bat @@ -16,7 +16,7 @@ cd build_windows set "buildTest=%~1" call :unquote u_generator %generator% -cmake -G "%u_generator%" -DHOTRODCPP_HOME=%HOTRODCPP_HOME% -DPROTOBUF_PROTOC_EXECUTABLE_CS="%PROTOBUF_PROTOC_EXECUTABLE_CS%" -DGOOGLE_PROTOBUF_NUPKG="%GOOGLE_PROTOBUF_NUPKG%" -DPROTOBUF_INCLUDE_DIR=%PROTOBUF_INCLUDE_DIR% -DJBOSS_HOME=%JBOSS_HOME% -DIKVM_CUSTOM_BIN_PATH=%IKVM_CUSTOM_BIN_PATH% -DOPENSSL_ROOT_DIR=%OPENSSL_ROOT_DIR% -DCONFIGURATION=RelWithDebInfo %~4 .. +cmake -G "%u_generator%" -DHOTRODCPP_HOME=%HOTRODCPP_HOME% -DSWIG_DIR=%SWIG_DIR% -DSWIG_EXECUTABLE=%SWIG_EXECUTABLE% -DPROTOBUF_PROTOC_EXECUTABLE_CS="%PROTOBUF_PROTOC_EXECUTABLE_CS%" -DGOOGLE_PROTOBUF_NUPKG="%GOOGLE_PROTOBUF_NUPKG%" -DPROTOBUF_INCLUDE_DIR=%PROTOBUF_INCLUDE_DIR% -DJBOSS_HOME=%JBOSS_HOME% -DIKVM_CUSTOM_BIN_PATH=%IKVM_CUSTOM_BIN_PATH% -DOPENSSL_ROOT_DIR=%OPENSSL_ROOT_DIR% -DCONFIGURATION=RelWithDebInfo %~4 .. if %errorlevel% neq 0 goto fail cmake --build . --config RelWithDebInfo From a0fd52fb7106a4f4ac5ca03b7f9e2222e6f4a07d Mon Sep 17 00:00:00 2001 From: Vittorio Rigamonti Date: Wed, 8 Aug 2018 14:29:20 +0200 Subject: [PATCH 6/6] Propagate exception from the C++ core --- .../HotRodClientRollbackException.cs | 12 + swig/hotrod_exception.i | 13 +- .../TransactionTest.cs | 242 +++++++++++------- 3 files changed, 167 insertions(+), 100 deletions(-) create mode 100644 src/Infinispan.HotRod/Exceptions/HotRodClientRollbackException.cs diff --git a/src/Infinispan.HotRod/Exceptions/HotRodClientRollbackException.cs b/src/Infinispan.HotRod/Exceptions/HotRodClientRollbackException.cs new file mode 100644 index 00000000..40606031 --- /dev/null +++ b/src/Infinispan.HotRod/Exceptions/HotRodClientRollbackException.cs @@ -0,0 +1,12 @@ +namespace Infinispan.HotRod.Exceptions +{ + /// + /// Used to indicated that a commit operation actually rolled back + /// + public class HotRodClientRollbackException : HotRodClientException + { + internal HotRodClientRollbackException(string message) : base(message) + { + } + } +} diff --git a/swig/hotrod_exception.i b/swig/hotrod_exception.i index cdfbc933..f2b84996 100644 --- a/swig/hotrod_exception.i +++ b/swig/hotrod_exception.i @@ -9,6 +9,7 @@ HotRod_HotRodClientException, HotRod_CounterLowerBoundException, HotRod_CounterUpperBoundException, + HotRod_HotRodClientRollbackException, HotRod_Exception, } HotRodExceptionCodes; @@ -66,6 +67,9 @@ SWIGPendingException.Set(new Infinispan.HotRod.Exceptions.CounterUpperBoundException(message)); break; case 9: + SWIGPendingException.Set(new Infinispan.HotRod.Exceptions.HotRodClientRollbackException(message)); + break; + case 10: default: SWIGPendingException.Set(new Infinispan.HotRod.Exceptions.Exception(message)); break; @@ -100,15 +104,18 @@ } catch (const infinispan::hotrod::UnsupportedOperationException& e) { SWIG_CSharpSetPendingExceptionCustom(HotRod_UnsupportedOperationException, e.what()); return $null; - } catch (const infinispan::hotrod::HotRodClientException& e) { - SWIG_CSharpSetPendingExceptionCustom(HotRod_HotRodClientException, e.what()); - return $null; } catch (const infinispan::hotrod::CounterLowerBoundException& e) { SWIG_CSharpSetPendingExceptionCustom(HotRod_CounterLowerBoundException, e.what()); return $null; } catch (const infinispan::hotrod::CounterUpperBoundException& e) { SWIG_CSharpSetPendingExceptionCustom(HotRod_CounterUpperBoundException, e.what()); return $null; + } catch (const infinispan::hotrod::HotRodClientRollbackException& e) { + SWIG_CSharpSetPendingExceptionCustom(HotRod_HotRodClientRollbackException, e.what()); + return $null; + } catch (const infinispan::hotrod::HotRodClientException& e) { + SWIG_CSharpSetPendingExceptionCustom(HotRod_HotRodClientException, e.what()); + return $null; } catch (const infinispan::hotrod::Exception& e) { SWIG_CSharpSetPendingExceptionCustom(HotRod_Exception, e.what()); return $null; diff --git a/test/Infinispan.HotRod.Tests/TransactionTest.cs b/test/Infinispan.HotRod.Tests/TransactionTest.cs index 4caec3c4..e5d87964 100644 --- a/test/Infinispan.HotRod.Tests/TransactionTest.cs +++ b/test/Infinispan.HotRod.Tests/TransactionTest.cs @@ -19,9 +19,6 @@ public class TransactionTest IMarshaller marshaller; IMarshaller nonTxMarshaller; - HotRodServer server1; - HotRodServer server2; - private void InitializeRemoteCacheManager(bool started) { ConfigurationBuilder conf = new ConfigurationBuilder(); @@ -44,7 +41,6 @@ private void InitializeNonTxRemoteCacheManager(bool started) nonTxRemoteManager = new RemoteCacheManager(conf.Build(), started); } - [Test] public void ReadCommitted() { @@ -54,15 +50,24 @@ public void ReadCommitted() string k1 = "key13"; string v1 = "boron"; + string rv1; cache.Clear(); - - txManager.Begin(); - cache.Put(k1, v1); - // Check the correct value from the tx context - string rv1 = cache.Get(k1); - Assert.AreEqual(rv1, v1); - txManager.Commit(); + try + { + txManager.Begin(); + cache.Put(k1, v1); + // Check the correct value from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + txManager.Commit(); + } + catch (Exception ex) + { + // try to release the tx resources + txManager.Rollback(); + throw ex; + } // Check the correct value from remote cache rv1 = cache.Get(k1); Assert.AreEqual(rv1, v1); @@ -77,15 +82,20 @@ public void ReadRollbackOnNotExistent() string k1 = "key13"; string v1 = "boron"; + string rv1; cache.Clear(); - - txManager.Begin(); - cache.Put(k1, v1); - // Check the correct value from the tx context - string rv1 = cache.Get(k1); - Assert.AreEqual(rv1, v1); - txManager.Rollback(); + try + { + txManager.Begin(); + cache.Put(k1, v1); + // Check the correct value from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + } + finally { + txManager.Rollback(); + } // Check the correct value from remote cache rv1 = cache.Get(k1); Assert.IsNull(rv1); @@ -103,15 +113,25 @@ public void ChangeExistentAndCommit() string k1 = "key13"; string v0 = "carbon"; string v1 = "boron"; + string rv1; cache.Clear(); cache.Put(k1, v0); - txManager.Begin(); - cache.Put(k1, v1); - // Check the correct value from the tx context - string rv1 = cache.Get(k1); - Assert.AreEqual(rv1, v1); - txManager.Commit(); + try + { + txManager.Begin(); + cache.Put(k1, v1); + // Check the correct value from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + txManager.Commit(); + } + catch (Exception ex) + { + // try to release the tx resources + txManager.Rollback(); + throw ex; + } // Check the correct value from remote cache rv1 = cache.Get(k1); Assert.AreEqual(rv1, v1); @@ -129,19 +149,22 @@ public void ReadRollbackOnExistent() string k1 = "key13"; string oldv = "oxygen"; string v1 = "boron"; + string rv1; cache.Clear(); - string oldrv1 = cache.Put(k1, oldv); Assert.IsNull(oldrv1); - - txManager.Begin(); - oldrv1 = cache.Put(k1, v1); - Assert.AreEqual(oldrv1, oldv); - // Check the correct value from the tx context - string rv1 = cache.Get(k1); - Assert.AreEqual(rv1, v1); - txManager.Rollback(); + try + { + txManager.Begin(); + oldrv1 = cache.Put(k1, v1); + Assert.AreEqual(oldrv1, oldv); + // Check the correct value from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + } finally { + txManager.Rollback(); + } // Check the correct value from remote cache rv1 = cache.Get(k1); Assert.AreEqual(oldrv1, oldv); @@ -157,19 +180,23 @@ public void ReadInTransactionContext() string k1 = "key13"; string v1 = "boron"; + string rv1; cache.Clear(); - - txManager.Begin(); - - string oldv1 = cache.Put(k1, v1); - // Check the correct value from the tx context - string rv1 = cache.Get(k1); - Assert.AreEqual(rv1, v1); - cache.Remove(k1); - rv1 = cache.Get(k1); - Assert.IsNull(rv1); - txManager.Rollback(); + try + { + txManager.Begin(); + + string oldv1 = cache.Put(k1, v1); + // Check the correct value from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + cache.Remove(k1); + rv1 = cache.Get(k1); + Assert.IsNull(rv1); + } finally { + txManager.Rollback(); + } } // TX Client must read last value during the tx (from the context) @@ -185,19 +212,28 @@ public void ReadCommittedAndNonTxRead() string k1 = "key13"; string v1 = "boron"; + string rv1; + string nontxrv1; cache.Clear(); - - txManager.Begin(); - - cache.Put(k1, v1); - // Check the correct value from the tx context - string rv1 = cache.Get(k1); - Assert.AreEqual(rv1, v1); - - string nontxrv1 = nonTxCache.Get(k1); - Assert.IsNull(nontxrv1); - txManager.Commit(); + try + { + txManager.Begin(); + + cache.Put(k1, v1); + // Check the correct value from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + nontxrv1 = nonTxCache.Get(k1); + Assert.IsNull(nontxrv1); + txManager.Commit(); + } + catch (Exception ex) + { + // try to release the tx resources + txManager.Rollback(); + throw ex; + } // Check the correct value from remote cache rv1 = cache.Get(k1); Assert.AreEqual(rv1, v1); @@ -217,19 +253,22 @@ public void PutAndReadWithNonTxCache() string k1 = "key13"; string v1 = "boron"; + string rv1; cache.Clear(); - - txManager.Begin(); - string oldv1 = nonTxCache.Put(k1, v1); - // Check the correct value from the tx context - string rv1 = nonTxCache.Get(k1); - Assert.AreEqual(rv1, v1); - rv1 = cache.Remove(k1); - rv1 = cache.Get(k1); - Assert.IsNull(rv1); - txManager.Rollback(); - + try + { + txManager.Begin(); + string oldv1 = nonTxCache.Put(k1, v1); + // Check the correct value from the tx context + rv1 = nonTxCache.Get(k1); + Assert.AreEqual(rv1, v1); + rv1 = cache.Remove(k1); + rv1 = cache.Get(k1); + Assert.IsNull(rv1); + } finally { + txManager.Rollback(); + } rv1 = nonTxCache.Get(k1); Assert.AreEqual(rv1, v1); } @@ -247,28 +286,28 @@ public void RepeatableGetForTxClient() string k1 = "key13"; string v1 = "boron"; string v2 = "helium"; + string rv1; cache.Clear(); - - txManager.Begin(); - - string oldv1 = nonTxCache.Put(k1, v1); - // Check the correct value from the tx context - string rv1 = cache.Get(k1); - Assert.AreEqual(rv1, v1); - - // This goes to the server - oldv1 = nonTxCache.Put(k1, v2); - - // But this values comes from the tx context - rv1 = cache.Get(k1); - Assert.AreEqual(rv1, v1); - - cache.Remove(k1); - rv1 = cache.Get(k1); - Assert.IsNull(rv1); - txManager.Rollback(); - + try + { + txManager.Begin(); + + string oldv1 = nonTxCache.Put(k1, v1); + // Check the correct value from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + // This goes to the server + oldv1 = nonTxCache.Put(k1, v2); + // But this values comes from the tx context + rv1 = cache.Get(k1); + Assert.AreEqual(rv1, v1); + cache.Remove(k1); + rv1 = cache.Get(k1); + Assert.IsNull(rv1); + } finally { + txManager.Rollback(); + } rv1 = nonTxCache.Get(k1); Assert.AreEqual(rv1, v2); } @@ -286,22 +325,31 @@ public void ConflictsAndFail() string v1 = "boron"; string k2 = "key14"; string v2 = "helium"; - string vx = "calcium"; cache.Clear(); - - txManager.Begin(); - - string oldv1 = cache.Put(k1, v1); - string oldv2 = cache.Put(k2, v2); - // Check the correct value from the tx context - string rv1 = nonTxCache.Put(k1, vx); - Assert.IsNull(rv1); - txManager.Commit(); + try + { + txManager.Begin(); + + string oldv1 = cache.Put(k1, v1); + string oldv2 = cache.Put(k2, v2); + // Check the correct value from the tx context + string rv1 = nonTxCache.Put(k1, vx); + Assert.IsNull(rv1); + Assert.Throws(() => + { + txManager.Commit(); + }); + } + catch (Exception ex) + { + // try to release the tx resources + txManager.Rollback(); + throw ex; + } Assert.AreEqual(cache.Get(k1), vx); Assert.IsNull(cache.Get(k2)); } - } }