Repository: ignite Updated Branches: refs/heads/ignite-1.6 80979dfcd -> b50eb654c
IGNITE-3020 .NET: Ensured that Windows service is stopped correctly in case of forceful node stop. This closes #679. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b50eb654 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b50eb654 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b50eb654 Branch: refs/heads/ignite-1.6 Commit: b50eb654c72bf3f318a5e4d2a8871607c96c0cba Parents: 80979df Author: Pavel Tupitsyn <[email protected]> Authored: Wed May 11 18:21:32 2016 +0300 Committer: vozerov-gridgain <[email protected]> Committed: Wed May 11 18:21:32 2016 +0300 ---------------------------------------------------------------------- .gitignore | 42 ++- .../internal/binary/BinaryClassDescriptor.java | 43 ++- .../ignite/internal/binary/BinaryContext.java | 90 +++--- .../internal/binary/BinaryReaderExImpl.java | 15 +- .../binary/GridBinaryWildcardsSelfTest.java | 53 ++-- ...acheBinaryObjectUserClassloaderSelfTest.java | 274 +++++++++++++++++++ .../marshaller/MarshallerContextTestImpl.java | 7 + .../testframework/junits/GridAbstractTest.java | 3 +- .../IgniteBinaryObjectsTestSuite.java | 3 + .../Apache.Ignite.Core.Tests.csproj | 2 + .../WindowsServiceTest.cs | 124 +++++++++ .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs | 6 + .../Impl/Unmanaged/UnmanagedCallbacks.cs | 6 + .../dotnet/Apache.Ignite/Apache.Ignite.csproj | 5 +- .../dotnet/Apache.Ignite/Config/Configurator.cs | 5 + .../Apache.Ignite/Service/IgniteService.cs | 102 +++---- .../Service/IgniteServiceInstaller.cs | 64 +++++ .../Apache.Ignite/Service/NativeMethods.cs | 57 ---- 18 files changed, 699 insertions(+), 202 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/.gitignore ---------------------------------------------------------------------- diff --git a/.gitignore b/.gitignore index f36b1d6..665770d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,6 @@ xcuserdata/ .DS_Store /bamboo/TEST*.xml /bamboo/junit*.properties -*.suo -*.csproj.user *.o *.lo *.obj @@ -21,16 +19,42 @@ target pom-installed.xml git-patch-prop-local.sh /slurp.sh -*.vcxproj.user -*.sdf -*.opensdf -*.opendb **/cpp/**/vs/x64/ **/cpp/**/vs/Win32/ -**/dotnet/**/obj/ -**/dotnet/**/bin/ /modules/platforms/cpp/doc/ .settings .classpath .project -/modules/platforms/**/*.VC.db \ No newline at end of file +/modules/platforms/**/*.VC.db +**/dotnet/libs/ + +#Visual Studio files +*.[Oo]bj +*.user +*.aps +*.pch +*.vspscc +*.vssscc +*_i.c +*_p.c +*.ncb +*.suo +*.tlb +*.tlh +*.bak +*.[Cc]ache +*.ilk +*.log +*.lib +*.sbr +*.sdf +*.opensdf +*.db +*.opendb +ipch/ +[Oo]bj/ +[Bb]in +[Dd]ebug*/ +[Rr]elease*/ +packages +*.classname http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java index d32b99a..d2d715b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java @@ -62,6 +62,9 @@ public class BinaryClassDescriptor { /** Configured serializer. */ private final BinarySerializer serializer; + /** Serializer that is passed during BinaryClassDescriptor construction. Can differ from {@link #serializer}. */ + private final BinarySerializer initialSerializer; + /** ID mapper. */ private final BinaryInternalMapper mapper; @@ -142,6 +145,8 @@ public class BinaryClassDescriptor { assert cls != null; assert mapper != null; + initialSerializer = serializer; + // If serializer is not defined at this point, then we have to user OptimizedMarshaller. useOptMarshaller = serializer == null; @@ -383,9 +388,45 @@ public class BinaryClassDescriptor { } /** + * @return Type name. + */ + String typeName() { + return typeName; + } + + /** + * @return Type mapper. + */ + BinaryInternalMapper mapper() { + return mapper; + } + + /** + * @return Serializer. + */ + BinarySerializer serializer() { + return serializer; + } + + /** + * @return Initial serializer that is passed during BinaryClassDescriptor construction. + * Can differ from {@link #serializer}. + */ + BinarySerializer initialSerializer() { + return initialSerializer; + } + + /** + * @return Affinity field key name. + */ + String affFieldKeyName() { + return affKeyFieldName; + } + + /** * @return User type flag. */ - public boolean userType() { + boolean userType() { return userType; } http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java index 8754795..daf34ad 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java @@ -17,7 +17,6 @@ package org.apache.ignite.internal.binary; -import java.io.Externalizable; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; @@ -99,8 +98,8 @@ import org.jsr166.ConcurrentHashMap8; * Binary context. */ public class BinaryContext { - /** */ - private static final ClassLoader dfltLdr = U.gridClassLoader(); + /** System loader.*/ + private static final ClassLoader sysLdr = U.gridClassLoader(); /** */ private static final BinaryInternalMapper DFLT_MAPPER = @@ -154,9 +153,6 @@ public class BinaryContext { /** */ private final ConcurrentMap<Class<?>, BinaryClassDescriptor> descByCls = new ConcurrentHashMap8<>(); - /** Holds classes loaded by default class loader only. */ - private final ConcurrentMap<Integer, BinaryClassDescriptor> userTypes = new ConcurrentHashMap8<>(); - /** */ private final Map<Integer, BinaryClassDescriptor> predefinedTypes = new HashMap<>(); @@ -203,13 +199,6 @@ public class BinaryContext { private volatile Map<Integer, BinarySchemaRegistry> schemas; /** - * For {@link Externalizable}. - */ - public BinaryContext() { - // No-op. - } - - /** * @param metaHnd Meta data handler. * @param igniteCfg Ignite configuration. * @param log Logger. @@ -570,8 +559,13 @@ public class BinaryContext { BinaryClassDescriptor desc = descByCls.get(cls); - if (desc == null || !desc.registered()) + if (desc == null) desc = registerClassDescriptor(cls, deserialize); + else if (!desc.registered()) { + assert desc.userType(); + + desc = registerUserClassDescriptor(desc); + } return desc; } @@ -597,16 +591,7 @@ public class BinaryContext { return desc; if (ldr == null) - ldr = dfltLdr; - - // If the type hasn't been loaded by default class loader then we mustn't return the descriptor from here - // giving a chance to a custom class loader to reload type's class. - if (userType && ldr.equals(dfltLdr)) { - desc = userTypes.get(typeId); - - if (desc != null) - return desc; - } + ldr = sysLdr; Class cls; @@ -617,14 +602,14 @@ public class BinaryContext { } catch (ClassNotFoundException e) { // Class might have been loaded by default class loader. - if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null) + if (userType && !ldr.equals(sysLdr) && (desc = descriptorForTypeId(true, typeId, sysLdr, deserialize)) != null) return desc; throw new BinaryInvalidTypeException(e); } catch (IgniteCheckedException e) { // Class might have been loaded by default class loader. - if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr, deserialize)) != null) + if (userType && !ldr.equals(sysLdr) && (desc = descriptorForTypeId(true, typeId, sysLdr, deserialize)) != null) return desc; throw new BinaryObjectException("Failed resolve class for ID: " + typeId, e); @@ -727,11 +712,6 @@ public class BinaryContext { new BinaryMetadata(typeId, typeName, desc.fieldsMeta(), affFieldName, schemas, desc.isEnum()).wrap(this)); } - // perform put() instead of putIfAbsent() because "registered" flag might have been changed or class loader - // might have reloaded described class. - if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr)) - userTypes.put(typeId, desc); - descByCls.put(cls, desc); typeId2Mapper.putIfAbsent(typeId, mapper); @@ -740,6 +720,47 @@ public class BinaryContext { } /** + * Creates and registers {@link BinaryClassDescriptor} for the given user {@code class}. + * + * @param desc Old descriptor that should be re-registered. + * @return Class descriptor. + */ + private BinaryClassDescriptor registerUserClassDescriptor(BinaryClassDescriptor desc) { + boolean registered; + + try { + registered = marshCtx.registerClass(desc.typeId(), desc.describedClass()); + } + catch (IgniteCheckedException e) { + throw new BinaryObjectException("Failed to register class.", e); + } + + if (registered) { + BinarySerializer serializer = desc.initialSerializer(); + + if (serializer == null) + serializer = serializerForClass(desc.describedClass()); + + desc = new BinaryClassDescriptor( + this, + desc.describedClass(), + true, + desc.typeId(), + desc.typeName(), + desc.affFieldKeyName(), + desc.mapper(), + serializer, + true, + true + ); + + descByCls.put(desc.describedClass(), desc); + } + + return desc; + } + + /** * Get serializer for class taking in count default one. * * @param cls Class. @@ -996,7 +1017,7 @@ public class BinaryContext { Class<?> cls = null; try { - cls = Class.forName(clsName); + cls = U.resolveClassLoader(configuration()).loadClass(clsName); } catch (ClassNotFoundException | NoClassDefFoundError ignored) { // No-op. @@ -1042,15 +1063,12 @@ public class BinaryContext { mapper, serializer, true, - true /* registered */ + false ); fieldsMeta = desc.fieldsMeta(); schemas = desc.schema() != null ? Collections.singleton(desc.schema()) : null; - if (IgniteUtils.detectClassLoader(cls).equals(dfltLdr)) - userTypes.put(id, desc); - descByCls.put(cls, desc); } http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java index 69aecbf..194b1be 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java @@ -114,6 +114,9 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina /** Footer end. */ private final int footerLen; + /** Class descriptor. */ + private BinaryClassDescriptor desc; + /** Mapper. */ private final BinaryInternalMapper mapper; @@ -254,7 +257,9 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina if (forUnmarshal) { // Registers class by type ID, at least locally if the cache is not ready yet. - typeId = ctx.descriptorForClass(BinaryUtils.doReadClass(in, ctx, ldr, typeId0), false).typeId(); + desc = ctx.descriptorForClass(BinaryUtils.doReadClass(in, ctx, ldr, typeId0), false); + + typeId = desc.typeId(); } else typeId = ctx.typeId(BinaryUtils.doReadClassName(in)); @@ -300,7 +305,10 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina * @return Descriptor. */ BinaryClassDescriptor descriptor() { - return ctx.descriptorForTypeId(userType, typeId, ldr, true); + if (desc == null) + desc = ctx.descriptorForTypeId(userType, typeId, ldr, true); + + return desc; } /** @@ -1462,7 +1470,8 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina break; case OBJ: - BinaryClassDescriptor desc = ctx.descriptorForTypeId(userType, typeId, ldr, true); + if (desc == null) + desc = ctx.descriptorForTypeId(userType, typeId, ldr, true); streamPosition(dataStart); http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java index d0d63b3..f69cea4 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/GridBinaryWildcardsSelfTest.java @@ -20,6 +20,7 @@ package org.apache.ignite.internal.binary; import java.util.Arrays; import java.util.Collection; import java.util.Map; +import java.util.concurrent.ConcurrentMap; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.binary.BinaryBasicIdMapper; import org.apache.ignite.binary.BinaryIdMapper; @@ -84,13 +85,13 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<Integer, Class> typeIds = U.field(ctx, "userTypes"); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); - assertEquals(3, typeIds.size()); + assertEquals(3, types.size()); - assertTrue(typeIds.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, mapper))); - assertTrue(typeIds.containsKey(typeId(CLASS2_FULL_NAME, nameMapper, mapper))); - assertTrue(typeIds.containsKey(typeId(INNER_CLASS_FULL_NAME, nameMapper, mapper))); + assertTrue(types.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, mapper))); + assertTrue(types.containsKey(typeId(CLASS2_FULL_NAME, nameMapper, mapper))); + assertTrue(types.containsKey(typeId(INNER_CLASS_FULL_NAME, nameMapper, mapper))); } /** @@ -157,13 +158,13 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<Integer, Class> typeIds = U.field(ctx, "userTypes"); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); - assertEquals(3, typeIds.size()); + assertEquals(3, types.size()); - assertTrue(typeIds.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, idMapper))); - assertTrue(typeIds.containsKey(typeId(CLASS2_FULL_NAME, nameMapper, idMapper))); - assertTrue(typeIds.containsKey(typeId(INNER_CLASS_FULL_NAME, nameMapper, idMapper))); + assertTrue(types.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, idMapper))); + assertTrue(types.containsKey(typeId(CLASS2_FULL_NAME, nameMapper, idMapper))); + assertTrue(types.containsKey(typeId(INNER_CLASS_FULL_NAME, nameMapper, idMapper))); } /** @@ -346,13 +347,13 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<Integer, Class> typeIds = U.field(ctx, "userTypes"); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); - assertEquals(3, typeIds.size()); + assertEquals(3, types.size()); - assertTrue(typeIds.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, mapper))); - assertTrue(typeIds.containsKey(typeId(INNER_CLASS_FULL_NAME, nameMapper, mapper))); - assertTrue(typeIds.containsKey("type2".hashCode())); + assertTrue(types.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, mapper))); + assertTrue(types.containsKey(typeId(INNER_CLASS_FULL_NAME, nameMapper, mapper))); + assertTrue(types.containsKey("type2".hashCode())); Map<String, org.apache.ignite.internal.binary.BinaryInternalMapper> typeMappers = U.field(ctx, "cls2Mappers"); @@ -387,12 +388,12 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<Integer, Class> typeIds = U.field(ctx, "userTypes"); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); - assertEquals(3, typeIds.size()); + assertEquals(3, types.size()); - assertTrue(typeIds.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, idMapper))); - assertTrue(typeIds.containsKey(typeId(CLASS2_FULL_NAME, nameMapper, idMapper))); + assertTrue(types.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, idMapper))); + assertTrue(types.containsKey(typeId(CLASS2_FULL_NAME, nameMapper, idMapper))); } /** @@ -460,12 +461,12 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<Integer, Class> typeIds = U.field(ctx, "userTypes"); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); - assertEquals(3, typeIds.size()); + assertEquals(3, types.size()); - assertTrue(typeIds.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, idMapper))); - assertTrue(typeIds.containsKey(typeId(CLASS2_FULL_NAME, nameMapper, idMapper))); + assertTrue(types.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, idMapper))); + assertTrue(types.containsKey(typeId(CLASS2_FULL_NAME, nameMapper, idMapper))); } /** @@ -580,11 +581,11 @@ public class GridBinaryWildcardsSelfTest extends GridCommonAbstractTest { BinaryContext ctx = binaryContext(marsh); - Map<Integer, Class> typeIds = U.field(ctx, "userTypes"); + ConcurrentMap<Integer, BinaryInternalMapper> types = U.field(ctx, "typeId2Mapper"); - assertEquals(3, typeIds.size()); + assertEquals(3, types.size()); - assertTrue(typeIds.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, idMapper))); + assertTrue(types.containsKey(typeId(CLASS1_FULL_NAME, nameMapper, idMapper))); Map<String, org.apache.ignite.internal.binary.BinaryInternalMapper> typeMappers = U.field(ctx, "cls2Mappers"); http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java new file mode 100644 index 0000000..4355796 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/binary/GridCacheBinaryObjectUserClassloaderSelfTest.java @@ -0,0 +1,274 @@ +/* + * 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. + */ + +package org.apache.ignite.internal.processors.cache.binary; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.binary.BinaryObjectException; +import org.apache.ignite.binary.BinaryReader; +import org.apache.ignite.binary.BinarySerializer; +import org.apache.ignite.binary.BinaryTypeConfiguration; +import org.apache.ignite.binary.BinaryWriter; +import org.apache.ignite.configuration.BinaryConfiguration; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.binary.BinaryMarshaller; +import org.apache.ignite.internal.util.typedef.internal.S; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +import static org.apache.ignite.cache.CacheMode.REPLICATED; +import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC; + +/** + * + */ +public class GridCacheBinaryObjectUserClassloaderSelfTest extends GridCommonAbstractTest { + /** */ + private static volatile boolean customBinaryConf = false; + + /** */ + private static volatile boolean deserialized = false; + + /** */ + private static volatile boolean useWrappingLoader = false; + + /** */ + private TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); + + /** {@inheritDoc} */ + @Override protected void afterTest() throws Exception { + super.afterTest(); + + stopAllGrids(); + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + TcpDiscoverySpi disco = new TcpDiscoverySpi(); + + disco.setIpFinder(ipFinder); + + cfg.setDiscoverySpi(disco); + + cfg.setCacheConfiguration(cacheConfiguration(gridName)); + + cfg.setMarshaller(new BinaryMarshaller()); + + cfg.setClassLoader(useWrappingLoader ? new WrappingClassLoader(getExternalClassLoader()) : + getExternalClassLoader()); + + if (customBinaryConf) { + BinarySerializer bs = new BinarySerializer() { + /** {@inheritDoc} */ + @Override public void writeBinary(Object obj, BinaryWriter writer) throws BinaryObjectException { + //No-op. + } + + /** {@inheritDoc} */ + @Override public void readBinary(Object obj, BinaryReader reader) throws BinaryObjectException { + deserialized = true; + } + }; + + BinaryTypeConfiguration btcfg1 = new BinaryTypeConfiguration(); + + btcfg1.setTypeName("org.apache.ignite.tests.p2p.CacheDeploymentTestValue"); + + btcfg1.setSerializer(bs); + + BinaryTypeConfiguration btcfg2 = new BinaryTypeConfiguration(); + + btcfg2.setTypeName("org.apache.ignite.internal.processors.cache.binary." + + "GridCacheBinaryObjectUserClassloaderSelfTest$TestValue1"); + + btcfg2.setSerializer(bs); + + BinaryConfiguration bcfg = new BinaryConfiguration(); + + Set<BinaryTypeConfiguration> set = new HashSet<>(); + + set.add(btcfg1); + set.add(btcfg2); + + bcfg.setTypeConfigurations(set); + + cfg.setBinaryConfiguration(bcfg); + } + + return cfg; + } + + /** + * Gets cache configuration for grid with specified name. + * + * @param gridName Grid name. + * @return Cache configuration. + */ + CacheConfiguration cacheConfiguration(String gridName) { + CacheConfiguration cacheCfg = defaultCacheConfiguration(); + + cacheCfg.setCacheMode(REPLICATED); + cacheCfg.setWriteSynchronizationMode(FULL_SYNC); + + return cacheCfg; + } + + + /** + * @throws Exception If test failed. + */ + public void testConfigurationRegistration() throws Exception { + useWrappingLoader = false; + + doTestConfigurationRegistration(); + } + + /** + * @throws Exception If test failed. + */ + public void testConfigurationRegistrationWithWrappingLoader() throws Exception { + useWrappingLoader = true; + + doTestConfigurationRegistration(); + } + + /** + * @throws Exception If test failed. + */ + private void doTestConfigurationRegistration() throws Exception { + try { + customBinaryConf = true; + + Ignite i1 = startGrid(1); + Ignite i2 = startGrid(2); + + IgniteCache<Integer, Object> cache1 = i1.cache(null); + IgniteCache<Integer, Object> cache2 = i2.cache(null); + + ClassLoader ldr = useWrappingLoader ? + ((WrappingClassLoader)i1.configuration().getClassLoader()).getParent() : + i1.configuration().getClassLoader(); + + Object v1 = ldr.loadClass("org.apache.ignite.tests.p2p.CacheDeploymentTestValue").newInstance(); + Object v2 = ldr.loadClass("org.apache.ignite.tests.p2p.CacheDeploymentTestValue2").newInstance(); + + cache1.put(1, v1); + cache1.put(2, v2); + cache1.put(3, new TestValue1(123)); + cache1.put(4, new TestValue2(123)); + + deserialized = false; + + cache2.get(1); + + assertTrue(deserialized); + + deserialized = false; + + cache2.get(2); + + assertFalse(deserialized); + + deserialized = false; + + cache2.get(3); + + assertTrue(deserialized); + + deserialized = false; + + cache2.get(4); + + assertFalse(deserialized); + } + finally { + customBinaryConf = false; + } + } + + /** + * + */ + private static class TestValue1 implements Serializable { + /** */ + private int val; + + /** + * @param val Value. + */ + public TestValue1(int val) { + this.val = val; + } + + /** + * @return Value. + */ + public int value() { + return val; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(TestValue1.class, this); + } + } + + /** + * + */ + private static class TestValue2 implements Serializable { + /** */ + private int val; + + /** + * @param val Value. + */ + public TestValue2(int val) { + this.val = val; + } + + /** + * @return Value. + */ + public int value() { + return val; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(TestValue2.class, this); + } + } + + /** + * + */ + private static class WrappingClassLoader extends ClassLoader { + public WrappingClassLoader(ClassLoader parent) { + super(parent); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java index e4921f4..c600ca4 100644 --- a/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java +++ b/modules/core/src/test/java/org/apache/ignite/marshaller/MarshallerContextTestImpl.java @@ -62,4 +62,11 @@ public class MarshallerContextTestImpl extends MarshallerContextAdapter { @Override protected String className(int id) { return map.get(id); } + + /** + * @return Internal map. + */ + public ConcurrentMap<Integer, String> internalMap() { + return map; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java index 170e9cf..3910ce4 100644 --- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java @@ -484,7 +484,8 @@ public abstract class GridAbstractTest extends TestCase { * @throws Exception If failed. {@link #afterTestsStopped()} will be called in this case. */ protected void beforeTestsStarted() throws Exception { - // No-op. + // Will clean and re-create marshaller directory from scratch. + U.resolveWorkDirectory("marshaller", true); } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java index 73c22e4..cedf9a7 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java @@ -47,6 +47,7 @@ import org.apache.ignite.internal.binary.noncompact.BinaryObjectBuilderNonCompac import org.apache.ignite.internal.binary.streams.BinaryHeapStreamByteOrderSelfTest; import org.apache.ignite.internal.binary.streams.BinaryOffheapStreamByteOrderSelfTest; import org.apache.ignite.internal.processors.cache.BinaryObjectOffHeapUnswapTemporaryTest; +import org.apache.ignite.internal.processors.cache.binary.GridCacheBinaryObjectUserClassloaderSelfTest; import org.apache.ignite.internal.processors.cache.binary.GridCacheBinaryStoreBinariesDefaultMappersSelfTest; import org.apache.ignite.internal.processors.cache.binary.GridCacheBinaryStoreBinariesSimpleNameMappersSelfTest; import org.apache.ignite.internal.processors.cache.binary.GridCacheBinaryStoreObjectsSelfTest; @@ -140,6 +141,8 @@ public class IgniteBinaryObjectsTestSuite extends TestSuite { suite.addTestSuite(BinaryHeapStreamByteOrderSelfTest.class); suite.addTestSuite(BinaryOffheapStreamByteOrderSelfTest.class); + suite.addTestSuite(GridCacheBinaryObjectUserClassloaderSelfTest.class); + return suite; } } http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/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 002fa26..ef774af 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 @@ -49,6 +49,7 @@ <Reference Include="System.configuration" /> <Reference Include="System.Core" /> <Reference Include="System.Runtime.Serialization" /> + <Reference Include="System.ServiceProcess" /> <Reference Include="System.XML" /> </ItemGroup> <ItemGroup> @@ -156,6 +157,7 @@ <Compile Include="Services\ServicesAsyncWrapper.cs" /> <Compile Include="TestRunner.cs" /> <Compile Include="TypeResolverTest.cs" /> + <Compile Include="WindowsServiceTest.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\Apache.Ignite.Core\Apache.Ignite.Core.csproj"> http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/platforms/dotnet/Apache.Ignite.Core.Tests/WindowsServiceTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/WindowsServiceTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/WindowsServiceTest.cs new file mode 100644 index 0000000..08d365a --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/WindowsServiceTest.cs @@ -0,0 +1,124 @@ +/* + * 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.IO; + using System.Linq; + using System.ServiceProcess; + using Apache.Ignite.Core.Cluster; + using Apache.Ignite.Core.Tests.Process; + using NUnit.Framework; + + /// <summary> + /// Tests windows service deployment and lifecycle. + /// <para /> + /// NOTE: This fixture requires administrative privileges. + /// </summary> + public class WindowsServiceTest + { + /// <summary> + /// Test fixture set up. + /// </summary> + [TestFixtureSetUp] + public void TestFixtureSetUp() + { + StopServiceAndUninstall(); + } + + /// <summary> + /// Test fixture tear down. + /// </summary> + [TestFixtureTearDown] + public void TestFixtureTearDown() + { + StopServiceAndUninstall(); + } + + /// <summary> + /// Tests that service stops when Ignition stops. + /// </summary> + [Test] + public void TestStopFromJava() + { + var exePath = typeof(IgniteRunner).Assembly.Location; + var springPath = Path.GetFullPath(@"config\compute\compute-grid1.xml"); + + IgniteProcess.Start(exePath, string.Empty, args: new[] + { + "/install", + "ForceTestClasspath=true", + "-springConfigUrl=" + springPath, + "-J-Xms513m", + "-J-Xmx555m" + }).WaitForExit(); + + var service = GetIgniteService(); + Assert.IsNotNull(service); + + service.Start(); // see IGNITE_HOME\work\log for service instance logs + service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(30)); + + using (var ignite = Ignition.Start(new IgniteConfiguration(TestUtils.GetTestConfiguration()) + { + SpringConfigUrl = springPath + })) + { + Assert.IsTrue(ignite.WaitTopology(2), "Failed to join with service node"); + + // Stop remote node via Java task + // Doing so will fail the task execution + Assert.Throws<ClusterGroupEmptyException>(() => + ignite.GetCluster().ForRemotes().GetCompute().ExecuteJavaTask<object>( + "org.apache.ignite.platform.PlatformStopIgniteTask", ignite.Name)); + + Assert.IsTrue(ignite.WaitTopology(1), "Failed to stop remote node"); + + // Check that service has stopped + service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30)); + } + } + + /// <summary> + /// Stops the service and uninstalls it. + /// </summary> + private static void StopServiceAndUninstall() + { + var controller = GetIgniteService(); + + if (controller != null) + { + if (controller.CanStop) + controller.Stop(); + + controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30)); + + var exePath = typeof(IgniteRunner).Assembly.Location; + IgniteProcess.Start(exePath, string.Empty, args: new[] {"/uninstall"}).WaitForExit(); + } + } + + /// <summary> + /// Gets the ignite service. + /// </summary> + private static ServiceController GetIgniteService() + { + return ServiceController.GetServices().FirstOrDefault(x => x.ServiceName.StartsWith("Apache Ignite.NET")); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs index aee82a7..d64f52c 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs @@ -348,7 +348,13 @@ namespace Apache.Ignite.Core.Impl UU.IgnitionStop(_proc.Context, Name, cancel); _cbs.Cleanup(); + } + /// <summary> + /// Called after node has stopped. + /// </summary> + internal void AfterNodeStop() + { foreach (var bean in _lifecycleBeans) bean.OnLifecycleEvent(LifecycleEventType.AfterNodeStop); } http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs index 8d810e3..f0e881c 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedCallbacks.cs @@ -1033,6 +1033,12 @@ namespace Apache.Ignite.Core.Impl.Unmanaged // Allow context to be collected, which will cause resource cleanup in finalizer. _ctx = null; + + // Notify grid + var ignite = _ignite; + + if (ignite != null) + ignite.AfterNodeStop(); } private void Error(void* target, int errType, sbyte* errClsChars, int errClsCharsLen, sbyte* errMsgChars, http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj b/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj index 08c14f2..747e1a5 100644 --- a/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj +++ b/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj @@ -33,6 +33,7 @@ <ItemGroup> <Reference Include="System" /> <Reference Include="System.Configuration" /> + <Reference Include="System.Configuration.Install" /> <Reference Include="System.Core" /> <Reference Include="System.ServiceProcess" /> <Reference Include="System.Xml.Linq" /> @@ -51,8 +52,10 @@ <Compile Include="Service\IgniteService.cs"> <SubType>Component</SubType> </Compile> - <Compile Include="Service\NativeMethods.cs" /> <Compile Include="Service\ServiceDescription.cs" /> + <Compile Include="Service\IgniteServiceInstaller.cs"> + <SubType>Component</SubType> + </Compile> </ItemGroup> <ItemGroup> <ProjectReference Include="..\Apache.Ignite.Core\Apache.Ignite.Core.csproj"> http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/platforms/dotnet/Apache.Ignite/Config/Configurator.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite/Config/Configurator.cs b/modules/platforms/dotnet/Apache.Ignite/Config/Configurator.cs index af009e8..c595de1 100644 --- a/modules/platforms/dotnet/Apache.Ignite/Config/Configurator.cs +++ b/modules/platforms/dotnet/Apache.Ignite/Config/Configurator.cs @@ -62,6 +62,9 @@ namespace Apache.Ignite.Config /** Command line argument: Config file name to read config section from. */ private const string CmdConfigFile = "ConfigFileName"; + /** Hidden command line argument: Force test classpath. */ + private const string CmdForceTestClasspath = "ForceTestClasspath"; + /** <inheritDoc /> */ public static IgniteConfiguration GetConfiguration(Tuple<string, string>[] args) { @@ -94,6 +97,8 @@ namespace Apache.Ignite.Config jvmOpts.Add(arg.Item2); else if (argIs(CmdAssembly)) assemblies.Add(arg.Item2); + else if (argIs(CmdForceTestClasspath) && arg.Item2 == "true") + Environment.SetEnvironmentVariable("IGNITE_NATIVE_TEST_CLASSPATH", "true"); } if (jvmOpts.Count > 0) http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/platforms/dotnet/Apache.Ignite/Service/IgniteService.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite/Service/IgniteService.cs b/modules/platforms/dotnet/Apache.Ignite/Service/IgniteService.cs index c64c7bf..4517f71 100644 --- a/modules/platforms/dotnet/Apache.Ignite/Service/IgniteService.cs +++ b/modules/platforms/dotnet/Apache.Ignite/Service/IgniteService.cs @@ -18,41 +18,42 @@ namespace Apache.Ignite.Service { using System; - using System.ComponentModel; + using System.Collections.Generic; + using System.Configuration.Install; using System.IO; using System.Linq; using System.Reflection; - using System.Runtime.InteropServices; using System.ServiceProcess; using System.Text; using Apache.Ignite.Core; using Apache.Ignite.Core.Common; + using Apache.Ignite.Core.Lifecycle; /// <summary> /// Ignite windows service. /// </summary> - internal class IgniteService : ServiceBase + internal class IgniteService : ServiceBase, ILifecycleBean { /** Service name. */ - private static readonly string SvcName = "Apache Ignite.NET"; + public const string SvcName = "Apache Ignite.NET"; /** Service display name. */ - private static readonly string SvcDisplayName = "Apache Ignite.NET " + + public static readonly string SvcDisplayName = SvcName + " " + Assembly.GetExecutingAssembly().GetName().Version.ToString(4); /** Service description. */ - private static readonly string SvcDesc = "Apache Ignite.NET Service."; + public const string SvcDesc = "Apache Ignite.NET Service."; /** Current executable name. */ private static readonly string ExeName = new FileInfo(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath).FullName; - /** Current executable fully qualified name. */ - private static readonly string FullExeName = Path.GetFileName(FullExeName); - /** Ignite configuration to start with. */ private readonly IgniteConfiguration _cfg; + /** Stopping recurse check flag. */ + private bool _isStopping; + /// <summary> /// Constructor. /// </summary> @@ -63,6 +64,13 @@ namespace Apache.Ignite.Service ServiceName = SvcName; _cfg = cfg; + + // Subscribe to lifecycle events + var beans = _cfg.LifecycleBeans ?? new List<ILifecycleBean>(); + + beans.Add(this); + + _cfg.LifecycleBeans = beans; } /** <inheritDoc /> */ @@ -74,7 +82,8 @@ namespace Apache.Ignite.Service /** <inheritDoc /> */ protected override void OnStop() { - Ignition.StopAll(true); + if (!_isStopping) + Ignition.StopAll(true); } /// <summary> @@ -140,47 +149,15 @@ namespace Apache.Ignite.Service private static void Install0(Tuple<string, string>[] args) { // 1. Prepare arguments. - var binPath = new StringBuilder(FullExeName).Append(" ").Append(IgniteRunner.Svc); + var argString = new StringBuilder(IgniteRunner.Svc); foreach (var arg in args) - binPath.Append(" ").AppendFormat("-{0}={1}", arg.Item1, arg.Item2); - - // 2. Get SC manager. - var scMgr = OpenServiceControlManager(); - - // 3. Create service. - var svc = NativeMethods.CreateService( - scMgr, - SvcName, - SvcDisplayName, - 983551, // Access constant. - 0x10, // Service type SERVICE_WIN32_OWN_PROCESS. - 0x2, // Start type SERVICE_AUTO_START. - 0x2, // Error control SERVICE_ERROR_SEVERE. - binPath.ToString(), - null, - IntPtr.Zero, - null, - null, // Use priviliged LocalSystem account. - null - ); - - if (svc == IntPtr.Zero) - throw new IgniteException("Failed to create the service.", new Win32Exception()); - - // 4. Set description. - var desc = new ServiceDescription {desc = Marshal.StringToHGlobalUni(SvcDesc)}; - - - try - { - if (!NativeMethods.ChangeServiceConfig2(svc, 1u, ref desc)) - throw new IgniteException("Failed to set service description.", new Win32Exception()); - } - finally - { - Marshal.FreeHGlobal(desc.desc); - } + argString.Append(" ").AppendFormat("-{0}={1}", arg.Item1, arg.Item2); + + IgniteServiceInstaller.Args = argString.ToString(); + + // 2. Install service. + ManagedInstallerClass.InstallHelper(new[] { ExeName }); } /// <summary> @@ -188,29 +165,18 @@ namespace Apache.Ignite.Service /// </summary> private static void Uninstall0() { - var scMgr = OpenServiceControlManager(); - - var svc = NativeMethods.OpenService(scMgr, SvcName, 65536); - - if (svc == IntPtr.Zero) - throw new IgniteException("Failed to uninstall the service.", new Win32Exception()); - - NativeMethods.DeleteService(svc); + ManagedInstallerClass.InstallHelper(new[] { ExeName, "/u" }); } - /// <summary> - /// Opens SC manager. - /// </summary> - /// <returns>SC manager pointer.</returns> - private static IntPtr OpenServiceControlManager() + /** <inheritdoc /> */ + public void OnLifecycleEvent(LifecycleEventType evt) { - var ptr = NativeMethods.OpenSCManager(null, null, 983103); - - if (ptr == IntPtr.Zero) - throw new IgniteException("Failed to initialize Service Control manager " + - "(did you run the command as administrator?)", new Win32Exception()); + if (evt == LifecycleEventType.AfterNodeStop) + { + _isStopping = true; - return ptr; + Stop(); + } } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/platforms/dotnet/Apache.Ignite/Service/IgniteServiceInstaller.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite/Service/IgniteServiceInstaller.cs b/modules/platforms/dotnet/Apache.Ignite/Service/IgniteServiceInstaller.cs new file mode 100644 index 0000000..713e568 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite/Service/IgniteServiceInstaller.cs @@ -0,0 +1,64 @@ +/* + * 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.Service +{ + using System.Collections; + using System.ComponentModel; + using System.Configuration.Install; + using System.ServiceProcess; + + /// <summary> + /// Service installer for InstallUtil. + /// </summary> + [RunInstaller(true)] + public class IgniteServiceInstaller : Installer + { + /// <summary> + /// Gets or sets the service arguments. + /// </summary> + public static string Args { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="IgniteServiceInstaller"/> class. + /// </summary> + public IgniteServiceInstaller() + { + Installers.Add(new ServiceInstaller + { + StartType = ServiceStartMode.Automatic, + ServiceName = IgniteService.SvcName, + Description = IgniteService.SvcDesc, + DisplayName = IgniteService.SvcDisplayName + }); + + Installers.Add(new ServiceProcessInstaller {Account = ServiceAccount.LocalSystem}); + } + + /** <inheritdoc /> */ + protected override void OnBeforeInstall(IDictionary savedState) + { + if (!string.IsNullOrWhiteSpace(Args)) + { + Context.Parameters["assemblyPath"] = + string.Format("\"{0}\" {1}", Context.Parameters["assemblyPath"], Args); + } + + base.OnBeforeInstall(savedState); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/b50eb654/modules/platforms/dotnet/Apache.Ignite/Service/NativeMethods.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite/Service/NativeMethods.cs b/modules/platforms/dotnet/Apache.Ignite/Service/NativeMethods.cs deleted file mode 100644 index 56ab15d..0000000 --- a/modules/platforms/dotnet/Apache.Ignite/Service/NativeMethods.cs +++ /dev/null @@ -1,57 +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. - */ - -namespace Apache.Ignite.Service -{ - using System; - using System.Runtime.InteropServices; - - /// <summary> - /// Native methods. - /// </summary> - internal class NativeMethods - { - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern IntPtr OpenSCManager(string machineName, string dbName, int access); - - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern IntPtr CreateService( - IntPtr db, - string svcName, - string displayName, - int access, - int svcType, - int startType, - int errControl, - string binPath, - string loadOrderGrp, - IntPtr pTagId, - string dependencies, - string servicesStartName, - string pwd - ); - - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern IntPtr OpenService(IntPtr db, string svcName, int access); - - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern bool DeleteService(IntPtr svc); - - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern bool ChangeServiceConfig2(IntPtr svc, uint infoLevel, ref ServiceDescription desc); - } -} \ No newline at end of file
