You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vk...@apache.org on 2016/05/13 19:20:38 UTC
[06/50] [abbrv] ignite git commit: IGNITE-3020 .NET: Ensured that
Windows service is stopped correctly in case of forceful node stop. This
closes #679.
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-2949
Commit: b50eb654c72bf3f318a5e4d2a8871607c96c0cba
Parents: 80979df
Author: Pavel Tupitsyn <pt...@gridgain.com>
Authored: Wed May 11 18:21:32 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
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 @@
+\ufeff/*
+ * 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 @@
+\ufeff/*
+ * 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