IGNITE-6922 Class cannot undeploy from grid in some specific cases - Fixes #3045.
Signed-off-by: Alexey Goncharuk <alexey.goncha...@gmail.com> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d2050237 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d2050237 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d2050237 Branch: refs/heads/ignite-zk Commit: d2050237ee2b760d1c9cbc906b281790fd0976b4 Parents: 08371f5 Author: vd-pyatkov <vpyat...@gridgain.com> Authored: Wed Nov 22 10:39:58 2017 +0300 Committer: Alexey Goncharuk <alexey.goncha...@gmail.com> Committed: Wed Nov 22 10:39:58 2017 +0300 ---------------------------------------------------------------------- .../GridDeploymentPerVersionStore.java | 36 +++--- modules/core/src/test/config/tests.properties | 1 + .../apache/ignite/p2p/SharedDeploymentTest.java | 128 +++++++++++++++++++ .../testsuites/IgniteP2PSelfTestSuite.java | 2 + .../tests/p2p/compute/ExternalCallable.java | 10 +- .../tests/p2p/compute/ExternalCallable1.java | 11 +- .../tests/p2p/compute/ExternalCallable2.java | 11 +- .../tests/p2p/compute/ExternalCallable.java | 59 +++++++++ .../tests/p2p/compute/ExternalCallable1.java | 59 +++++++++ .../tests/p2p/compute/ExternalCallable2.java | 59 +++++++++ 10 files changed, 348 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java index 070b390..8447c97 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java @@ -376,31 +376,33 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter { // Find existing deployments that need to be checked // whether they should be reused for this request. - for (SharedDeployment d : deps) { - if (!d.pendingUndeploy() && !d.undeployed()) { - Map<UUID, IgniteUuid> parties = d.participants(); + if (ctx.config().getDeploymentMode() == CONTINUOUS) { + for (SharedDeployment d : deps) { + if (!d.pendingUndeploy() && !d.undeployed()) { + Map<UUID, IgniteUuid> parties = d.participants(); - if (parties != null) { - IgniteUuid ldrId = parties.get(meta.senderNodeId()); + if (parties != null) { + IgniteUuid ldrId = parties.get(meta.senderNodeId()); - if (ldrId != null) { - assert !ldrId.equals(meta.classLoaderId()); + if (ldrId != null) { + assert !ldrId.equals(meta.classLoaderId()); - if (log.isDebugEnabled()) - log.debug("Skipping deployment (loaders on remote node are different) " + - "[dep=" + d + ", meta=" + meta + ']'); + if (log.isDebugEnabled()) + log.debug("Skipping deployment (loaders on remote node are different) " + + "[dep=" + d + ", meta=" + meta + ']'); - continue; + continue; + } } - } - if (depsToCheck == null) - depsToCheck = new LinkedList<>(); + if (depsToCheck == null) + depsToCheck = new LinkedList<>(); - if (log.isDebugEnabled()) - log.debug("Adding deployment to check: " + d); + if (log.isDebugEnabled()) + log.debug("Adding deployment to check: " + d); - depsToCheck.add(d); + depsToCheck.add(d); + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/core/src/test/config/tests.properties ---------------------------------------------------------------------- diff --git a/modules/core/src/test/config/tests.properties b/modules/core/src/test/config/tests.properties index 1ea5b3d..718d661 100644 --- a/modules/core/src/test/config/tests.properties +++ b/modules/core/src/test/config/tests.properties @@ -88,6 +88,7 @@ grid.comm.selftest.timeout=10000 #P2P tests #Overwrite this property. It should point to P2P module compilation directory. p2p.uri.cls=file://localhost/@{IGNITE_HOME}/modules/extdata/p2p/target/classes/ +p2p.uri.cls.second=file://localhost/@{IGNITE_HOME}/modules/extdata/uri/target/classes/ # AOP tests. # Connector port for RMI. http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/core/src/test/java/org/apache/ignite/p2p/SharedDeploymentTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/p2p/SharedDeploymentTest.java b/modules/core/src/test/java/org/apache/ignite/p2p/SharedDeploymentTest.java new file mode 100644 index 0000000..cc0340e --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/p2p/SharedDeploymentTest.java @@ -0,0 +1,128 @@ +/* + * 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.p2p; + +import org.apache.ignite.Ignite; +import org.apache.ignite.configuration.DeploymentMode; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.lang.IgniteCallable; +import org.apache.ignite.testframework.GridTestExternalClassLoader; +import org.apache.ignite.testframework.config.GridTestProperties; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import java.lang.reflect.Constructor; +import java.net.URL; +import java.util.Collection; + +/** + */ +public class SharedDeploymentTest extends GridCommonAbstractTest { + /** */ + private static final String RUN_CLS = "org.apache.ignite.tests.p2p.compute.ExternalCallable"; + + /** */ + private static final String RUN_CLS1 = "org.apache.ignite.tests.p2p.compute.ExternalCallable1"; + + /** */ + private static final String RUN_CLS2 = "org.apache.ignite.tests.p2p.compute.ExternalCallable2"; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + return super.getConfiguration(igniteInstanceName) + .setPeerClassLoadingEnabled(true) + .setDeploymentMode(DeploymentMode.SHARED); + } + + /** + * @throws Exception if failed. + */ + public void testDeploymentFromSecondAndThird() throws Exception { + try { + startGrid(1); + + final Ignite ignite2 = startGrid(2); + Ignite ignite3 = startGrid(3); + + Collection<Object> res = runJob0(new GridTestExternalClassLoader(new URL[] { + new URL(GridTestProperties.getProperty("p2p.uri.cls"))}, RUN_CLS1/*, RUN_CLS2*/), ignite2, 10_000, 1); + + for (Object o: res) + assertEquals(o, 42); + + res = runJob1(new GridTestExternalClassLoader(new URL[] { + new URL(GridTestProperties.getProperty("p2p.uri.cls"))}, RUN_CLS, RUN_CLS2), ignite3, 10_000, 2); + + for (Object o: res) + assertEquals(o, 42); + + res = runJob2(new GridTestExternalClassLoader(new URL[] { + new URL(GridTestProperties.getProperty("p2p.uri.cls"))}, RUN_CLS, RUN_CLS1), ignite3, 10_000, 3); + + for (Object o: res) + assertEquals(o, 42); + + ignite3.close(); + + ignite3 = startGrid(3); + + res = runJob2(new GridTestExternalClassLoader(new URL[] { + new URL(GridTestProperties.getProperty("p2p.uri.cls.second"))}, RUN_CLS, RUN_CLS1), ignite3, 10_000, 4); + + for (Object o: res) + assertEquals(o, 43); + } + finally { + stopAllGrids(); + } + } + + /** + * @param ignite Ignite instance. + * @param timeout Timeout. + * @param param Parameter. + * @throws Exception If failed. + */ + private Collection<Object> runJob1(ClassLoader testClassLoader, Ignite ignite, long timeout, int param) throws Exception { + Constructor ctor = testClassLoader.loadClass(RUN_CLS1).getConstructor(int.class); + + return ignite.compute().withTimeout(timeout).broadcast((IgniteCallable<Object>)ctor.newInstance(param)); + } + + /** + * @param ignite Ignite instance. + * @param timeout Timeout. + * @param param Parameter. + * @throws Exception If failed. + */ + private Collection<Object> runJob0(ClassLoader testClassLoader, Ignite ignite, long timeout, int param) throws Exception { + Constructor ctor = testClassLoader.loadClass(RUN_CLS).getConstructor(int.class); + + return ignite.compute().withTimeout(timeout).broadcast((IgniteCallable<Object>)ctor.newInstance(param)); + } + + /** + * @param ignite Ignite instance. + * @param timeout Timeout. + * @param param Parameter. + * @throws Exception If failed. + */ + private Collection<Object> runJob2(ClassLoader testClassLoader, Ignite ignite, long timeout, int param) throws Exception { + Constructor ctor = testClassLoader.loadClass(RUN_CLS2).getConstructor(int.class); + + return ignite.compute().withTimeout(timeout).broadcast((IgniteCallable<Object>)ctor.newInstance(param)); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java index abd9967..3c50baf 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java @@ -35,6 +35,7 @@ import org.apache.ignite.p2p.GridP2PRemoteClassLoadersSelfTest; import org.apache.ignite.p2p.GridP2PSameClassLoaderSelfTest; import org.apache.ignite.p2p.GridP2PTimeoutSelfTest; import org.apache.ignite.p2p.GridP2PUndeploySelfTest; +import org.apache.ignite.p2p.SharedDeploymentTest; import org.apache.ignite.testframework.GridTestUtils; /** @@ -72,6 +73,7 @@ public class IgniteP2PSelfTestSuite extends TestSuite { suite.addTest(new TestSuite(GridP2PMissedResourceCacheSizeSelfTest.class)); suite.addTest(new TestSuite(GridP2PContinuousDeploymentSelfTest.class)); suite.addTest(new TestSuite(DeploymentClassLoaderCallableTest.class)); + suite.addTest(new TestSuite(SharedDeploymentTest.class)); GridTestUtils.addTestIfNeeded(suite, GridDeploymentMessageCountSelfTest.class, ignoredTests); return suite; http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java ---------------------------------------------------------------------- diff --git a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java index 25f1f3e..d24895c 100644 --- a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java +++ b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java @@ -18,8 +18,10 @@ package org.apache.ignite.tests.p2p.compute; import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteLogger; import org.apache.ignite.lang.IgniteCallable; import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.resources.LoggerResource; /** */ @@ -28,6 +30,10 @@ public class ExternalCallable implements IgniteCallable { @IgniteInstanceResource Ignite ignite; + /** Logger. */ + @LoggerResource + private IgniteLogger log; + /** */ private int param; @@ -46,10 +52,8 @@ public class ExternalCallable implements IgniteCallable { /** {@inheritDoc} */ @Override public Object call() { - System.err.println("!!!!! I am job " + param + " on " + ignite.name()); + log.info("!!!!! I am job " + param + " on " + ignite.name()); return 42; } } - - http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java ---------------------------------------------------------------------- diff --git a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java index 6a6befc..b20f3b9 100644 --- a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java +++ b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java @@ -18,8 +18,10 @@ package org.apache.ignite.tests.p2p.compute; import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteLogger; import org.apache.ignite.lang.IgniteCallable; import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.resources.LoggerResource; /** */ @@ -28,11 +30,14 @@ public class ExternalCallable1 implements IgniteCallable { @IgniteInstanceResource Ignite ignite; + /** Logger. */ + @LoggerResource + private IgniteLogger log; + /** */ private int param; /** - * */ public ExternalCallable1() { // No-op. @@ -47,10 +52,8 @@ public class ExternalCallable1 implements IgniteCallable { /** {@inheritDoc} */ @Override public Object call() { - System.err.println("!!!!! I am job_1 " + param + " on " + ignite.name()); + log.info("!!!!! I am job_1 " + param + " on " + ignite.name()); return 42; } } - - http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java ---------------------------------------------------------------------- diff --git a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java index 7d1d0f7..48d51ba 100644 --- a/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java +++ b/modules/extdata/p2p/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java @@ -18,8 +18,10 @@ package org.apache.ignite.tests.p2p.compute; import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteLogger; import org.apache.ignite.lang.IgniteCallable; import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.resources.LoggerResource; /** */ @@ -28,11 +30,14 @@ public class ExternalCallable2 implements IgniteCallable { @IgniteInstanceResource Ignite ignite; + /** Logger. */ + @LoggerResource + private IgniteLogger log; + /** */ private int param; /** - * */ public ExternalCallable2() { // No-op. @@ -47,10 +52,8 @@ public class ExternalCallable2 implements IgniteCallable { /** {@inheritDoc} */ @Override public Object call() { - System.err.println("!!!!! I am job_2 " + param + " on " + ignite.name()); + log.info("!!!!! I am job_2 " + param + " on " + ignite.name()); return 42; } } - - http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java ---------------------------------------------------------------------- diff --git a/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java b/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java new file mode 100644 index 0000000..0920199 --- /dev/null +++ b/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable.java @@ -0,0 +1,59 @@ +/* + * 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.tests.p2p.compute; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.lang.IgniteCallable; +import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.resources.LoggerResource; + +/** + */ +public class ExternalCallable implements IgniteCallable { + /** */ + @IgniteInstanceResource + Ignite ignite; + + /** Logger. */ + @LoggerResource + private IgniteLogger log; + + /** */ + private int param; + + /** + */ + public ExternalCallable() { + // No-op. + } + + /** + * @param param Param. + */ + public ExternalCallable(int param) { + this.param = param; + } + + /** {@inheritDoc} */ + @Override public Object call() { + log.info("!!!!! I am modified job " + param + " on " + ignite.name()); + + return 43; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java ---------------------------------------------------------------------- diff --git a/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java b/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java new file mode 100644 index 0000000..fa48f0f --- /dev/null +++ b/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable1.java @@ -0,0 +1,59 @@ +/* + * 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.tests.p2p.compute; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.lang.IgniteCallable; +import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.resources.LoggerResource; + +/** + */ +public class ExternalCallable1 implements IgniteCallable { + /** */ + @IgniteInstanceResource + Ignite ignite; + + /** Logger. */ + @LoggerResource + private IgniteLogger log; + + /** */ + private int param; + + /** + */ + public ExternalCallable1() { + // No-op. + } + + /** + * @param param Param. + */ + public ExternalCallable1(int param) { + this.param = param; + } + + /** {@inheritDoc} */ + @Override public Object call() { + log.info("!!!!! I am modified job_1 " + param + " on " + ignite.name()); + + return 43; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/d2050237/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java ---------------------------------------------------------------------- diff --git a/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java b/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java new file mode 100644 index 0000000..a1ab9c1 --- /dev/null +++ b/modules/extdata/uri/src/main/java/org/apache/ignite/tests/p2p/compute/ExternalCallable2.java @@ -0,0 +1,59 @@ +/* + * 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.tests.p2p.compute; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.lang.IgniteCallable; +import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.resources.LoggerResource; + +/** + */ +public class ExternalCallable2 implements IgniteCallable { + /** */ + @IgniteInstanceResource + Ignite ignite; + + /** Logger. */ + @LoggerResource + private IgniteLogger log; + + /** */ + private int param; + + /** + */ + public ExternalCallable2() { + // No-op. + } + + /** + * @param param Param. + */ + public ExternalCallable2(int param) { + this.param = param; + } + + /** {@inheritDoc} */ + @Override public Object call() { + log.info("!!!!! I am modified job_2 " + param + " on " + ignite.name()); + + return 43; + } +}