http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.csproj index d660b62..8278365 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests.DotNetCore/Apache.Ignite.Core.Tests.DotNetCore.csproj @@ -16,6 +16,10 @@ <NoWarn>1701;1702;1705;NU1701</NoWarn> </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> + <AllowUnsafeBlocks>true</AllowUnsafeBlocks> + </PropertyGroup> + <ItemGroup> <Compile Include="..\Apache.Ignite.Core.Tests\ApiParity\BinaryParityTest.cs" Link="ApiParity\BinaryParityTest.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\ApiParity\CacheAffinityParityTest.cs" Link="ApiParity\CacheAffinityParityTest.cs" /> @@ -42,7 +46,12 @@ <Compile Include="..\Apache.Ignite.Core.Tests\ApiParity\TransactionsParityTest.cs" Link="ApiParity\TransactionsParityTest.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\AssertExtensions.cs" Link="Common\AssertExtensions.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\BinaryConfigurationTest.cs" Link="Binary\BinaryConfigurationTest.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Binary\BinaryBuilderSelfTest.cs" Link="Binary\BinaryBuilderSelfTest.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Binary\BinaryBuilderSelfTestDynamicRegistration.cs" Link="Binary\BinaryBuilderSelfTestDynamicRegistration.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\Binary\BinaryDateTimeTest.cs" Link="Binary\BinaryDateTimeTest.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Binary\BinarySelfTest.cs" Link="Binary\BinarySelfTest.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Binary\EnumsTest.cs" Link="Binary\EnumsTest.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Binary\EnumsTestOnline.cs" Link="Binary\EnumsTestOnline.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\Binary\JavaBinaryInteropTest.cs" Link="Binary\JavaBinaryInteropTest.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\Binary\Serializable\AdvancedSerializationTest.cs" Link="Binary\Serializable\AdvancedSerializationTest.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\Binary\Serializable\CallbacksTest.cs" Link="Binary\Serializable\CallbacksTest.cs" /> @@ -98,6 +107,7 @@ <Compile Include="..\Apache.Ignite.Core.Tests\Client\ClientTestBase.cs" Link="ThinClient\ClientTestBase.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\Client\IgniteClientConfigurationTest.cs" Link="ThinClient\IgniteClientConfigurationTest.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\Compute\ComputeApiTest.cs" Link="Compute\ComputeApiTest.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Compute\ComputeApiTest.JavaTask.cs" Link="Compute\ComputeApiTest.JavaTask.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\DataStructures\AtomicLongTest.cs" Link="DataStructures\AtomicLongTest.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\DataStructures\AtomicReferenceTest.cs" Link="DataStructures\AtomicReferenceTest.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\DataStructures\AtomicSequenceTest.cs" Link="DataStructures\AtomicSequenceTest.cs" /> @@ -112,6 +122,10 @@ <Compile Include="..\Apache.Ignite.Core.Tests\Plugin\TestIgnitePluginException.cs" Link="Plugin\TestIgnitePluginException.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\Plugin\TestIgnitePluginProvider.cs" Link="Plugin\TestIgnitePluginProvider.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\Query\BinarizablePerson.cs" Link="Cache\Query\BinarizablePerson.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Services\ServiceProxyTest.cs" Link="Services\ServiceProxyTest.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Services\ServicesAsyncWrapper.cs" Link="Services\ServicesAsyncWrapper.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Services\ServicesTest.cs" Link="Services\ServicesTest.cs" /> + <Compile Include="..\Apache.Ignite.Core.Tests\Services\ServicesTestAsync.cs" Link="Services\ServicesTestAsync.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\TaskExtensions.cs" Link="Common\TaskExtensions.cs" /> <Compile Include="..\Apache.Ignite.Core.Tests\TestUtils.Common.cs" Link="Common\TestUtils.Common.cs" /> </ItemGroup> @@ -168,6 +182,7 @@ <Folder Include="DataStructures\" /> <Folder Include="ApiParity\" /> <Folder Include="Plugin\" /> + <Folder Include="Services\" /> <Folder Include="ThinClient\Cache\" /> </ItemGroup>
http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs index 5837ab1..f03a77a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/BinaryBuilderSelfTest.cs @@ -50,8 +50,6 @@ namespace Apache.Ignite.Core.Tests.Binary [TestFixtureSetUp] public void SetUp() { - TestUtils.KillProcesses(); - var cfg = new IgniteConfiguration(TestUtils.GetTestConfiguration()) { BinaryConfiguration = new BinaryConfiguration http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs index fcce021..afe0a9a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTest.cs @@ -30,9 +30,7 @@ namespace Apache.Ignite.Core.Tests.Cache using Apache.Ignite.Core.Cache.Expiry; using Apache.Ignite.Core.Cluster; using Apache.Ignite.Core.Common; -#if !NETCOREAPP2_0 using Apache.Ignite.Core.Impl.Cache; -#endif using Apache.Ignite.Core.Tests.Query; using Apache.Ignite.Core.Transactions; using NUnit.Framework; @@ -2225,7 +2223,6 @@ namespace Apache.Ignite.Core.Tests.Cache } } -#if !NETCOREAPP2_0 /// <summary> /// Test skip-store semantics. /// </summary> @@ -2252,7 +2249,6 @@ namespace Apache.Ignite.Core.Tests.Cache // Ensure other flags are preserved. Assert.IsTrue(((CacheImpl<int, int>) cache.WithKeepBinary<int, int>().WithSkipStore()).IsKeepBinary); } -#endif [Test] public void TestRebalance() http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs index 77ae8fe..7a60e9a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheAbstractTransactionalTest.cs @@ -556,8 +556,12 @@ namespace Apache.Ignite.Core.Tests.Cache // Increment keys within tx in different order to cause a deadlock. var aex = Assert.Throws<AggregateException>(() => - Task.WaitAll(Task.Factory.StartNew(() => increment(keys0)), - Task.Factory.StartNew(() => increment(keys0.Reverse().ToArray())))); + Task.WaitAll(new[] + { + Task.Factory.StartNew(() => increment(keys0)), + Task.Factory.StartNew(() => increment(keys0.Reverse().ToArray())) + }, + TimeSpan.FromSeconds(40))); Assert.AreEqual(2, aex.InnerExceptions.Count); http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CreateCacheTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CreateCacheTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CreateCacheTest.cs index 92804be..047fc2b 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CreateCacheTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CreateCacheTest.cs @@ -22,10 +22,8 @@ namespace Apache.Ignite.Core.Tests.Client.Cache using Apache.Ignite.Core.Client; using Apache.Ignite.Core.Client.Cache; using Apache.Ignite.Core.Configuration; -#if !NETCOREAPP2_0 using Apache.Ignite.Core.Impl.Client.Cache; using Apache.Ignite.Core.Impl.Client; -#endif using Apache.Ignite.Core.Tests.Cache; using NUnit.Framework; @@ -152,7 +150,6 @@ namespace Apache.Ignite.Core.Tests.Client.Cache AssertClientConfigsAreEqual(cfg, cache.GetConfiguration()); } -#if !NETCOREAPP2_0 /// <summary> /// Tests cache creation from partial configuration. /// </summary> @@ -184,7 +181,6 @@ namespace Apache.Ignite.Core.Tests.Client.Cache AssertExtensions.ReflectionEqual(cfg, cache.GetConfiguration()); } -#endif /// <summary> /// Tests cache creation from configuration. http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs index 0bf3c37..1da60b1 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientConnectionTest.cs @@ -114,7 +114,6 @@ namespace Apache.Ignite.Core.Tests.Client Assert.Throws<ArgumentNullException>(() => Ignition.StartClient(new IgniteClientConfiguration())); } -#if !NETCOREAPP2_0 /// <summary> /// Tests the incorrect protocol version error. /// </summary> @@ -135,7 +134,6 @@ namespace Apache.Ignite.Core.Tests.Client "Client version: -1.-1.-1. Server version: 1.0.0", ex.Message); } } -#endif /// <summary> /// Tests that connector can be disabled. http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs index 6c4c00a..cf0ad40 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Compute/ComputeApiTest.cs @@ -784,19 +784,12 @@ namespace Apache.Ignite.Core.Tests.Compute _grid1.GetCluster().ForRemotes().GetCompute().Broadcast(new ExceptionalComputeAction())); Assert.IsNotNull(ex.InnerException); -#if NETCOREAPP2_0 - // Exceptions can't be serialized on .NET Core - Assert.AreEqual("Operation is not supported on this platform.", - ex.InnerException.Message); -#else Assert.AreEqual("Compute job has failed on remote node, examine InnerException for details.", ex.InnerException.Message); Assert.IsNotNull(ex.InnerException.InnerException); Assert.AreEqual(ExceptionalComputeAction.ErrorText, ex.InnerException.InnerException.Message); -#endif } -#if !NETCOREAPP2_0 /// <summary> /// Tests the footer setting. /// </summary> @@ -808,7 +801,6 @@ namespace Apache.Ignite.Core.Tests.Compute foreach (var g in new[] {_grid1, _grid2, _grid3}) Assert.AreEqual(CompactFooter, g.GetConfiguration().BinaryConfiguration.CompactFooter); } -#endif /// <summary> /// Create configuration. http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Log/CustomLoggerTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Log/CustomLoggerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Log/CustomLoggerTest.cs index 50d2dbf..543287e 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Log/CustomLoggerTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Log/CustomLoggerTest.cs @@ -119,7 +119,6 @@ namespace Apache.Ignite.Core.Tests.Log Assert.IsInstanceOf<ArithmeticException>(err.Exception); } -#if !NETCOREAPP2_0 // Exception serialization is not supported in .NET Core /// <summary> /// Tests that .NET exception propagates through Java to the log. /// </summary> @@ -145,7 +144,6 @@ namespace Apache.Ignite.Core.Tests.Log ((ArithmeticException) errFromJava.Exception.InnerException).Message); } } -#endif /// <summary> /// Tests the <see cref="QueryEntity"/> validation. http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs index eb6192d..133ffdf 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServiceProxyTest.cs @@ -190,6 +190,9 @@ namespace Apache.Ignite.Core.Tests.Services "can't resolve ambiguity.", ex.Message); } + /// <summary> + /// Tests the exception. + /// </summary> [Test] public void TestException() { @@ -261,7 +264,7 @@ namespace Apache.Ignite.Core.Tests.Services { _svc = new TestIgniteService(Binary); - var prx = new ServiceProxy<T>(InvokeProxyMethod).GetTransparentProxy(); + var prx = ServiceProxyFactory<T>.CreateProxy(InvokeProxyMethod); Assert.IsFalse(ReferenceEquals(_svc, prx)); @@ -315,7 +318,7 @@ namespace Apache.Ignite.Core.Tests.Services /// <summary> /// Test service interface. /// </summary> - protected interface ITestIgniteServiceProperties + public interface ITestIgniteServiceProperties { /** */ int IntProp { get; set; } @@ -330,7 +333,7 @@ namespace Apache.Ignite.Core.Tests.Services /// <summary> /// Test service interface to check ambiguity handling. /// </summary> - protected interface ITestIgniteServiceAmbiguity + public interface ITestIgniteServiceAmbiguity { /** */ int AmbiguousMethod(int arg); @@ -339,7 +342,7 @@ namespace Apache.Ignite.Core.Tests.Services /// <summary> /// Test service interface. /// </summary> - protected interface ITestIgniteService : ITestIgniteServiceProperties + public interface ITestIgniteService : ITestIgniteServiceProperties { /** */ void VoidMethod(); @@ -390,7 +393,7 @@ namespace Apache.Ignite.Core.Tests.Services /// <summary> /// Test service interface. Does not derive from actual interface, but has all the same method signatures. /// </summary> - protected interface ITestIgniteServiceProxyInterface + public interface ITestIgniteServiceProxyInterface { /** */ int IntProp { get; set; } @@ -570,6 +573,7 @@ namespace Apache.Ignite.Core.Tests.Services /** <inheritdoc /> */ public override int GetHashCode() { + // ReSharper disable once NonReadonlyMemberInGetHashCode return IntProp.GetHashCode(); } @@ -653,7 +657,7 @@ namespace Apache.Ignite.Core.Tests.Services /// <summary> /// Binarizable object for method argument/result. /// </summary> - protected class TestBinarizableClass : IBinarizable + public class TestBinarizableClass : IBinarizable { /** */ public string Prop { get; set; } http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServicesTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServicesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServicesTest.cs index d3dd9b0..b8f4cdf 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServicesTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Services/ServicesTest.cs @@ -30,7 +30,6 @@ namespace Apache.Ignite.Core.Tests.Services using Apache.Ignite.Core.Common; using Apache.Ignite.Core.Resource; using Apache.Ignite.Core.Services; - using Apache.Ignite.Core.Tests.Compute; using NUnit.Framework; /// <summary> @@ -72,7 +71,6 @@ namespace Apache.Ignite.Core.Tests.Services public void SetUp() { StartGrids(); - EventsTestHelper.ListenResult = true; } /// <summary> @@ -96,8 +94,6 @@ namespace Apache.Ignite.Core.Tests.Services } finally { - EventsTestHelper.AssertFailures(); - if (TestContext.CurrentContext.Test.Name.StartsWith("TestEventTypes")) StopGrids(); // clean events for other tests } @@ -292,7 +288,6 @@ namespace Apache.Ignite.Core.Tests.Services // Check proxy properties Assert.IsNotNull(prx); - Assert.AreEqual(prx.GetType(), svc.GetType()); Assert.AreEqual(prx.ToString(), svc.ToString()); Assert.AreEqual(17, prx.TestProperty); Assert.IsTrue(prx.Initialized); @@ -352,8 +347,7 @@ namespace Apache.Ignite.Core.Tests.Services // .. but setter does not var ex = Assert.Throws<ServiceInvocationException>(() => { prx.TestProperty = new object(); }); - Assert.IsNotNull(ex.InnerException); - Assert.AreEqual("Specified cast is not valid.", ex.InnerException.Message); + Assert.IsInstanceOf<InvalidCastException>(ex.InnerException); } /// <summary> @@ -375,7 +369,6 @@ namespace Apache.Ignite.Core.Tests.Services Assert.AreEqual(1, desc.AffinityKey); Assert.AreEqual(1, desc.MaxPerNodeCount); Assert.AreEqual(1, desc.TotalCount); - Assert.AreEqual(typeof(TestIgniteServiceSerializable), desc.Type); Assert.AreEqual(Grid1.GetCluster().GetLocalNode().Id, desc.OriginNodeId); var top = desc.TopologySnapshot; @@ -747,11 +740,6 @@ namespace Apache.Ignite.Core.Tests.Services // Verify decriptor var descriptor = Services.GetServiceDescriptors().Single(x => x.Name == javaSvcName); Assert.AreEqual(javaSvcName, descriptor.Name); - Assert.Throws<ServiceInvocationException>(() => - { - // ReSharper disable once UnusedVariable - var type = descriptor.Type; - }); var svc = Services.GetServiceProxy<IJavaService>(javaSvcName, false); var binSvc = Services.WithKeepBinary().WithServerKeepBinary() @@ -833,9 +821,7 @@ namespace Apache.Ignite.Core.Tests.Services { foreach (var grid in Grids) { -#if !NETCOREAPP2_0 Assert.AreEqual(CompactFooter, ((Impl.Ignite) grid).Marshaller.CompactFooter); -#endif Assert.AreEqual(CompactFooter, grid.GetConfiguration().BinaryConfiguration.CompactFooter); } } @@ -848,9 +834,9 @@ namespace Apache.Ignite.Core.Tests.Services if (Grid1 != null) return; - Grid1 = Ignition.Start(GetConfiguration("config\\compute\\compute-grid1.xml")); - Grid2 = Ignition.Start(GetConfiguration("config\\compute\\compute-grid2.xml")); - Grid3 = Ignition.Start(GetConfiguration("config\\compute\\compute-grid3.xml")); + Grid1 = Ignition.Start(GetConfiguration("Config\\Compute\\compute-grid1.xml")); + Grid2 = Ignition.Start(GetConfiguration("Config\\Compute\\compute-grid2.xml")); + Grid3 = Ignition.Start(GetConfiguration("Config\\Compute\\compute-grid3.xml")); Grids = new[] { Grid1, Grid2, Grid3 }; } @@ -895,14 +881,16 @@ namespace Apache.Ignite.Core.Tests.Services /// </summary> private IgniteConfiguration GetConfiguration(string springConfigUrl) { +#if !NETCOREAPP2_0 if (!CompactFooter) - springConfigUrl = ComputeApiTestFullFooter.ReplaceFooterSetting(springConfigUrl); + { + springConfigUrl = Compute.ComputeApiTestFullFooter.ReplaceFooterSetting(springConfigUrl); + } +#endif - return new IgniteConfiguration + return new IgniteConfiguration(TestUtils.GetTestConfiguration()) { SpringConfigUrl = springConfigUrl, - JvmClasspath = TestUtils.CreateTestClasspath(), - JvmOptions = TestUtils.TestJavaOptions(), BinaryConfiguration = new BinaryConfiguration( typeof (TestIgniteServiceBinarizable), typeof (TestIgniteServiceBinarizableErr), @@ -952,7 +940,7 @@ namespace Apache.Ignite.Core.Tests.Services /// <summary> /// Test service interface for proxying. /// </summary> - private interface ITestIgniteService + public interface ITestIgniteService { int TestProperty { get; set; } @@ -982,7 +970,7 @@ namespace Apache.Ignite.Core.Tests.Services /// Test service interface for proxy usage. /// Has some of the original interface members with different signatures. /// </summary> - private interface ITestIgniteServiceProxyInterface + public interface ITestIgniteServiceProxyInterface { /** */ Guid NodeId { get; } @@ -1199,7 +1187,7 @@ namespace Apache.Ignite.Core.Tests.Services /// Java service proxy interface. /// </summary> [SuppressMessage("ReSharper", "InconsistentNaming")] - private interface IJavaService + public interface IJavaService { /** */ bool isCancelled(); @@ -1315,7 +1303,7 @@ namespace Apache.Ignite.Core.Tests.Services /// <summary> /// Interop class. /// </summary> - private class PlatformComputeBinarizable + public class PlatformComputeBinarizable { /** */ public int Field { get; set; } http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Common.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Common.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Common.cs index 2d735e9..c00ca49 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Common.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.Common.cs @@ -26,10 +26,8 @@ namespace Apache.Ignite.Core.Tests using Apache.Ignite.Core.Cluster; using Apache.Ignite.Core.Discovery.Tcp; using Apache.Ignite.Core.Discovery.Tcp.Static; -#if !NETCOREAPP2_0 using Apache.Ignite.Core.Impl; using Apache.Ignite.Core.Impl.Binary; -#endif using NUnit.Framework; /// <summary> @@ -320,7 +318,6 @@ namespace Apache.Ignite.Core.Tests /// <param name="timeout">Timeout, in milliseconds.</param> public static void AssertHandleRegistryHasItems(IIgnite grid, int expectedCount, int timeout) { -#if !NETCOREAPP2_0 var handleRegistry = ((Ignite)grid).HandleRegistry; expectedCount++; // Skip default lifecycle bean @@ -336,7 +333,6 @@ namespace Apache.Ignite.Core.Tests grid.Name, expectedCount, handleRegistry.Count, items.Select(x => x.ToString()).Aggregate((x, y) => x + "\n" + y)); } -#endif } /// <summary> @@ -349,24 +345,9 @@ namespace Apache.Ignite.Core.Tests Serializer = raw ? new BinaryReflectiveSerializer {RawMode = true} : null }; -#if NETCOREAPP2_0 - var marshType = typeof(IIgnite).Assembly.GetType("Apache.Ignite.Core.Impl.Binary.Marshaller"); - var marsh = Activator.CreateInstance(marshType, new object[] { cfg, null }); - marshType.GetProperty("CompactFooter").SetValue(marsh, false); - - var bytes = marshType.GetMethod("Marshal").MakeGenericMethod(typeof(object)) - .Invoke(marsh, new object[] { obj }); - - var res = marshType.GetMethods().Single(mi => - mi.Name == "Unmarshal" && mi.GetParameters().First().ParameterType == typeof(byte[])) - .MakeGenericMethod(typeof(object)).Invoke(marsh, new[] { bytes, 0 }); - - return (T)res; -#else var marsh = new Marshaller(cfg) { CompactFooter = false }; return marsh.Unmarshal<T>(marsh.Marshal(obj)); -#endif } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/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 cdde538..9a6aeb9 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -142,6 +142,9 @@ <Compile Include="Impl\IPlatformTargetInternal.cs" /> <Compile Include="Impl\DataRegionMetrics.cs" /> <Compile Include="Impl\PersistentStore\PersistentStoreMetrics.cs" /> + <Compile Include="Impl\Services\ServiceMethodHelper.cs" /> + <Compile Include="Impl\Services\ServiceProxyFactory.cs" /> + <Compile Include="Impl\Services\ServiceProxyTypeGenerator.cs" /> <Compile Include="Impl\Shell.cs" /> <Compile Include="Impl\Unmanaged\Jni\DllLoader.cs" /> <Compile Include="Impl\Unmanaged\Jni\AppDomains.cs" /> @@ -519,7 +522,6 @@ <Compile Include="Impl\Resource\ResourceTypeDescriptor.cs" /> <Compile Include="Impl\Services\ServiceContext.cs" /> <Compile Include="Impl\Services\ServiceDescriptor.cs" /> - <Compile Include="Impl\Services\ServiceProxy.cs" /> <Compile Include="Impl\Services\ServiceProxyInvoker.cs" /> <Compile Include="Impl\Services\ServiceProxySerializer.cs" /> <Compile Include="Impl\Services\Services.cs" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceMethodHelper.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceMethodHelper.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceMethodHelper.cs new file mode 100644 index 0000000..e6fb2c0 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceMethodHelper.cs @@ -0,0 +1,61 @@ +/* + * 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.Impl.Services +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Reflection; + + /// <summary> + /// Provides reflection information about types. + /// This class used by ServiceProxyTypeGenerator and by generated proxy (to initialize static field). + /// </summary> + internal static class ServiceMethodHelper + { + /// <summary> + /// Provides information about virtual methods of the type + /// </summary> + /// <param name="type">Type to inspect.</param> + /// <returns>List of virtual methods.</returns> + public static MethodInfo[] GetVirtualMethods(Type type) + { + Debug.Assert(type != null); + var methods = new List<MethodInfo>(); + + foreach (var method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | + BindingFlags.NonPublic | BindingFlags.DeclaredOnly)) + { + if (method.IsVirtual) + methods.Add(method); + } + + if (type.IsInterface) + { + foreach (var method in typeof(object).GetMethods( + BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) + { + if (method.IsVirtual) + methods.Add(method); + } + } + + return methods.ToArray(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxy.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxy.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxy.cs deleted file mode 100644 index 7952865..0000000 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxy.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - */ - -#if !NETCOREAPP2_0 -namespace Apache.Ignite.Core.Impl.Services -{ - using System; - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; - using System.Reflection; - using System.Runtime.Remoting.Messaging; - using System.Runtime.Remoting.Proxies; - - /// <summary> - /// Service proxy: user works with a remote service as if it is a local object. - /// </summary> - /// <typeparam name="T">User type to be proxied.</typeparam> - internal class ServiceProxy<T> : RealProxy - { - /** Services. */ - private readonly Func<MethodBase, object[], object> _invokeAction; - - /// <summary> - /// Initializes a new instance of the <see cref="ServiceProxy{T}" /> class. - /// </summary> - /// <param name="invokeAction">Method invoke action.</param> - public ServiceProxy(Func<MethodBase, object[], object> invokeAction) - : base(typeof (T)) - { - Debug.Assert(invokeAction != null); - - _invokeAction = invokeAction; - } - - /** <inheritdoc /> */ - [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")] - public override IMessage Invoke(IMessage msg) - { - var methodCall = msg as IMethodCallMessage; - - if (methodCall == null) - throw new NotSupportedException("Service proxy operation type not supported: " + msg.GetType() + - ". Only method and property calls are supported."); - - if (methodCall.InArgCount != methodCall.ArgCount) - throw new NotSupportedException("Service proxy does not support out arguments: " - + methodCall.MethodBase); - - var result = _invokeAction(methodCall.MethodBase, methodCall.Args); - - return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall); - } - - /** <inheritdoc /> */ - public new T GetTransparentProxy() - { - return (T) base.GetTransparentProxy(); - } - } -} -#endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxyFactory.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxyFactory.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxyFactory.cs new file mode 100644 index 0000000..a32f10e --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxyFactory.cs @@ -0,0 +1,68 @@ +/* + * 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.Impl.Services +{ + using System; + using System.Diagnostics; + using System.Linq.Expressions; + using System.Reflection; + using ProxyAction = System.Func<System.Reflection.MethodBase, object[], object>; + + /// <summary> + /// Factory for proxy creation. + /// </summary> + /// <typeparam name="T">User type to be proxied.</typeparam> + internal static class ServiceProxyFactory<T> + { + /** */ + private static readonly Func<ProxyAction, T> Factory = GenerateFactory(); + + /// <summary> + /// Creates proxy which methods call provided function. + /// </summary> + /// <param name="action">Action to call.</param> + /// <returns>Proxy.</returns> + public static T CreateProxy(ProxyAction action) + { + Debug.Assert(action != null); + + return Factory(action); + } + + /// <summary> + /// Generates the proxy factory. + /// </summary> + private static Func<ProxyAction, T> GenerateFactory() + { + // Generate proxy class + var result = ServiceProxyTypeGenerator.Generate(typeof(T)); + var typeCtr = result.Item1.GetConstructor(new[] { typeof(ProxyAction), typeof(MethodInfo[]) }); + Debug.Assert(typeCtr != null); + + // Generate method that creates proxy class instance. + // Single parameter of method + var action = Expression.Parameter(typeof(ProxyAction)); + + // Call constructor and pass action parameter and array of methods. + var ctr = Expression.New(typeCtr, action, Expression.Constant(result.Item2)); + var lambda = Expression.Lambda<Func<ProxyAction, T>>(ctr, action); + + return lambda.Compile(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxyTypeGenerator.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxyTypeGenerator.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxyTypeGenerator.cs new file mode 100644 index 0000000..97de9c7 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/ServiceProxyTypeGenerator.cs @@ -0,0 +1,281 @@ +/* + * 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.Impl.Services +{ + using System; + using System.Diagnostics; + using System.Reflection; + using System.Reflection.Emit; + using ProxyAction = System.Func<System.Reflection.MethodBase, object[], object>; + + /// <summary> + /// Emits service proxy type. + /// </summary> + internal static class ServiceProxyTypeGenerator + { + /** */ + private static readonly Type ActionType = typeof(ProxyAction); + + /** */ + private static readonly MethodInfo InvokeMethod = ActionType.GetMethod("Invoke"); + + /** */ + private static readonly ModuleBuilder ModuleBuilder = CreateModuleBuilder(); + + /// <summary> + /// Generates the proxy for specified service type. + /// </summary> + public static Tuple<Type, MethodInfo[]> Generate(Type serviceType) + { + Debug.Assert(serviceType != null); + Debug.Assert(serviceType.FullName != null); + + var isClass = serviceType.IsClass; + var proxyType = ModuleBuilder.DefineType(serviceType.FullName, + TypeAttributes.Class, isClass ? serviceType : null); + + var buildContext = new ProxyBuildContext(proxyType, serviceType); + if (!isClass) + { + proxyType.AddInterfaceImplementation(serviceType); + } + + GenerateFields(buildContext); + GenerateStaticConstructor(buildContext); + GenerateConstructor(buildContext); + + buildContext.Methods = ServiceMethodHelper.GetVirtualMethods(buildContext.ServiceType); + for (var i = 0; i < buildContext.Methods.Length; i++) + { + GenerateMethod(buildContext, i); + } + + var type = proxyType.CreateType(); + return Tuple.Create(type, buildContext.Methods); + } + + /// <summary> + /// Creates a builder for a temporary module. + /// </summary> + private static ModuleBuilder CreateModuleBuilder() + { + var name = Guid.NewGuid().ToString("N"); + +#if !NETCOREAPP2_0 + var assemblyBuilder = + AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(name), + AssemblyBuilderAccess.RunAndCollect); +#else + var assemblyBuilder = + AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(name), + AssemblyBuilderAccess.RunAndCollect); +#endif + + return assemblyBuilder.DefineDynamicModule(name); + } + + /// <summary> + /// Generates readonly fields: action and method array. + /// </summary> + private static void GenerateFields(ProxyBuildContext buildContext) + { + // Static field - empty object array to optimize calls without parameters. + buildContext.EmptyParametersField = buildContext.ProxyType.DefineField("_emptyParameters", + typeof(object[]), FieldAttributes.Static | FieldAttributes.Private | FieldAttributes.InitOnly); + + // Instance field for function to invoke. + buildContext.ActionField = buildContext.ProxyType.DefineField("_action", ActionType, + FieldAttributes.Private | FieldAttributes.InitOnly); + + // Field - array with methods of service's type. + buildContext.MethodsField = buildContext.ProxyType.DefineField("_methods", typeof(MethodInfo[]), + FieldAttributes.Private | FieldAttributes.InitOnly); + } + + /// <summary> + /// Generates the static constructor (type initializer). + /// </summary> + private static void GenerateStaticConstructor(ProxyBuildContext buildContext) + { + var cb = buildContext.ProxyType.DefineConstructor( + MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.HideBySig, + CallingConventions.Standard, new Type[0]); + var gen = cb.GetILGenerator(); + //fill _emptyParameters field + gen.Emit(OpCodes.Ldc_I4_0); + gen.Emit(OpCodes.Newarr, typeof(object)); + gen.Emit(OpCodes.Stsfld, buildContext.EmptyParametersField); + + gen.Emit(OpCodes.Ret); + } + + /// <summary> + /// Generates the constructor which calls base class (when necessary) and initializes fields. + /// </summary> + private static void GenerateConstructor(ProxyBuildContext buildContext) + { + var baseType = buildContext.ServiceType; + var isClass = baseType.IsClass; + + ConstructorInfo baseCtr = null; + if (isClass) + { + baseCtr = baseType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, + null, new Type[0], null); + if (baseCtr == null) + throw new NotSupportedException( + "Service proxy does not support base types without parameterless constructor: " + + baseType.FullName); + } + + var cb = buildContext.ProxyType.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, + new[] {ActionType, typeof(MethodInfo[])}); + var gen = cb.GetILGenerator(); + + if (isClass) + { + // Load "this". + gen.Emit(OpCodes.Ldarg_0); + // Call base constructor. + gen.Emit(OpCodes.Call, baseCtr); + } + + // Assign parameters to fields. + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Ldarg_1); + gen.Emit(OpCodes.Stfld, buildContext.ActionField); + + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Ldarg_2); + gen.Emit(OpCodes.Stfld, buildContext.MethodsField); + + gen.Emit(OpCodes.Ret); + } + + /// <summary> + /// Generates the overriding method which delegates to ProxyAction. + /// </summary> + private static void GenerateMethod(ProxyBuildContext buildContext, int methodIndex) + { + var method = buildContext.Methods[methodIndex]; + Debug.Assert(method.DeclaringType != null); + var parameters = method.GetParameters(); + var parameterTypes = new Type[parameters.Length]; + for (var i = 0; i < parameters.Length; i++) + parameterTypes[i] = parameters[i].ParameterType; + + var attributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig; + if (method.DeclaringType.IsInterface) + attributes |= MethodAttributes.Final | MethodAttributes.NewSlot; + if ((method.Attributes & MethodAttributes.SpecialName) == MethodAttributes.SpecialName) + attributes |= MethodAttributes.SpecialName; + var methodBuilder = + buildContext.ProxyType.DefineMethod(method.Name, attributes, method.ReturnType, parameterTypes); + var gen = methodBuilder.GetILGenerator(); + + // Prepare arguments for action invocation. + + // Load action field. + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Ldfld, buildContext.ActionField); + + // Load methods array field. + gen.Emit(OpCodes.Ldarg_0); + gen.Emit(OpCodes.Ldfld, buildContext.MethodsField); + + // Load index of method. + gen.Emit(OpCodes.Ldc_I4, methodIndex); + + // Load array element. + gen.Emit(OpCodes.Ldelem_Ref); + + if (parameters.Length > 0) + { + // Create array for action's parameters. + gen.Emit(OpCodes.Ldc_I4, parameters.Length); + gen.Emit(OpCodes.Newarr, typeof(object)); + + // Fill array. + // Load call arguments. + for (var i = 0; i < parameters.Length; i++) + { + gen.Emit(OpCodes.Dup); + + // Parameter's index in array. + gen.Emit(OpCodes.Ldc_I4, i); + + // Parameter's value. + gen.Emit(OpCodes.Ldarg, i + 1); + if (parameterTypes[i].IsValueType) + { + gen.Emit(OpCodes.Box, parameterTypes[i]); + } + + // Set array's element + gen.Emit(OpCodes.Stelem_Ref); + } + } + else + { + // Load static empty parameters field. + gen.Emit(OpCodes.Ldsfld, buildContext.EmptyParametersField); + } + + // Call action method. + gen.Emit(OpCodes.Callvirt, InvokeMethod); + + // Load result. + if (method.ReturnType != typeof(void)) + { + if (method.ReturnType.IsValueType) + gen.Emit(OpCodes.Unbox_Any, method.ReturnType); + } + else + { + // Method should not return result, so remove result from stack. + gen.Emit(OpCodes.Pop); + } + //exit + gen.Emit(OpCodes.Ret); + } + + /// <summary> + /// Proxy build state. + /// </summary> + private class ProxyBuildContext + { + /// <summary> + /// Initializes a new instance of the <see cref="ProxyBuildContext"/> class. + /// </summary> + public ProxyBuildContext(TypeBuilder proxyType, Type serviceType) + { + ProxyType = proxyType; + ServiceType = serviceType; + } + + /** */ public TypeBuilder ProxyType { get; private set; } + /** */ public Type ServiceType { get; private set; } + + /** */ public FieldBuilder MethodsField { get; set; } + /** */ public FieldBuilder EmptyParametersField { get; set; } + /** */ public FieldBuilder ActionField { get; set; } + + /** */ public MethodInfo[] Methods { get; set; } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/Services.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/Services.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/Services.cs index ce8332b..0360f97 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/Services.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Services/Services.cs @@ -366,7 +366,6 @@ namespace Apache.Ignite.Core.Impl.Services /** <inheritDoc /> */ public T GetServiceProxy<T>(string name, bool sticky) where T : class { -#if !NETCOREAPP2_0 IgniteArgumentCheck.NotNullOrEmpty(name, "name"); IgniteArgumentCheck.Ensure(typeof(T).IsInterface, "T", "Service proxy type should be an interface: " + typeof(T)); @@ -385,11 +384,8 @@ namespace Apache.Ignite.Core.Impl.Services var platform = GetServiceDescriptors().Cast<ServiceDescriptor>().Single(x => x.Name == name).Platform; - return new ServiceProxy<T>((method, args) => - InvokeProxyMethod(javaProxy, method, args, platform)).GetTransparentProxy(); -#else - throw new Apache.Ignite.Core.Common.IgniteException("Service proxies are not supported on .NET Core: IGNITE-7281"); -#endif + return ServiceProxyFactory<T>.CreateProxy((method, args) => + InvokeProxyMethod(javaProxy, method, args, platform)); } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs index 7dc615c..0c0f44c 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Properties/AssemblyInfo.cs @@ -44,5 +44,7 @@ using System.Runtime.InteropServices; [assembly: InternalsVisibleTo("Apache.Ignite.Core.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a5bf8e0062a26bde53ccf0f8c42ef5b122a22052f99aecacb7028adcc163050324ee3c75ff40eb0cbe2d0426fa20eca03726cad90d7eb882ff47f5361567a82b676a27565f88b2479d7b9354ae0a1e526ee781b6e11de943d8f4a49efb53765f8c954022bede0fca86c133fab038af8dc88b67d6b6e5b9796d6ca490e699efab")] [assembly: InternalsVisibleTo("Apache.Ignite.Benchmarks, PublicKey=0024000004800000940000000602000000240000525341310004000001000100a3e0c1df4cbedbd4ed0e88808401c69b69ec12575ed1c056ac9f448e018fb29af19d236b7b03563aad66c48ab2045e72971ed098d4f65d4cdd38d65abcb39b4f84c626b22ccab2754375f0e8c97dc304fa146f0eddad5cc40a71803a8f15b0b0bb0bff0d4bf0ff6a64bb1044e0d71e6e2405b83fd4c1f7b3e2cfc2e9d50823d4")] [assembly: InternalsVisibleTo("Apache.Ignite.AspNet.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c9380ce05eb74bd7c531f72e9ea615c59d7eceb09bd9795cb3dff1fcf638fd799c2a58a9be42fff156efe1c8cdebb751e27763f6c9a7c80cdc1dc1bbf44283608ef18ccd5017fd57b2b026503637c89c2537f361807f3bdd49265f4d444716159d989342561d324b1a0961640338bb32eaf67f4ae0c95f1b210f65404b0909c6")] - +#if NETCOREAPP2_0 +[assembly: InternalsVisibleTo("Apache.Ignite.Core.Tests.DotNetCore")] +#endif #endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/ssh/src/main/java/org/apache/ignite/internal/util/nodestart/StartNodeCallableImpl.java ---------------------------------------------------------------------- diff --git a/modules/ssh/src/main/java/org/apache/ignite/internal/util/nodestart/StartNodeCallableImpl.java b/modules/ssh/src/main/java/org/apache/ignite/internal/util/nodestart/StartNodeCallableImpl.java index f192d59..c9bc7ee 100644 --- a/modules/ssh/src/main/java/org/apache/ignite/internal/util/nodestart/StartNodeCallableImpl.java +++ b/modules/ssh/src/main/java/org/apache/ignite/internal/util/nodestart/StartNodeCallableImpl.java @@ -25,17 +25,26 @@ import com.jcraft.jsch.Session; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.InterruptedIOException; import java.io.PrintStream; +import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; +import org.apache.ignite.Ignite; import org.apache.ignite.IgniteLogger; import org.apache.ignite.cluster.ClusterStartNodeResult; +import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.IgniteInterruptedCheckedException; import org.apache.ignite.internal.cluster.ClusterStartNodeResultImpl; +import org.apache.ignite.internal.processors.timeout.GridTimeoutObject; +import org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter; +import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor; import org.apache.ignite.internal.util.typedef.X; +import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.resources.IgniteInstanceResource; import org.apache.ignite.resources.LoggerResource; import static org.apache.ignite.IgniteSystemProperties.IGNITE_SSH_HOST; @@ -51,12 +60,30 @@ public class StartNodeCallableImpl implements StartNodeCallable { /** Default Ignite home path for Linux (taken from environment variable). */ private static final String DFLT_IGNITE_HOME_LINUX = "$IGNITE_HOME"; + /** Windows console encoding */ + private static final String WINDOWS_ENCODING = "IBM866"; + + /** Default start script path for Windows. */ + private static final String DFLT_SCRIPT_WIN = "bin\\ignite.bat -v -np"; + /** Default start script path for Linux. */ private static final String DFLT_SCRIPT_LINUX = "bin/ignite.sh -v"; /** Date format for log file name. */ private static final SimpleDateFormat FILE_NAME_DATE_FORMAT = new SimpleDateFormat("MM-dd-yyyy--HH-mm-ss"); + /** Used to register successful node start in log */ + private static final String SUCCESSFUL_START_MSG = "Successfully bound to TCP port"; + + /** */ + private static final long EXECUTE_WAIT_TIME = 1000; + + /** */ + private static final long NODE_START_CHECK_PERIOD = 2000; + + /** */ + private static final long NODE_START_CHECK_LIMIT = 5; + /** Specification. */ private final IgniteRemoteStartSpecification spec; @@ -65,13 +92,18 @@ public class StartNodeCallableImpl implements StartNodeCallable { /** Logger. */ @LoggerResource - private IgniteLogger log; + private transient IgniteLogger log; + + /** Ignite. */ + @IgniteInstanceResource + private transient Ignite ignite; /** * Required by Externalizable. */ public StartNodeCallableImpl() { spec = null; + timeout = 0; assert false; @@ -87,6 +119,7 @@ public class StartNodeCallableImpl implements StartNodeCallable { assert spec != null; this.spec = spec; + this.timeout = timeout; } @@ -111,6 +144,8 @@ public class StartNodeCallableImpl implements StartNodeCallable { boolean win = isWindows(ses); + info("Windows mode: " + win, spec.logger(), log); + char separator = win ? '\\' : '/'; spec.fixPaths(separator); @@ -123,30 +158,95 @@ public class StartNodeCallableImpl implements StartNodeCallable { String script = spec.script(); if (script == null) - script = DFLT_SCRIPT_LINUX; + script = win ? DFLT_SCRIPT_WIN : DFLT_SCRIPT_LINUX; String cfg = spec.configuration(); if (cfg == null) cfg = ""; - String startNodeCmd; - String scriptOutputFileName = FILE_NAME_DATE_FORMAT.format(new Date()) + '-' - + UUID.randomUUID().toString().substring(0, 8) + ".log"; + String id = FILE_NAME_DATE_FORMAT.format(new Date()) + '-' + UUID.randomUUID().toString().substring(0, 8); + + String scriptOutputFileName = id + ".log"; + + int spaceIdx = script.indexOf(' '); - if (win) - throw new UnsupportedOperationException("Apache Ignite cannot be auto-started on Windows from IgniteCluster.startNodes(â¦) API."); + String scriptPath = spaceIdx > -1 ? script.substring(0, spaceIdx) : script; + + String scriptArgs = spaceIdx > -1 ? script.substring(spaceIdx + 1) : ""; + + String rmtLogArgs = buildRemoteLogArguments(spec.username(), spec.host()); + + String scriptOutputDir; + + String dfltTmpDir = igniteHome + separator + "work" + separator + "log"; + + if (win) { + String tmpDir = env(ses, "%TMPDIR%", dfltTmpDir, WINDOWS_ENCODING); + + if ("%TMPDIR%".equals(tmpDir)) + tmpDir = dfltTmpDir; + + scriptOutputDir = tmpDir + "\\ignite-startNodes"; + } else { // Assume Unix. - int spaceIdx = script.indexOf(' '); + String logDir = env(ses, "$TMPDIR", dfltTmpDir); + + scriptOutputDir = logDir + "/ignite-startNodes"; + } + + shell(ses, "mkdir " + scriptOutputDir); - String scriptPath = spaceIdx > -1 ? script.substring(0, spaceIdx) : script; - String scriptArgs = spaceIdx > -1 ? script.substring(spaceIdx + 1) : ""; - String rmtLogArgs = buildRemoteLogArguments(spec.username(), spec.host()); - String tmpDir = env(ses, "$TMPDIR", "/tmp/"); - String scriptOutputDir = tmpDir + "ignite-startNodes"; + String scriptOutputPath = scriptOutputDir + separator + scriptOutputFileName; - shell(ses, "mkdir " + scriptOutputDir); + String findSuccess; + if (win) { + String scriptFileName = scriptOutputDir + '\\' + id + ".bat"; + + String createScript = new SB() + .a("echo \"").a(igniteHome).a('\\').a(scriptPath).a("\" ") + .a(scriptArgs) + .a(!cfg.isEmpty() ? " \"" : "").a(cfg).a(!cfg.isEmpty() ? "\"" : "") + .a(rmtLogArgs) + .a(" ^> ").a(scriptOutputPath).a(" ^2^>^&^1") + .a(" > ").a(scriptFileName) + .toString(); + + info("Create script with command: " + createScript, spec.logger(), log); + + shell(ses, createScript); + + try { + String createTask = new SB() + .a("schtasks /create /f /sc onstart") + .a(" /ru ").a(spec.username()) + .a(" /rp ").a(spec.password()) + .a(" /tn ").a(id) + .a(" /np /tr \"").a(scriptFileName).a('\"') + .toString(); + + info("Create task with command: " + createTask, spec.logger(), log); + + shell(ses, createTask); + + String runTask = "schtasks /run /i /tn " + id; + + info("Run task with command: " + runTask, spec.logger(), log); + + shell(ses, runTask); + } + finally { + String deleteTask = "schtasks /delete /f /tn " + id; + + info("Delete task with command: " + deleteTask, spec.logger(), log); + + shell(ses, deleteTask); + } + + findSuccess = "find \"" + SUCCESSFUL_START_MSG + "\" " + scriptOutputPath; + } + else { // Assume Unix. // Mac os don't support ~ in double quotes. Trying get home path from remote system. if (igniteHome.startsWith("~")) { String homeDir = env(ses, "$HOME", "~"); @@ -154,22 +254,36 @@ public class StartNodeCallableImpl implements StartNodeCallable { igniteHome = igniteHome.replaceFirst("~", homeDir); } - startNodeCmd = new SB(). + String startNodeCmd = new SB() // Console output is consumed, started nodes must use Ignite file appenders for log. - a("nohup "). - a("\"").a(igniteHome).a('/').a(scriptPath).a("\""). - a(" ").a(scriptArgs). - a(!cfg.isEmpty() ? " \"" : "").a(cfg).a(!cfg.isEmpty() ? "\"" : ""). - a(rmtLogArgs). - a(" > ").a(scriptOutputDir).a("/").a(scriptOutputFileName).a(" 2>& 1 &"). - toString(); + .a("nohup ") + .a("\"").a(igniteHome).a('/').a(scriptPath).a("\"") + .a(" ").a(scriptArgs) + .a(!cfg.isEmpty() ? " \"" : "").a(cfg).a(!cfg.isEmpty() ? "\"" : "") + .a(rmtLogArgs) + .a(" > ").a(scriptOutputDir).a('/').a(scriptOutputFileName).a(" 2>& 1 &") + .toString(); + + info("Starting remote node with SSH command: " + startNodeCmd, spec.logger(), log); + + shell(ses, startNodeCmd); + + findSuccess = "grep \"" + SUCCESSFUL_START_MSG + "\" " + scriptOutputPath; } - info("Starting remote node with SSH command: " + startNodeCmd, spec.logger(), log); + for (int i = 0; i < NODE_START_CHECK_LIMIT; ++i) { + Thread.sleep(NODE_START_CHECK_PERIOD); + + String res = exec(ses, findSuccess, win ? WINDOWS_ENCODING : null); - shell(ses, startNodeCmd); + info("Find result: " + res, spec.logger(), log); + + if (res != null && res.contains(SUCCESSFUL_START_MSG)) + return new ClusterStartNodeResultImpl(spec.host(), true, null); + } - return new ClusterStartNodeResultImpl(spec.host(), true, null); + return new ClusterStartNodeResultImpl(spec.host(), false, "Remote node could not start. " + + "See log for details: " + scriptOutputPath); } catch (IgniteInterruptedCheckedException e) { return new ClusterStartNodeResultImpl(spec.host(), false, e.getMessage()); @@ -203,7 +317,7 @@ public class StartNodeCallableImpl implements StartNodeCallable { try (PrintStream out = new PrintStream(ch.getOutputStream(), true)) { out.println(cmd); - U.sleep(1000); + U.sleep(EXECUTE_WAIT_TIME); } } finally { @@ -238,8 +352,29 @@ public class StartNodeCallableImpl implements StartNodeCallable { * @throws JSchException In case of SSH error. */ private String env(Session ses, String name, String dflt) throws JSchException { + return env(ses, name, dflt, null); + } + + /** + * Gets the value of the specified environment variable. + * + * @param ses SSH session. + * @param name environment variable name. + * @param dflt default value. + * @param encoding Process output encoding, {@code null} for default charset encoding. + * @return environment variable value. + * @throws JSchException In case of SSH error. + */ + private String env(Session ses, String name, String dflt, String encoding) throws JSchException { try { - return exec(ses, "echo " + name); + String res = exec(ses, "echo " + name, encoding); + + if (res == null) + return dflt; + + res = res.trim(); + + return res.isEmpty() ? dflt : res; } catch (IOException ignored) { return dflt; @@ -256,6 +391,20 @@ public class StartNodeCallableImpl implements StartNodeCallable { * @throws IOException If failed. */ private String exec(Session ses, String cmd) throws JSchException, IOException { + return exec(ses, cmd, null); + } + + /** + * Gets the value of the specified environment variable. + * + * @param ses SSH session. + * @param cmd environment variable name. + * @param encoding Process output encoding, {@code null} for default charset encoding. + * @return environment variable value. + * @throws JSchException In case of SSH error. + * @throws IOException If failed. + */ + private String exec(Session ses, final String cmd, String encoding) throws JSchException, IOException { ChannelExec ch = null; try { @@ -265,9 +414,62 @@ public class StartNodeCallableImpl implements StartNodeCallable { ch.connect(); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(ch.getInputStream()))) { - return reader.readLine(); + if (encoding == null) + encoding = Charset.defaultCharset().name(); + + IgniteEx grid = (IgniteEx)ignite; + + GridTimeoutProcessor proc = grid.context().timeout(); + + GridTimeoutObject to = null; + + SB out = null; + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(ch.getInputStream(), encoding))) { + String line; + + boolean first = true; + + while ((line = reader.readLine()) != null) { + if (first) + out = new SB(); + else + out.a('\n'); + + out.a(line); + + if (first) { + to = new GridTimeoutObjectAdapter(EXECUTE_WAIT_TIME) { + /** */ + private final Thread thread = Thread.currentThread(); + + @Override public void onTimeout() { + thread.interrupt(); + } + + @Override public String toString() { + return S.toString("GridTimeoutObject", "cmd", cmd, "thread", thread); + } + }; + + assert proc.addTimeoutObject(to) : "Timeout object was not added: " + to; + + first = false; + } + } } + catch (InterruptedIOException ignore) { + // No-op. + } + finally { + if (to != null) { + boolean r = proc.removeTimeoutObject(to); + + assert r || to.endTime() <= U.currentTimeMillis() : "Timeout object was not removed: " + to; + } + } + + return out == null ? null : out.toString(); } finally { if (ch != null && ch.isConnected()) http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/web-console/frontend/app/app.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/app.js b/modules/web-console/frontend/app/app.js index 332bc24..7380124 100644 --- a/modules/web-console/frontend/app/app.js +++ b/modules/web-console/frontend/app/app.js @@ -92,6 +92,7 @@ import ModelNormalizer from './services/ModelNormalizer.service.js'; import UnsavedChangesGuard from './services/UnsavedChangesGuard.service'; import Clusters from './services/Clusters'; import Caches from './services/Caches'; +import {CSV} from './services/CSV'; import AngularStrapTooltip from './services/AngularStrapTooltip.decorator'; import AngularStrapSelect from './services/AngularStrapSelect.decorator'; @@ -263,6 +264,7 @@ angular.module('ignite-console', [ .service('IgniteActivitiesUserDialog', IgniteActivitiesUserDialog) .service('Clusters', Clusters) .service('Caches', Caches) +.service(CSV.name, CSV) // Controllers. .controller(...resetPassword) .controller(...profile) http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/web-console/frontend/app/components/grid-export/component.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/grid-export/component.js b/modules/web-console/frontend/app/components/grid-export/component.js index 9c239a6..18e41c7 100644 --- a/modules/web-console/frontend/app/components/grid-export/component.js +++ b/modules/web-console/frontend/app/components/grid-export/component.js @@ -16,13 +16,18 @@ */ import template from './template.pug'; +import {CSV} from 'app/services/CSV'; export default { template, controller: class { - static $inject = ['$scope', 'uiGridGroupingConstants', 'uiGridExporterService', 'uiGridExporterConstants']; + static $inject = ['$scope', 'uiGridGroupingConstants', 'uiGridExporterService', 'uiGridExporterConstants', CSV.name]; - constructor($scope, uiGridGroupingConstants, uiGridExporterService, uiGridExporterConstants) { + /** + * @param {CSV} CSV + */ + constructor($scope, uiGridGroupingConstants, uiGridExporterService, uiGridExporterConstants, CSV) { + this.CSV = CSV; Object.assign(this, { uiGridGroupingConstants, uiGridExporterService, uiGridExporterConstants }); } @@ -42,7 +47,7 @@ export default { data.push(values); }); - const csvContent = this.uiGridExporterService.formatAsCsv(columnHeaders, data, this.gridApi.grid.options.exporterCsvColumnSeparator); + const csvContent = this.uiGridExporterService.formatAsCsv(columnHeaders, data, this.CSV.getSeparator()); this.uiGridExporterService.downloadFile(this.gridApi.grid.options.exporterCsvFilename, csvContent, this.gridApi.grid.options.exporterOlderExcelCompatibility); } }, http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js index 6c55753..62bc269 100644 --- a/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js +++ b/modules/web-console/frontend/app/components/list-of-registered-users/list-of-registered-users.controller.js @@ -91,7 +91,11 @@ export default class IgniteListOfRegisteredUsersCtrl { user.adminChanging = true; AdminData.toggleAdmin(user) - .finally(() => user.adminChanging = false); + .finally(() => { + $ctrl._updateSelected(); + + user.adminChanging = false; + }); }; const showActivities = () => { http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/web-console/frontend/app/components/page-queries/controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-queries/controller.js b/modules/web-console/frontend/app/components/page-queries/controller.js index bd03b22..a871a0d 100644 --- a/modules/web-console/frontend/app/components/page-queries/controller.js +++ b/modules/web-console/frontend/app/components/page-queries/controller.js @@ -25,6 +25,8 @@ import { fromPromise } from 'rxjs/observable/fromPromise'; import { timer } from 'rxjs/observable/timer'; import { defer } from 'rxjs/observable/defer'; +import {CSV} from 'app/services/CSV'; + import paragraphRateTemplateUrl from 'views/sql/paragraph-rate.tpl.pug'; import cacheMetadataTemplateUrl from 'views/sql/cache-metadata.tpl.pug'; import chartSettingsTemplateUrl from 'views/sql/chart-settings.tpl.pug'; @@ -246,11 +248,15 @@ class Paragraph { // Controller for SQL notebook screen. export default class { - static $inject = ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$filter', '$modal', '$popover', 'IgniteLoading', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'AgentManager', 'IgniteChartColors', 'IgniteNotebook', 'IgniteNodes', 'uiGridExporterConstants', 'IgniteVersion', 'IgniteActivitiesData', 'JavaTypes', 'IgniteCopyToClipboard']; + static $inject = ['$rootScope', '$scope', '$http', '$q', '$timeout', '$interval', '$animate', '$location', '$anchorScroll', '$state', '$filter', '$modal', '$popover', 'IgniteLoading', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteConfirm', 'AgentManager', 'IgniteChartColors', 'IgniteNotebook', 'IgniteNodes', 'uiGridExporterConstants', 'IgniteVersion', 'IgniteActivitiesData', 'JavaTypes', 'IgniteCopyToClipboard', CSV.name]; - constructor($root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, LegacyUtils, Messages, Confirm, agentMgr, IgniteChartColors, Notebook, Nodes, uiGridExporterConstants, Version, ActivitiesData, JavaTypes, IgniteCopyToClipboard) { + /** + * @param {CSV} CSV + */ + constructor($root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, LegacyUtils, Messages, Confirm, agentMgr, IgniteChartColors, Notebook, Nodes, uiGridExporterConstants, Version, ActivitiesData, JavaTypes, IgniteCopyToClipboard, CSV) { const $ctrl = this; + this.CSV = CSV; Object.assign(this, { $root, $scope, $http, $q, $timeout, $interval, $animate, $location, $anchorScroll, $state, $filter, $modal, $popover, Loading, LegacyUtils, Messages, Confirm, agentMgr, IgniteChartColors, Notebook, Nodes, uiGridExporterConstants, Version, ActivitiesData, JavaTypes }); // Define template urls. @@ -1654,6 +1660,7 @@ export default class { }; const _export = (fileName, columnDefs, meta, rows, toClipBoard = false) => { + const csvSeparator = this.CSV.getSeparator(); let csvContent = ''; const cols = []; @@ -1666,7 +1673,7 @@ export default class { excludedCols.push(idx); }); - csvContent += cols.join(';') + '\n'; + csvContent += cols.join(csvSeparator) + '\n'; _.forEach(rows, (row) => { cols.length = 0; @@ -1689,7 +1696,7 @@ export default class { }); } - csvContent += cols.join(';') + '\n'; + csvContent += cols.join(csvSeparator) + '\n'; }); if (toClipBoard) http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/web-console/frontend/app/components/web-console-header/component.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/web-console-header/component.js b/modules/web-console/frontend/app/components/web-console-header/component.js index 3b1f2f2..a0a8230 100644 --- a/modules/web-console/frontend/app/components/web-console-header/component.js +++ b/modules/web-console/frontend/app/components/web-console-header/component.js @@ -24,7 +24,7 @@ export default { static $inject = ['$rootScope', '$scope', '$state', 'IgniteBranding', 'UserNotifications']; static connectedClustersUnvisibleStates = [ - '403', '404' + '403', '404', 'signin' ]; constructor($rootScope, $scope, $state, branding, UserNotifications) { http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js index 0c40890..cf14293 100644 --- a/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js +++ b/modules/web-console/frontend/app/modules/configuration/generator/ConfigurationGenerator.js @@ -1479,7 +1479,8 @@ export default class IgniteConfigurationGenerator { .boolProperty('cacheSanityCheckEnabled'); } - cfg.boolProperty('lateAffinityAssignment'); + if (available(['1.0.0', '2.1.0'])) + cfg.boolProperty('lateAffinityAssignment'); return cfg; } @@ -1509,30 +1510,34 @@ export default class IgniteConfigurationGenerator { // Generate marshaller group. static clusterMarshaller(cluster, available, cfg = this.igniteConfigurationBean(cluster)) { - const kind = _.get(cluster.marshaller, 'kind'); - const settings = _.get(cluster.marshaller, kind); + if (available(['1.0.0', '2.1.0'])) { + const kind = _.get(cluster.marshaller, 'kind'); + const settings = _.get(cluster.marshaller, kind); - let bean; + let bean; - switch (kind) { - case 'OptimizedMarshaller': - bean = new Bean('org.apache.ignite.marshaller.optimized.OptimizedMarshaller', 'marshaller', settings) - .intProperty('poolSize') - .intProperty('requireSerializable'); + switch (kind) { + case 'OptimizedMarshaller': + if (available(['1.0.0', '2.0.0'])) { + bean = new Bean('org.apache.ignite.marshaller.optimized.OptimizedMarshaller', 'marshaller', settings) + .intProperty('poolSize') + .intProperty('requireSerializable'); + } - break; + break; - case 'JdkMarshaller': - bean = new Bean('org.apache.ignite.marshaller.jdk.JdkMarshaller', 'marshaller', settings); + case 'JdkMarshaller': + bean = new Bean('org.apache.ignite.marshaller.jdk.JdkMarshaller', 'marshaller', settings); - break; + break; - default: + default: // No-op. - } + } - if (bean) - cfg.beanProperty('marshaller', bean); + if (bean) + cfg.beanProperty('marshaller', bean); + } cfg.intProperty('marshalLocalJobs'); @@ -1881,7 +1886,8 @@ export default class IgniteConfigurationGenerator { /** * Generate eviction policy object. * @param {Object} ccfg Parent configuration. - * @param {String} name Property name. + * @param {Function} available Function to check feature is supported in Ignite current version. + * @param {Boolean} near Near cache flag. * @param {Object} src Source. * @param {Object} dflt Default. * @returns {Object} Parent configuration. @@ -2335,7 +2341,7 @@ export default class IgniteConfigurationGenerator { this.cacheNodeFilter(cache, igfs ? [igfs] : [], ccfg); this.cacheConcurrency(cache, available, ccfg); this.cacheRebalance(cache, ccfg); - this.cacheNearServer(cache, ccfg); + this.cacheNearServer(cache, available, ccfg); this.cacheStatistics(cache, ccfg); this.cacheDomains(cache.domains, available, ccfg); http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js b/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js index e5f4804..74b3fc6 100644 --- a/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js +++ b/modules/web-console/frontend/app/modules/configuration/generator/JavaTransformer.service.js @@ -17,7 +17,9 @@ import AbstractTransformer from './AbstractTransformer'; import StringBuilder from './StringBuilder'; +import VersionService from 'app/services/Version.service'; +const versionService = new VersionService(); const STORE_FACTORY = ['org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory']; // Descriptors for generation of demo data. @@ -884,12 +886,13 @@ export default class IgniteJavaTransformer extends AbstractTransformer { * Build Java startup class with configuration. * * @param {Bean} cfg + * @param available Function to check target version of generated source to appropriate for generation. * @param pkg Package name. * @param {String} clsName Class name for generate factory class otherwise generate code snippet. * @param {Array.<Object>} clientNearCaches Is client node. * @returns {StringBuilder} */ - static igniteConfiguration(cfg, pkg, clsName, clientNearCaches) { + static igniteConfiguration(cfg, available, pkg, clsName, clientNearCaches) { const sb = new StringBuilder(); sb.append(`package ${pkg};`); @@ -903,7 +906,7 @@ export default class IgniteJavaTransformer extends AbstractTransformer { imports.push('org.apache.ignite.configuration.NearCacheConfiguration'); _.forEach(clientNearCaches, (cache) => { - const nearCacheBean = this.generator.cacheNearClient(cache); + const nearCacheBean = this.generator.cacheNearClient(cache, available); nearCacheBean.cacheName = cache.name; @@ -1045,7 +1048,9 @@ export default class IgniteJavaTransformer extends AbstractTransformer { const clientNearCaches = client ? _.filter(cluster.caches, (cache) => cache.cacheMode === 'PARTITIONED' && _.get(cache, 'clientNearConfiguration.enabled')) : []; - return this.igniteConfiguration(cfg, pkg, clsName, clientNearCaches); + const available = versionService.since.bind(versionService, targetVer.ignite); + + return this.igniteConfiguration(cfg, available, pkg, clsName, clientNearCaches); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/f53d8574/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js b/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js index f0bfdb6..9e35e5d 100644 --- a/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js +++ b/modules/web-console/frontend/app/modules/configuration/generator/SpringTransformer.service.js @@ -19,6 +19,9 @@ import _ from 'lodash'; import AbstractTransformer from './AbstractTransformer'; import StringBuilder from './StringBuilder'; +import VersionService from 'app/services/Version.service'; + +const versionService = new VersionService(); export default class IgniteSpringTransformer extends AbstractTransformer { static escapeXml(str) { @@ -252,10 +255,11 @@ export default class IgniteSpringTransformer extends AbstractTransformer { * Build final XML. * * @param {Bean} cfg Ignite configuration. + * @param available Function to check target version of generated source to appropriate for generation. * @param {Boolean} clientNearCaches * @returns {StringBuilder} */ - static igniteConfiguration(cfg, clientNearCaches) { + static igniteConfiguration(cfg, available, clientNearCaches) { const sb = new StringBuilder(); // 0. Add header. @@ -302,7 +306,7 @@ export default class IgniteSpringTransformer extends AbstractTransformer { _.forEach(clientNearCaches, (cache) => { this.commentBlock(sb, `Configuration of near cache for cache "${cache.name}"`); - this.appendBean(sb, this.generator.cacheNearClient(cache), true); + this.appendBean(sb, this.generator.cacheNearClient(cache, available), true); sb.emptyLine(); }); @@ -322,6 +326,8 @@ export default class IgniteSpringTransformer extends AbstractTransformer { const clientNearCaches = client ? _.filter(cluster.caches, (cache) => cache.cacheMode === 'PARTITIONED' && _.get(cache, 'clientNearConfiguration.enabled')) : []; - return this.igniteConfiguration(cfg, clientNearCaches); + const available = versionService.since.bind(versionService, targetVer.ignite); + + return this.igniteConfiguration(cfg, available, clientNearCaches); } }
