You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2019/03/13 18:07:18 UTC
[ignite] branch master updated: IGNITE-11384 Added ability for
services hot redeployment via DeploymentSpi - Fixes #6060.
This is an automated email from the ASF dual-hosted git repository.
agoncharuk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 1f1807b IGNITE-11384 Added ability for services hot redeployment via DeploymentSpi - Fixes #6060.
1f1807b is described below
commit 1f1807b776d5691b3d61f6bf5ee2d022c0430830
Author: Vyacheslav Daradur <da...@gmail.com>
AuthorDate: Wed Mar 13 20:36:46 2019 +0300
IGNITE-11384 Added ability for services hot redeployment via DeploymentSpi - Fixes #6060.
Signed-off-by: Alexey Goncharuk <al...@gmail.com>
---
.../processors/service/IgniteServiceProcessor.java | 8 +-
...ServiceHotRedeploymentViaDeploymentSpiTest.java | 161 +++++++++++++++++++++
.../testsuites/IgniteServiceGridTestSuite.java | 2 +
3 files changed, 170 insertions(+), 1 deletion(-)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/IgniteServiceProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/IgniteServiceProcessor.java
index d993803..1e4f22b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/IgniteServiceProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/IgniteServiceProcessor.java
@@ -52,6 +52,7 @@ import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.IgniteInterruptedCheckedException;
import org.apache.ignite.internal.SkipDaemon;
+import org.apache.ignite.internal.managers.deployment.GridDeployment;
import org.apache.ignite.internal.managers.discovery.CustomEventListener;
import org.apache.ignite.internal.managers.discovery.DiscoCache;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -1239,9 +1240,14 @@ public class IgniteServiceProcessor extends ServiceProcessorAdapter implements I
*/
private Service copyAndInject(ServiceConfiguration cfg) throws IgniteCheckedException {
if (cfg instanceof LazyServiceConfiguration) {
+ LazyServiceConfiguration srvcCfg = (LazyServiceConfiguration)cfg;
+
+ GridDeployment srvcDep = ctx.deploy().getDeployment(srvcCfg.serviceClassName());
+
byte[] bytes = ((LazyServiceConfiguration)cfg).serviceBytes();
- Service srvc = U.unmarshal(marsh, bytes, U.resolveClassLoader(null, ctx.config()));
+ Service srvc = U.unmarshal(marsh, bytes,
+ U.resolveClassLoader(srvcDep != null ? srvcDep.classLoader() : null, ctx.config()));
ctx.resource().inject(srvc);
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/service/ServiceHotRedeploymentViaDeploymentSpiTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/service/ServiceHotRedeploymentViaDeploymentSpiTest.java
new file mode 100644
index 0000000..c14f0bb
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/service/ServiceHotRedeploymentViaDeploymentSpiTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.service;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.services.Service;
+import org.apache.ignite.spi.deployment.DeploymentSpi;
+import org.apache.ignite.spi.deployment.local.LocalDeploymentSpi;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests services hot redeployment via {@link DeploymentSpi}.
+ *
+ * <b>NOTE:</b> to run test via Maven Surefire Plugin, the property "forkCount' should be set great than '0' or profile
+ * 'surefire-fork-count-1' enabled.
+ */
+public class ServiceHotRedeploymentViaDeploymentSpiTest extends GridCommonAbstractTest {
+ /** */
+ private static final String SERVICE_NAME = "test-service";
+
+ /** */
+ private Path srcTmpDir;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+ IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+ cfg.setDeploymentSpi(new LocalDeploymentSpi());
+
+ return cfg;
+ }
+
+ /** */
+ @BeforeClass
+ public static void check() {
+ Assume.assumeTrue(isEventDrivenServiceProcessorEnabled());
+ }
+
+ /** */
+ @Before
+ public void prepare() throws IOException {
+ srcTmpDir = Files.createTempDirectory(getClass().getSimpleName());
+ }
+
+ /** */
+ @After
+ public void cleanup() {
+ U.delete(srcTmpDir);
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ @Test
+ public void serviceHotRedeploymentTest() throws Exception {
+ URLClassLoader clsLdr = prepareClassLoader(1);
+ Class<?> cls = clsLdr.loadClass("MyRenewServiceImpl");
+
+ MyRenewService srvc = (MyRenewService)cls.newInstance();
+
+ assertEquals(1, srvc.version());
+
+ try {
+ Ignite ignite = startGrid(0);
+
+ final DeploymentSpi depSpi = ignite.configuration().getDeploymentSpi();
+
+ depSpi.register(clsLdr, srvc.getClass());
+
+ ignite.services().deployClusterSingleton(SERVICE_NAME, srvc);
+ MyRenewService proxy = ignite.services().serviceProxy(SERVICE_NAME, MyRenewService.class, false);
+ assertEquals(1, proxy.version());
+
+ ignite.services().cancel(SERVICE_NAME);
+ depSpi.unregister(srvc.getClass().getName());
+
+ clsLdr.close();
+
+ clsLdr = prepareClassLoader(2);
+ depSpi.register(clsLdr, srvc.getClass());
+
+ ignite.services().deployClusterSingleton(SERVICE_NAME, srvc);
+ proxy = ignite.services().serviceProxy(SERVICE_NAME, MyRenewService.class, false);
+ assertEquals(2, proxy.version());
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /** */
+ public interface MyRenewService extends Service {
+ /**
+ * @return Service's version.
+ */
+ public int version();
+ }
+
+ /**
+ * @param ver Version of generated class.
+ * @return Prepared classloader.
+ * @throws Exception In case of an error.
+ */
+ private URLClassLoader prepareClassLoader(int ver) throws Exception {
+ String source = "import org.apache.ignite.internal.processors.service.ServiceHotRedeploymentViaDeploymentSpiTest;\n" +
+ "import org.apache.ignite.services.ServiceContext;\n" +
+ "public class MyRenewServiceImpl implements ServiceHotRedeploymentViaDeploymentSpiTest.MyRenewService {\n" +
+ " @Override public int version() {\n" +
+ " return " + ver + ";\n" +
+ " }\n" +
+ " @Override public void cancel(ServiceContext ctx) {}\n" +
+ " @Override public void init(ServiceContext ctx) throws Exception {}\n" +
+ " @Override public void execute(ServiceContext ctx) throws Exception {}\n" +
+ "}";
+
+ Files.createDirectories(srcTmpDir); // To avoid possible NoSuchFileException on some OS.
+
+ File srcFile = new File(srcTmpDir.toFile(), "MyRenewServiceImpl.java");
+
+ Path srcFilePath = Files.write(srcFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
+
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+
+ compiler.run(null, null, null, srcFilePath.toString());
+
+ assertTrue("Failed to remove source file.", srcFile.delete());
+
+ return new URLClassLoader(new URL[] {srcTmpDir.toUri().toURL()});
+ }
+}
\ No newline at end of file
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteServiceGridTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteServiceGridTestSuite.java
index 675f0b3..02691ae 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteServiceGridTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteServiceGridTestSuite.java
@@ -53,6 +53,7 @@ import org.apache.ignite.internal.processors.service.ServiceDeploymentProcessing
import org.apache.ignite.internal.processors.service.ServiceDeploymentProcessingOnCoordinatorLeftTest;
import org.apache.ignite.internal.processors.service.ServiceDeploymentProcessingOnNodesFailTest;
import org.apache.ignite.internal.processors.service.ServiceDeploymentProcessingOnNodesLeftTest;
+import org.apache.ignite.internal.processors.service.ServiceHotRedeploymentViaDeploymentSpiTest;
import org.apache.ignite.internal.processors.service.ServiceInfoSelfTest;
import org.apache.ignite.internal.processors.service.ServicePredicateAccessCacheTest;
import org.apache.ignite.internal.processors.service.ServiceReassignmentFunctionSelfTest;
@@ -109,6 +110,7 @@ import org.junit.runners.Suite;
ServiceReassignmentFunctionSelfTest.class,
ServiceInfoSelfTest.class,
ServiceDeploymentProcessIdSelfTest.class,
+ ServiceHotRedeploymentViaDeploymentSpiTest.class,
})
public class IgniteServiceGridTestSuite {
}