Repository: ignite Updated Branches: refs/heads/master 67be050a2 -> 0bb56a64e
IGNITE-8070 .NET: add IgniteConfiguration.FailureHandler Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0bb56a64 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0bb56a64 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0bb56a64 Branch: refs/heads/master Commit: 0bb56a64e338d676e3182244e17f9e79a318f808 Parents: 67be050 Author: Ivan Daschinskiy <[email protected]> Authored: Tue May 15 10:07:01 2018 +0300 Committer: Pavel Tupitsyn <[email protected]> Committed: Tue May 15 10:07:01 2018 +0300 ---------------------------------------------------------------------- .../failure/StopNodeOrHaltFailureHandler.java | 18 +++ .../utils/PlatformConfigurationUtils.java | 47 +++++++ .../Apache.Ignite.Core.Tests.csproj | 3 + .../ApiParity/IgniteConfigurationParityTest.cs | 3 +- .../Cache/Store/CacheStoreTest.cs | 44 ++++-- .../Config/full-config.xml | 3 +- .../Config/ignite-halthandler-dotnet-cfg.xml | 54 ++++++++ .../Config/ignite-stophandler-dotnet-cfg.xml | 54 ++++++++ .../FailureHandlerTest.cs | 133 +++++++++++++++++++ .../IgniteConfigurationSerializerTest.cs | 15 ++- .../TestUtils.Windows.cs | 2 + .../Apache.Ignite.Core.csproj | 5 +- .../Failure/IFailureHandler.cs | 33 +++++ .../Failure/NoOpFailureHandler.cs | 28 ++++ .../Failure/StopNodeFailureHandler.cs | 28 ++++ .../Failure/StopNodeOrHaltFailureHandler.cs | 97 ++++++++++++++ .../Apache.Ignite.Core/IgniteConfiguration.cs | 86 +++++++++++- .../IgniteConfigurationSection.xsd | 21 ++- 18 files changed, 653 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/core/src/main/java/org/apache/ignite/failure/StopNodeOrHaltFailureHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/failure/StopNodeOrHaltFailureHandler.java b/modules/core/src/main/java/org/apache/ignite/failure/StopNodeOrHaltFailureHandler.java index 879ddb0..24c8b17 100644 --- a/modules/core/src/main/java/org/apache/ignite/failure/StopNodeOrHaltFailureHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/failure/StopNodeOrHaltFailureHandler.java @@ -101,6 +101,24 @@ public class StopNodeOrHaltFailureHandler implements FailureHandler { return true; } + /** + * Get stop node timeout. + * + * @return Stop node timeout. + */ + public long timeout() { + return timeout; + } + + /** + * Get try stop. + * + * @return Try stop. + */ + public boolean tryStop() { + return tryStop; + } + /** {@inheritDoc} */ @Override public String toString() { return S.toString(StopNodeOrHaltFailureHandler.class, this); http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java index 3cf14677..b4f82a4 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java @@ -70,6 +70,10 @@ import org.apache.ignite.configuration.SqlConnectorConfiguration; import org.apache.ignite.configuration.TransactionConfiguration; import org.apache.ignite.configuration.WALMode; import org.apache.ignite.events.Event; +import org.apache.ignite.failure.FailureHandler; +import org.apache.ignite.failure.NoOpFailureHandler; +import org.apache.ignite.failure.StopNodeFailureHandler; +import org.apache.ignite.failure.StopNodeOrHaltFailureHandler; import org.apache.ignite.internal.binary.BinaryRawReaderEx; import org.apache.ignite.internal.binary.BinaryRawWriterEx; import org.apache.ignite.internal.processors.platform.cache.affinity.PlatformAffinityFunction; @@ -77,6 +81,7 @@ import org.apache.ignite.internal.processors.platform.cache.expiry.PlatformExpir import org.apache.ignite.internal.processors.platform.events.PlatformLocalEventListener; import org.apache.ignite.internal.processors.platform.plugin.cache.PlatformCachePluginConfiguration; import org.apache.ignite.internal.util.typedef.F; +import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.lang.IgniteBiTuple; import org.apache.ignite.lang.IgnitePredicate; import org.apache.ignite.platform.dotnet.PlatformDotNetAffinityFunction; @@ -772,6 +777,25 @@ public class PlatformConfigurationUtils { if (in.readBoolean()) cfg.setSslContextFactory(readSslContextFactory(in)); + if (in.readBoolean()) { + switch (in.readByte()) { + case 0: + cfg.setFailureHandler(new NoOpFailureHandler()); + + break; + + case 1: + cfg.setFailureHandler(new StopNodeFailureHandler()); + + break; + + case 2: + cfg.setFailureHandler(new StopNodeOrHaltFailureHandler(in.readBoolean(), in.readLong())); + + break; + } + } + readPluginConfiguration(cfg, in); readLocalEventListeners(cfg, in); @@ -1284,6 +1308,29 @@ public class PlatformConfigurationUtils { writeSslContextFactory(w, cfg.getSslContextFactory()); + FailureHandler failureHnd = cfg.getFailureHandler(); + + if (failureHnd instanceof NoOpFailureHandler) { + w.writeBoolean(true); + + w.writeByte((byte) 0); + } + else if (failureHnd instanceof StopNodeFailureHandler) { + w.writeBoolean(true); + + w.writeByte((byte) 1); + } + else if (failureHnd instanceof StopNodeOrHaltFailureHandler) { + w.writeBoolean(true); + + w.writeByte((byte) 2); + + w.writeBoolean(((StopNodeOrHaltFailureHandler)failureHnd).tryStop()); + + w.writeLong(((StopNodeOrHaltFailureHandler)failureHnd).timeout()); + } else + w.writeBoolean(false); + w.writeString(cfg.getIgniteHome()); w.writeLong(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getInit()); http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj index fe7781d..00eddeb 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj @@ -194,6 +194,7 @@ <Compile Include="Common\IgniteGuidTest.cs" /> <Compile Include="Deployment\RuntimeDependencyFunc.cs" /> <Compile Include="EventsTestLocalListeners.cs" /> + <Compile Include="FailureHandlerTest.cs" /> <Compile Include="Process\ListDataReader.cs" /> <Compile Include="Log\ConcurrentMemoryTarget.cs" /> <Compile Include="Log\DefaultLoggerTest.cs" /> @@ -418,6 +419,8 @@ <Content Include="Config\full-config.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> + <Content Include="Config\ignite-halthandler-dotnet-cfg.xml" /> + <Content Include="Config\ignite-stophandler-dotnet-cfg.xml" /> <Content Include="Config\Lifecycle\lifecycle-beans.xml"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs index bf34fc0..1fd8e72 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/IgniteConfigurationParityTest.cs @@ -80,8 +80,7 @@ namespace Apache.Ignite.Core.Tests.ApiParity "TimeServerPortBase", "TimeServerPortRange", "IncludeProperties", - "isAutoActivationEnabled", // IGNITE-7301 - "failureHandler" // IGNITE-8070 + "isAutoActivationEnabled" // IGNITE-7301 }; /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs index 07c3cfa..fffd08a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Store/CacheStoreTest.cs @@ -52,11 +52,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Store [TestFixtureSetUp] public virtual void BeforeTests() { - Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) - { - IgniteInstanceName = GridName, - SpringConfigUrl = "config\\native-client-test-cache-store.xml", - }); + Restart(); } /// <summary> @@ -76,6 +72,21 @@ namespace Apache.Ignite.Core.Tests.Cache.Store } } + + /// <summary> + /// Stop all instances, set and start a test instance. + /// </summary> + private void Restart() + { + Ignition.StopAll(true); + + Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) + { + IgniteInstanceName = GridName, + SpringConfigUrl = "config\\native-client-test-cache-store.xml", + }); + } + /// <summary> /// Test tear down. /// </summary> @@ -245,22 +256,29 @@ namespace Apache.Ignite.Core.Tests.Cache.Store cache.Remove(1); } - - + /// <summary> /// Tests that exceptions from CacheStoreFactory are propagated properly. /// </summary> [Test] - [Ignore("IGNITE-8070")] public void TestFailedCacheStoreException() { - var ccfg = new CacheConfiguration("CacheWithFailedStore") + try { - CacheStoreFactory = new FailedCacheStoreFactory(), - ReadThrough = true - }; + var ccfg = new CacheConfiguration("CacheWithFailedStore") + { + CacheStoreFactory = new FailedCacheStoreFactory(), + ReadThrough = true + }; - Assert.Throws<CacheException>(() => Ignition.GetIgnite(GridName).GetOrCreateCache<int, int>(ccfg)); + Assert.Throws<CacheException>(() => Ignition.GetIgnite(GridName).GetOrCreateCache<int, int>(ccfg)); + } + finally + { + // After failed cache grid is in ivalid state. Should be restarted. + Restart(); + } + } [Test] http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml index 341cf7c..d50cf4f 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml @@ -159,4 +159,5 @@ <sslContextFactory type='SslContextFactory' protocol='SSL' keyStoreFilePath='KeyStore/server.jks' keyStorePassword='123456' trustStoreFilePath='KeyStore/trust.jks' trustStorePassword='123456'/> -</igniteConfiguration> \ No newline at end of file + <failureHandler type="StopNodeOrHaltFailureHandler" tryStop="true" timeout="0:1:0"/> +</igniteConfiguration> http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/ignite-halthandler-dotnet-cfg.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/ignite-halthandler-dotnet-cfg.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/ignite-halthandler-dotnet-cfg.xml new file mode 100644 index 0000000..ca3e3a6 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/ignite-halthandler-dotnet-cfg.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<configuration> + <configSections> + <section name="igniteConfiguration" type="Apache.Ignite.Core.IgniteConfigurationSection, Apache.Ignite.Core" /> + </configSections> + + <igniteConfiguration xmlns="http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection" + localhost="127.0.0.1"> + <discoverySpi type="TcpDiscoverySpi"> + <ipFinder type="TcpDiscoveryStaticIpFinder"> + <endpoints> + <string>127.0.0.1:47500</string> + </endpoints> + </ipFinder> + </discoverySpi> + + <jvmOptions> + <string>-Xms512m</string> + <string>-Xmx702m</string> + <string>-DOPT25</string> + </jvmOptions> + + <cacheConfiguration> + <cacheConfiguration name='testCache' cacheMode='Replicated' /> + </cacheConfiguration> + + <binaryConfiguration> + <types> + <string>Apache.Ignite.Core.Tests.ExecutableTest+RemoteConfiguration, Apache.Ignite.Core.Tests</string> + <string>Apache.Ignite.Core.Tests.ExecutableTest+RemoteConfigurationClosure, Apache.Ignite.Core.Tests</string> + </types> + </binaryConfiguration> + + <failureHandler type="StopNodeOrHaltFailureHandler" tryStop="false" timeout="0:0:0"/> + </igniteConfiguration> +</configuration> http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/ignite-stophandler-dotnet-cfg.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/ignite-stophandler-dotnet-cfg.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/ignite-stophandler-dotnet-cfg.xml new file mode 100644 index 0000000..8e6ace7 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/ignite-stophandler-dotnet-cfg.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<configuration> + <configSections> + <section name="igniteConfiguration" type="Apache.Ignite.Core.IgniteConfigurationSection, Apache.Ignite.Core" /> + </configSections> + + <igniteConfiguration xmlns="http://ignite.apache.org/schema/dotnet/IgniteConfigurationSection" + localhost="127.0.0.1"> + <discoverySpi type="TcpDiscoverySpi"> + <ipFinder type="TcpDiscoveryStaticIpFinder"> + <endpoints> + <string>127.0.0.1:47500</string> + </endpoints> + </ipFinder> + </discoverySpi> + + <jvmOptions> + <string>-Xms512m</string> + <string>-Xmx702m</string> + <string>-DOPT25</string> + </jvmOptions> + + <cacheConfiguration> + <cacheConfiguration name='testCache' cacheMode='Replicated' /> + </cacheConfiguration> + + <binaryConfiguration> + <types> + <string>Apache.Ignite.Core.Tests.ExecutableTest+RemoteConfiguration, Apache.Ignite.Core.Tests</string> + <string>Apache.Ignite.Core.Tests.ExecutableTest+RemoteConfigurationClosure, Apache.Ignite.Core.Tests</string> + </types> + </binaryConfiguration> + + <failureHandler type="StopNodeFailureHandler"/> + </igniteConfiguration> +</configuration> http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/FailureHandlerTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/FailureHandlerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/FailureHandlerTest.cs new file mode 100644 index 0000000..7c447b1 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/FailureHandlerTest.cs @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Tests +{ + using System; + using System.Threading; + using Apache.Ignite.Core.Cache; + using Apache.Ignite.Core.Cache.Configuration; + using Apache.Ignite.Core.Cache.Store; + using Apache.Ignite.Core.Common; + using Apache.Ignite.Core.Failure; + using Apache.Ignite.Core.Tests.Process; + using NUnit.Framework; + + /// <summary> + /// Tests all three failure handlers: <see cref="StopNodeFailureHandler"/>, <see cref="StopNodeOrHaltFailureHandler"/> + /// and <see cref="NoOpFailureHandler"/>. By default in test configuration we use <see cref="NoOpFailureHandler"/>. + /// For others we should start node by <see cref="IgniteProcess"/>. + /// </summary> + public class FailureHandlerTest + { + /// <summary> + /// Grid that uses <see cref="NoOpFailureHandler"/> and therefore can be started without + /// <see cref="IgniteProcess"/>. + /// </summary> + private IIgnite _grid; + + /** Part of failed CacheStore Exception message. */ + private const string CacheStoreExMessage = "Could not create .NET CacheStore"; + + /// <summary> + /// Set-up routine. + /// </summary> + [SetUp] + public void SetUp() + { + TestUtils.KillProcesses(); + + _grid = Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration())); + + Assert.IsTrue(_grid.WaitTopology(1)); + } + + /// <summary> + /// Tear-down routine. + /// </summary> + [TearDown] + public void TearDown() + { + Ignition.StopAll(true); + + TestUtils.KillProcesses(); + } + + /// <summary> + /// Tests <see cref="StopNodeFailureHandler"/> + /// </summary> + [Test] + public void TestStopNodeFailureHandler() + { + TestFailureHandler(typeof(StopNodeFailureHandler)); + } + + /// <summary> + /// Tests <see cref="StopNodeOrHaltFailureHandler"/> + /// </summary> + [Test] + public void TestStopNodeOrHaltFailureHandler() + { + TestFailureHandler(typeof(StopNodeOrHaltFailureHandler)); + } + + private void TestFailureHandler(Type type) + { + var configFile = "config\\ignite-stophandler-dotnet-cfg.xml"; + + if (type == typeof(StopNodeOrHaltFailureHandler)) + { + configFile = "config\\ignite-halthandler-dotnet-cfg.xml"; + } + + var proc = new IgniteProcess("-jvmClasspath=" + TestUtils.CreateTestClasspath(), + "-configFileName=" + configFile); + + Assert.IsTrue(proc.Alive); + + + var ccfg = new CacheConfiguration("CacheWithFailedStore") + { + CacheStoreFactory = new FailedCacheStoreFactory(), + ReadThrough = true + }; + + var ex = Assert.Throws<CacheException>(() => _grid.GetOrCreateCache<int, int>(ccfg)); + + Assert.IsTrue(ex.Message.Contains(CacheStoreExMessage)); + + Thread.Sleep(TimeSpan.Parse("0:0:5")); + + Assert.IsFalse(proc.Alive); + } + + /// <summary> + /// Test factory that fails grid. + /// </summary> + [Serializable] + public class FailedCacheStoreFactory : IFactory<ICacheStore> + { + /// <summary> + /// Creates an instance of the cache store. Throws an exception during creation. This cause grid to fail. + /// </summary> + public ICacheStore CreateInstance() + { + throw new Exception("Failed cache store"); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs index 31d0861..226106f 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs @@ -47,6 +47,7 @@ namespace Apache.Ignite.Core.Tests using Apache.Ignite.Core.Discovery.Tcp; using Apache.Ignite.Core.Discovery.Tcp.Multicast; using Apache.Ignite.Core.Events; + using Apache.Ignite.Core.Failure; using Apache.Ignite.Core.Lifecycle; using Apache.Ignite.Core.Log; using Apache.Ignite.Core.PersistentStore; @@ -340,6 +341,13 @@ namespace Apache.Ignite.Core.Tests Assert.IsFalse(dr.MetricsEnabled); Assert.IsInstanceOf<SslContextFactory>(cfg.SslContextFactory); + + Assert.IsInstanceOf<StopNodeOrHaltFailureHandler>(cfg.FailureHandler); + + var failureHandler = (StopNodeOrHaltFailureHandler)cfg.FailureHandler; + + Assert.IsTrue(failureHandler.TryStop); + Assert.AreEqual(TimeSpan.Parse("0:1:0"), failureHandler.Timeout); } /// <summary> @@ -1002,7 +1010,12 @@ namespace Apache.Ignite.Core.Tests } } }, - SslContextFactory = new SslContextFactory() + SslContextFactory = new SslContextFactory(), + FailureHandler = new StopNodeOrHaltFailureHandler() + { + TryStop = false, + Timeout = TimeSpan.FromSeconds(10) + } }; } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Windows.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Windows.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Windows.cs index f8ff874..31d5c58 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Windows.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Windows.cs @@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Tests using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Apache.Ignite.Core.Configuration; + using Apache.Ignite.Core.Failure; using Apache.Ignite.Core.Impl; using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Tests.Process; @@ -79,6 +80,7 @@ namespace Apache.Ignite.Core.Tests : 256 * 1024 * 1024 } }, + FailureHandler = new NoOpFailureHandler(), WorkDirectory = WorkDir }; } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj index 3e8c00f..9ae3a26 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -73,6 +73,10 @@ <Compile Include="Client\IgniteClientException.cs" /> <Compile Include="Client\IIgniteClient.cs" /> <Compile Include="Common\ExceptionFactory.cs" /> + <Compile Include="Failure\IFailureHandler.cs" /> + <Compile Include="Failure\NoOpFailureHandler.cs" /> + <Compile Include="Failure\StopNodeFailureHandler.cs" /> + <Compile Include="Failure\StopNodeOrHaltFailureHandler.cs" /> <Compile Include="Impl\Cache\QueryMetricsImpl.cs" /> <Compile Include="Impl\Common\TaskRunner.cs" /> <Compile Include="Impl\Transactions\TransactionCollectionImpl.cs" /> @@ -585,7 +589,6 @@ <None Include="NuGet\Install.ps1" /> <None Include="Apache.Ignite.Core.snk" /> </ItemGroup> - <ItemGroup /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core/Failure/IFailureHandler.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Failure/IFailureHandler.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Failure/IFailureHandler.cs new file mode 100644 index 0000000..d3f8254 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Failure/IFailureHandler.cs @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Failure +{ + using System.Diagnostics.CodeAnalysis; + + /// <summary> + /// Failure handler interface. + /// <para /> + /// Only predefined implementations are supported: + /// <see cref="NoOpFailureHandler"/>, <see cref="StopNodeFailureHandler"/>, <see cref="StopNodeOrHaltFailureHandler"/>. + /// </summary> + [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")] + public interface IFailureHandler + { + // No-op. + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core/Failure/NoOpFailureHandler.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Failure/NoOpFailureHandler.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Failure/NoOpFailureHandler.cs new file mode 100644 index 0000000..544b88d --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Failure/NoOpFailureHandler.cs @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Failure +{ + /// <summary> + /// Just ignores any failure. It's useful for tests and debugging. + /// <para /> + /// </summary> + public class NoOpFailureHandler : IFailureHandler + { + // No-op. + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core/Failure/StopNodeFailureHandler.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Failure/StopNodeFailureHandler.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Failure/StopNodeFailureHandler.cs new file mode 100644 index 0000000..9e7cdb0 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Failure/StopNodeFailureHandler.cs @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Failure +{ + /// <summary> + /// Handler will stop node in case of critical error. + /// <para /> + /// </summary>h + public class StopNodeFailureHandler : IFailureHandler + { + // No-op. + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core/Failure/StopNodeOrHaltFailureHandler.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Failure/StopNodeOrHaltFailureHandler.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Failure/StopNodeOrHaltFailureHandler.cs new file mode 100644 index 0000000..1ee2c58 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Failure/StopNodeOrHaltFailureHandler.cs @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace Apache.Ignite.Core.Failure +{ + using System; + using System.ComponentModel; + using System.Diagnostics; + using Apache.Ignite.Core.Binary; + + /// <summary> + /// Handler will try to stop node if <see cref="TryStop"/> value is true. + /// If node can't be stopped during provided <see cref="Timeout"/> or <see cref="TryStop"/> value is false + /// then JVM process will be terminated forcibly. + /// <para /> + /// </summary> + public class StopNodeOrHaltFailureHandler : IFailureHandler + { + /// <summary> + /// Try stop flag. + /// Defaults false. + /// </summary> + [DefaultValue(false)] + public bool TryStop { get; set; } + + + /// <summary> + /// Stop node timeout. + /// Defaults to 0. + /// </summary> + [DefaultValue(typeof(TimeSpan), "0:0:0")] + public TimeSpan Timeout { get; set; } + + /// <summary> + /// Initialize a new instance of the <see cref="StopNodeOrHaltFailureHandler"/> + /// </summary> + public StopNodeOrHaltFailureHandler() + { + TryStop = false; + Timeout = TimeSpan.Zero; + } + + /// <summary> + /// Reads instance. + /// </summary> + internal static StopNodeOrHaltFailureHandler Read(IBinaryRawReader reader) + { + Debug.Assert(reader != null); + + var tryStop = reader.ReadBoolean(); + var timeout = reader.ReadLong(); + + return new StopNodeOrHaltFailureHandler + { + TryStop = tryStop, + Timeout = timeout < 0 || timeout > TimeSpan.MaxValue.TotalMilliseconds + ? TimeSpan.Zero + : TimeSpan.FromMilliseconds(timeout) + }; + } + + /// <summary> + /// Writes this instance. + /// </summary> + internal void Write(IBinaryRawWriter writer) + { + writer.WriteBoolean(TryStop); + + if (Timeout == TimeSpan.MaxValue) + { + writer.WriteLong(long.MaxValue); + } + else if (Timeout < TimeSpan.Zero) + { + writer.WriteLong(0); + } + else + { + writer.WriteLong((long)Timeout.TotalMilliseconds); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs index 059bea4..7d8cfc7 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfiguration.cs @@ -40,6 +40,7 @@ namespace Apache.Ignite.Core using Apache.Ignite.Core.Discovery; using Apache.Ignite.Core.Discovery.Tcp; using Apache.Ignite.Core.Events; + using Apache.Ignite.Core.Failure; using Apache.Ignite.Core.Impl; using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Common; @@ -196,7 +197,7 @@ namespace Apache.Ignite.Core /** */ private bool? _authenticationEnabled; - + /** Local event listeners. Stored as array to ensure index access. */ private LocalEventListener[] _localEventListenersInternal; @@ -511,7 +512,43 @@ namespace Apache.Ignite.Core // SSL Context factory. SslFactorySerializer.Write(writer, SslContextFactory); + + // Failure handler. + if (FailureHandler == null) + { + writer.WriteBoolean(false); + } + else + { + writer.WriteBoolean(true); + + if (FailureHandler is NoOpFailureHandler) + { + writer.WriteByte(0); + } + else if (FailureHandler is StopNodeFailureHandler) + { + writer.WriteByte(1); + } + else + { + var failHnd = FailureHandler as StopNodeOrHaltFailureHandler; + + if (failHnd == null) + { + throw new InvalidOperationException(string.Format( + "Unsupported IgniteConfiguration.FailureHandler: '{0}'. " + + "Supported implementations: '{1}', '{2}', '{3}'.", + FailureHandler.GetType(), typeof(NoOpFailureHandler), typeof(StopNodeFailureHandler), + typeof(StopNodeOrHaltFailureHandler))); + } + writer.WriteByte(2); + + failHnd.Write(writer); + } + } + // Plugins (should be last). if (PluginConfigurations != null) { @@ -690,7 +727,8 @@ namespace Apache.Ignite.Core // Event storage switch (r.ReadByte()) { - case 1: EventStorageSpi = new NoopEventStorageSpi(); + case 1: + EventStorageSpi = new NoopEventStorageSpi(); break; case 2: @@ -737,6 +775,37 @@ namespace Apache.Ignite.Core // SSL context factory. SslContextFactory = SslFactorySerializer.Read(r); + + //Failure handler. + if (r.ReadBoolean()) + { + switch (r.ReadByte()) + { + case 0: + FailureHandler = new NoOpFailureHandler(); + + break; + + case 1: + FailureHandler = new StopNodeFailureHandler(); + + break; + + case 2: + FailureHandler = StopNodeOrHaltFailureHandler.Read(r); + + break; + + default: + FailureHandler = null; + + break; + } + } + else + { + FailureHandler = null; + } } /// <summary> @@ -1447,5 +1516,18 @@ namespace Apache.Ignite.Core get { return _authenticationEnabled ?? DefaultAuthenticationEnabled; } set { _authenticationEnabled = value; } } + + /// <summary> + /// Gets or sets predefined failure handlers implementation. + /// A failure handler handles critical failures of Ignite instance accordingly: + /// <para><see cref="NoOpFailureHandler"/> -- do nothing.</para> + /// <para><see cref="StopNodeFailureHandler"/> -- stop node.</para> + /// <para><see cref="StopNodeOrHaltFailureHandler"/> -- try to stop node if tryStop value is true. + /// If node can't be stopped during provided timeout or tryStop value is false then JVM process will be terminated forcibly.</para> + /// <para/> + /// Only these implementations are supported: + /// <see cref="NoOpFailureHandler"/>, <see cref="StopNodeOrHaltFailureHandler"/>, <see cref="StopNodeFailureHandler"/>. + /// </summary> + public IFailureHandler FailureHandler { get; set; } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bb56a64/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd index 7d3d8ad..f16ef43 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more @@ -2010,6 +2010,25 @@ </xs:sequence> </xs:complexType> </xs:element> + <xs:element name="failureHandler" minOccurs="0"> + <xs:complexType> + <xs:attribute name="type" type="xs:string" use="required"> + <xs:annotation> + <xs:documentation>Assembly-qualified type name.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="tryStop" type="xs:boolean" default="false"> + <xs:annotation> + <xs:documentation>Try stop before halt node parameter, use only for StopNodeOrHaltFailureHandler.</xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="timeout" type="xs:string" default="0:0:0"> + <xs:annotation> + <xs:documentation>Timeout for node stop, use only for StopNodeOrHaltFailureHandler.</xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> </xs:all> <xs:attribute name="igniteInstanceName" type="xs:string"> <xs:annotation>
