This is an automated email from the ASF dual-hosted git repository.
namelchev 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 cf98eadcb04 IGNITE-23202 Fixed server node fail when node service
filter class unknown (#11539)
cf98eadcb04 is described below
commit cf98eadcb04e8191ed9b5fb1a51b8bbd2b867ab8
Author: Nikolay <[email protected]>
AuthorDate: Mon Oct 7 18:11:54 2024 +0300
IGNITE-23202 Fixed server node fail when node service filter class unknown
(#11539)
Co-authored-by: Nikita Amelchev <[email protected]>
---
.../processors/service/IgniteServiceProcessor.java | 70 ++++++++++++++++++----
.../service/LazyServiceConfiguration.java | 53 +++++++++++++++-
.../processors/service/PreparedConfigurations.java | 5 +-
.../service/ServiceDeploymentRequest.java | 7 +--
.../internal/processors/service/ServiceInfo.java | 45 +++++++-------
...eploymentClassLoadingDefaultMarshallerTest.java | 65 ++++++++++++++++++++
.../processors/service/ServiceInfoSelfTest.java | 26 ++++++--
7 files changed, 221 insertions(+), 50 deletions(-)
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 cd35645ee9b..ad547262b88 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
@@ -397,8 +397,16 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
ServiceProcessorCommonDiscoveryData clusterData =
(ServiceProcessorCommonDiscoveryData)data.commonData();
- for (ServiceInfo desc : clusterData.registeredServices())
+ for (ServiceInfo desc : clusterData.registeredServices()) {
+ try {
+ unmarshalNodeFilterIfNeeded(desc.configuration());
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteException("Cannot join the cluster.", e);
+ }
+
registerService(desc);
+ }
}
/** {@inheritDoc} */
@@ -413,15 +421,27 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
ClusterNode node,
DiscoveryDataBag.JoiningNodeDiscoveryData data
) {
- if (data.joiningNodeData() == null || !ctx.security().enabled())
+ if (data.joiningNodeData() == null)
return null;
List<ServiceInfo> svcs =
((ServiceProcessorJoinNodeDiscoveryData)data.joiningNodeData()).services();
- SecurityException err = checkDeployPermissionDuringJoin(node, svcs);
+ if (ctx.security().enabled()) {
+ SecurityException err = checkDeployPermissionDuringJoin(node,
svcs);
- if (err != null)
- return new IgniteNodeValidationResult(node.id(), err.getMessage());
+ if (err != null)
+ return new IgniteNodeValidationResult(node.id(),
err.getMessage());
+ }
+
+ for (ServiceInfo svc : svcs) {
+ try {
+ unmarshalNodeFilterIfNeeded(svc.configuration());
+ }
+ catch (IgniteCheckedException e) {
+ return new IgniteNodeValidationResult(node.id(), "Node join is
rejected [joiningNodeId=" + node.id() +
+ ", msg=" + e.getMessage() + ']');
+ }
+ }
return null;
}
@@ -654,7 +674,7 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
*/
private PreparedConfigurations<IgniteUuid>
prepareServiceConfigurations(Collection<ServiceConfiguration> cfgs,
IgnitePredicate<ClusterNode> dfltNodeFilter) {
- List<ServiceConfiguration> cfgsCp = new ArrayList<>(cfgs.size());
+ List<LazyServiceConfiguration> cfgsCp = new ArrayList<>(cfgs.size());
List<GridServiceDeploymentFuture<IgniteUuid>> failedFuts = null;
@@ -679,12 +699,14 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
if (err == null) {
try {
byte[] srvcBytes = U.marshal(marsh, cfg.getService());
+ byte[] nodeFilterBytes = U.marshal(marsh,
cfg.getNodeFilter());
byte[] interceptorsBytes = U.marshal(marsh,
cfg.getInterceptors());
String[] knownSvcMdtNames = cfg instanceof
PlatformServiceConfiguration ?
((PlatformServiceConfiguration)cfg).mtdNames() : null;
- cfgsCp.add(new LazyServiceConfiguration(cfg, srvcBytes,
interceptorsBytes).platformMtdNames(knownSvcMdtNames));
+ cfgsCp.add(new LazyServiceConfiguration(cfg, srvcBytes,
nodeFilterBytes, interceptorsBytes)
+ .platformMtdNames(knownSvcMdtNames));
}
catch (Exception e) {
U.error(log, "Failed to marshal service with configured
marshaller " +
@@ -771,7 +793,7 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
PreparedConfigurations<IgniteUuid> srvcCfg =
prepareServiceConfigurations(cfgs, dfltNodeFilter);
- List<ServiceConfiguration> cfgsCp = srvcCfg.cfgs;
+ List<LazyServiceConfiguration> cfgsCp = srvcCfg.cfgs;
List<GridServiceDeploymentFuture<IgniteUuid>> failedFuts =
srvcCfg.failedFuts;
@@ -781,7 +803,7 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
try {
Collection<ServiceChangeAbstractRequest> reqs = new
ArrayList<>();
- for (ServiceConfiguration cfg : cfgsCp) {
+ for (LazyServiceConfiguration cfg : cfgsCp) {
IgniteUuid srvcId = IgniteUuid.randomUuid();
GridServiceDeploymentFuture<IgniteUuid> fut = new
GridServiceDeploymentFuture<>(cfg, srvcId);
@@ -1421,6 +1443,23 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
}
}
+ /** @param cfg Lazy service configuration. */
+ private void unmarshalNodeFilterIfNeeded(LazyServiceConfiguration cfg)
throws IgniteCheckedException {
+ if (cfg.getNodeFilter() != null)
+ return;
+
+ GridDeployment dep =
ctx.deploy().getDeployment(cfg.serviceClassName());
+
+ ClassLoader clsLdr = U.resolveClassLoader(dep != null ?
dep.classLoader() : null, ctx.config());
+
+ try {
+ cfg.setNodeFilter(U.unmarshal(marsh, cfg.nodeFilterBytes(),
clsLdr));
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteCheckedException("Failed to unmarshal class of
service node filter [cfg=" + cfg + ']', e);
+ }
+ }
+
/**
* @param ctxs Contexts to cancel.
* @param cancelCnt Number of contexts to cancel.
@@ -1712,7 +1751,7 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
}
}
- for (ServiceConfiguration srvcCfg : prepCfgs.cfgs) {
+ for (LazyServiceConfiguration srvcCfg : prepCfgs.cfgs) {
ServiceInfo srvcInfo = new ServiceInfo(ctx.localNodeId(),
IgniteUuid.randomUuid(), srvcCfg, true);
srvcInfo.context(ctx);
@@ -1764,11 +1803,20 @@ public class IgniteServiceProcessor extends
GridProcessorAdapter implements Igni
"exists : [" + "srvcId" + reqSrvcId + ", srvcTop=" +
oldDesc.topologySnapshot() + ']');
}
else {
- ServiceConfiguration cfg =
((ServiceDeploymentRequest)req).configuration();
+ LazyServiceConfiguration cfg =
((ServiceDeploymentRequest)req).configuration();
if (ctx.security().enabled())
err =
checkPermissions(((ServiceDeploymentRequest)req).configuration().getName(),
SERVICE_DEPLOY);
+ if (err == null) {
+ try {
+ unmarshalNodeFilterIfNeeded(cfg);
+ }
+ catch (IgniteCheckedException e) {
+ err = new IgniteCheckedException("Failed to deploy
service.", e);
+ }
+ }
+
if (err == null) {
oldDesc = lookupInRegisteredServices(cfg.getName());
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/LazyServiceConfiguration.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/LazyServiceConfiguration.java
index b7fc099e33a..c5c35b2f1fc 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/LazyServiceConfiguration.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/LazyServiceConfiguration.java
@@ -18,12 +18,13 @@
package org.apache.ignite.internal.processors.service;
import java.util.Arrays;
+import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.services.Service;
import org.apache.ignite.services.ServiceCallInterceptor;
import org.apache.ignite.services.ServiceConfiguration;
-import org.jetbrains.annotations.Nullable;
/**
* Lazy service configuration.
@@ -36,6 +37,10 @@ public class LazyServiceConfiguration extends
ServiceConfiguration {
@GridToStringExclude
private transient Service srvc;
+ /** Node filter. */
+ @GridToStringExclude
+ private transient IgnitePredicate<ClusterNode> nodeFilter;
+
/** Service interceptors. */
@GridToStringExclude
private transient ServiceCallInterceptor[] interceptors;
@@ -46,6 +51,9 @@ public class LazyServiceConfiguration extends
ServiceConfiguration {
/** */
private byte[] srvcBytes;
+ /** */
+ private byte[] nodeFilterBytes;
+
/** */
private byte[] interceptorsBytes;
@@ -65,7 +73,12 @@ public class LazyServiceConfiguration extends
ServiceConfiguration {
* @param srvcBytes Marshalled service.
* @param interceptorsBytes Marshalled interceptors.
*/
- public LazyServiceConfiguration(ServiceConfiguration cfg, byte[]
srvcBytes, @Nullable byte[] interceptorsBytes) {
+ public LazyServiceConfiguration(
+ ServiceConfiguration cfg,
+ byte[] srvcBytes,
+ byte[] nodeFilterBytes,
+ byte[] interceptorsBytes
+ ) {
assert cfg.getService() != null : cfg;
assert srvcBytes != null;
@@ -75,6 +88,7 @@ public class LazyServiceConfiguration extends
ServiceConfiguration {
cacheName = cfg.getCacheName();
affKey = cfg.getAffinityKey();
nodeFilter = cfg.getNodeFilter();
+ this.nodeFilterBytes = nodeFilterBytes;
this.srvcBytes = srvcBytes;
srvc = cfg.getService();
srvcClsName = srvc.getClass().getName();
@@ -83,6 +97,13 @@ public class LazyServiceConfiguration extends
ServiceConfiguration {
this.interceptorsBytes = interceptorsBytes;
}
+ /**
+ * @return Node filter bytes.
+ */
+ public byte[] nodeFilterBytes() {
+ return nodeFilterBytes;
+ }
+
/**
* @return Service bytes.
*/
@@ -104,6 +125,18 @@ public class LazyServiceConfiguration extends
ServiceConfiguration {
return srvc;
}
+ /** {@inheritDoc} */
+ @Override public ServiceConfiguration
setNodeFilter(IgnitePredicate<ClusterNode> nodeFilter) {
+ this.nodeFilter = nodeFilter;
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgnitePredicate<ClusterNode> getNodeFilter() {
+ return nodeFilter;
+ }
+
/** {@inheritDoc} */
@Override public ServiceCallInterceptor[] getInterceptors() {
return interceptors;
@@ -116,6 +149,19 @@ public class LazyServiceConfiguration extends
ServiceConfiguration {
return interceptorsBytes;
}
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (!(o instanceof LazyServiceConfiguration))
+ return super.equals(o);
+
+ if (!equalsIgnoreNodeFilter(o))
+ return false;
+
+ LazyServiceConfiguration that = (LazyServiceConfiguration)o;
+
+ return Arrays.equals(nodeFilterBytes, that.nodeFilterBytes);
+ }
+
/** {@inheritDoc} */
@SuppressWarnings("RedundantIfStatement")
@Override public boolean equalsIgnoreNodeFilter(Object o) {
@@ -168,6 +214,7 @@ public class LazyServiceConfiguration extends
ServiceConfiguration {
String svcCls = srvc == null ? "" : srvc.getClass().getSimpleName();
String nodeFilterCls = nodeFilter == null ? "" :
nodeFilter.getClass().getSimpleName();
- return S.toString(LazyServiceConfiguration.class, this, "svcCls",
svcCls, "nodeFilterCls", nodeFilterCls);
+ return S.toString(LazyServiceConfiguration.class, this, "name", name,
"svcCls", svcCls,
+ "nodeFilterCls", nodeFilterCls);
}
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/PreparedConfigurations.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/PreparedConfigurations.java
index abfb65cb2df..ce20378132e 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/PreparedConfigurations.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/PreparedConfigurations.java
@@ -20,14 +20,13 @@ package org.apache.ignite.internal.processors.service;
import java.io.Serializable;
import java.util.List;
import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.services.ServiceConfiguration;
/**
* Result of services validation before deployment.
*/
class PreparedConfigurations<T extends Serializable> {
/** */
- final List<ServiceConfiguration> cfgs;
+ final List<LazyServiceConfiguration> cfgs;
/** */
final List<GridServiceDeploymentFuture<T>> failedFuts;
@@ -36,7 +35,7 @@ class PreparedConfigurations<T extends Serializable> {
* @param cfgs Configurations to deploy.
* @param failedFuts Finished futures for failed configurations.
*/
- PreparedConfigurations(List<ServiceConfiguration> cfgs,
List<GridServiceDeploymentFuture<T>> failedFuts) {
+ PreparedConfigurations(List<LazyServiceConfiguration> cfgs,
List<GridServiceDeploymentFuture<T>> failedFuts) {
this.cfgs = cfgs;
this.failedFuts = failedFuts;
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceDeploymentRequest.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceDeploymentRequest.java
index d41e5aab7f4..ba7152ed187 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceDeploymentRequest.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceDeploymentRequest.java
@@ -19,7 +19,6 @@ package org.apache.ignite.internal.processors.service;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.services.ServiceConfiguration;
import org.jetbrains.annotations.NotNull;
/**
@@ -30,13 +29,13 @@ public class ServiceDeploymentRequest extends
ServiceChangeAbstractRequest {
private static final long serialVersionUID = 0L;
/** Service configuration. */
- private final ServiceConfiguration cfg;
+ private final LazyServiceConfiguration cfg;
/**
* @param srvcId Service id.
* @param cfg Service configuration.
*/
- public ServiceDeploymentRequest(@NotNull IgniteUuid srvcId, @NotNull
ServiceConfiguration cfg) {
+ public ServiceDeploymentRequest(@NotNull IgniteUuid srvcId, @NotNull
LazyServiceConfiguration cfg) {
super(srvcId);
this.cfg = cfg;
@@ -45,7 +44,7 @@ public class ServiceDeploymentRequest extends
ServiceChangeAbstractRequest {
/**
* @return Service configuration.
*/
- public ServiceConfiguration configuration() {
+ public LazyServiceConfiguration configuration() {
return cfg;
}
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceInfo.java
b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceInfo.java
index 3d6d60965ff..1d750d13e11 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceInfo.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/ServiceInfo.java
@@ -27,7 +27,6 @@ import
org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.services.Service;
-import org.apache.ignite.services.ServiceConfiguration;
import org.apache.ignite.services.ServiceDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -49,7 +48,7 @@ public class ServiceInfo implements ServiceDescriptor {
private final IgniteUuid srvcId;
/** Service configuration. */
- private final ServiceConfiguration cfg;
+ private final LazyServiceConfiguration cfg;
/** Statically configured flag. */
private final boolean staticCfg;
@@ -66,7 +65,7 @@ public class ServiceInfo implements ServiceDescriptor {
* @param srvcId Service id.
* @param cfg Service configuration.
*/
- public ServiceInfo(@NotNull UUID originNodeId, @NotNull IgniteUuid srvcId,
@NotNull ServiceConfiguration cfg) {
+ public ServiceInfo(@NotNull UUID originNodeId, @NotNull IgniteUuid srvcId,
@NotNull LazyServiceConfiguration cfg) {
this(originNodeId, srvcId, cfg, false);
}
@@ -76,7 +75,7 @@ public class ServiceInfo implements ServiceDescriptor {
* @param cfg Service configuration.
* @param staticCfg Statically configured flag.
*/
- public ServiceInfo(@NotNull UUID originNodeId, @NotNull IgniteUuid srvcId,
@NotNull ServiceConfiguration cfg,
+ public ServiceInfo(@NotNull UUID originNodeId, @NotNull IgniteUuid srvcId,
@NotNull LazyServiceConfiguration cfg,
boolean staticCfg) {
this.originNodeId = originNodeId;
this.srvcId = srvcId;
@@ -107,7 +106,7 @@ public class ServiceInfo implements ServiceDescriptor {
*
* @return Service configuration.
*/
- public ServiceConfiguration configuration() {
+ public LazyServiceConfiguration configuration() {
return cfg;
}
@@ -134,34 +133,30 @@ public class ServiceInfo implements ServiceDescriptor {
/** {@inheritDoc} */
@Override public Class<? extends Service> serviceClass() {
- if (cfg instanceof LazyServiceConfiguration) {
- if (srvcCls != null)
- return srvcCls;
+ if (srvcCls != null)
+ return srvcCls;
- String clsName =
((LazyServiceConfiguration)cfg).serviceClassName();
+ String clsName = cfg.serviceClassName();
- try {
- srvcCls = (Class<? extends Service>)Class.forName(clsName);
+ try {
+ srvcCls = (Class<? extends Service>)Class.forName(clsName);
- return srvcCls;
- }
- catch (ClassNotFoundException e) {
- if (ctx != null) {
- GridDeployment srvcDep =
ctx.deploy().getDeployment(clsName);
+ return srvcCls;
+ }
+ catch (ClassNotFoundException e) {
+ if (ctx != null) {
+ GridDeployment srvcDep = ctx.deploy().getDeployment(clsName);
- if (srvcDep != null) {
- srvcCls = (Class<? extends
Service>)srvcDep.deployedClass(clsName).get1();
+ if (srvcDep != null) {
+ srvcCls = (Class<? extends
Service>)srvcDep.deployedClass(clsName).get1();
- if (srvcCls != null)
- return srvcCls;
- }
+ if (srvcCls != null)
+ return srvcCls;
}
-
- throw new IgniteException("Failed to find service class: " +
clsName, e);
}
+
+ throw new IgniteException("Failed to find service class: " +
clsName, e);
}
- else
- return cfg.getService().getClass();
}
/** {@inheritDoc} */
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/service/IgniteServiceDeploymentClassLoadingDefaultMarshallerTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/service/IgniteServiceDeploymentClassLoadingDefaultMarshallerTest.java
index 5ea781ac3d1..febac2431fe 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/service/IgniteServiceDeploymentClassLoadingDefaultMarshallerTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/service/IgniteServiceDeploymentClassLoadingDefaultMarshallerTest.java
@@ -19,15 +19,22 @@ package org.apache.ignite.internal.processors.service;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.failure.StopNodeFailureHandler;
+import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.marshaller.Marshaller;
import org.apache.ignite.services.Service;
import org.apache.ignite.services.ServiceConfiguration;
+import org.apache.ignite.services.ServiceDeploymentException;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.junit.Test;
+import static
org.apache.ignite.testframework.GridTestUtils.assertThrowsWithCause;
+
/**
* Tests that not all nodes in cluster need user's service definition (only
nodes according to filter).
*/
@@ -35,6 +42,9 @@ public class
IgniteServiceDeploymentClassLoadingDefaultMarshallerTest extends Gr
/** */
private static final String NOOP_SERVICE_CLS_NAME =
"org.apache.ignite.tests.p2p.NoopService";
+ /** */
+ private static final String NODE_FILTER_CLS_NAME =
"org.apache.ignite.tests.p2p.ExcludeNodeFilter";
+
/** */
private static final int SERVER_NODE = 0;
@@ -69,6 +79,8 @@ public class
IgniteServiceDeploymentClassLoadingDefaultMarshallerTest extends Gr
if (extClsLdrGrids.contains(igniteInstanceName))
cfg.setClassLoader(extClsLdr);
+ cfg.setFailureHandler(new StopNodeFailureHandler());
+
return cfg;
}
@@ -152,6 +164,59 @@ public class
IgniteServiceDeploymentClassLoadingDefaultMarshallerTest extends Gr
startClientGrid(CLIENT_NODE_WITH_EXT_CLASS_LOADER).services().deploy(serviceConfig());
}
+ /** @throws Exception If failed. */
+ @Test
+ public void testFailWhenNodeFilterClassNotFound() throws Exception {
+ IgniteEx srv = startGrid(SERVER_NODE);
+ IgniteEx cli = startClientGrid(CLIENT_NODE);
+
+ ServiceConfiguration svcCfg = new ServiceConfiguration()
+ .setName("TestDeploymentService")
+
.setService(((Class<Service>)extClsLdr.loadClass(NOOP_SERVICE_CLS_NAME)).getDeclaredConstructor().newInstance())
+
.setNodeFilter(((Class<IgnitePredicate<ClusterNode>>)extClsLdr.loadClass(NODE_FILTER_CLS_NAME))
+ .getConstructor(UUID.class)
+ .newInstance(cli.context().localNodeId()))
+ .setTotalCount(1);
+
+ // 1. Node filter class not found on nodes.
+ assertThrowsWithCause(() -> cli.services().deploy(svcCfg),
ServiceDeploymentException.class);
+
+ // 2. Node filter class not found on cluster nodes during node join.
+ IgniteConfiguration cfg =
getConfiguration(getTestIgniteInstanceName(SERVER_NODE_WITH_EXT_CLASS_LOADER))
+ .setServiceConfiguration(svcCfg);
+
+ assertThrowsWithCause(() -> startGrid(cfg),
IgniteCheckedException.class);
+
+ assertTrue(cli.services().serviceDescriptors().isEmpty());
+ assertTrue(srv.services().serviceDescriptors().isEmpty());
+
+ // Check node availability.
+ srv.createCache(DEFAULT_CACHE_NAME).put(1, 1);
+ cli.cache(DEFAULT_CACHE_NAME).put(2, 2);
+ }
+
+ /** @throws Exception If failed. */
+ @Test
+ public void testFailWhenNodeFilterClassNotFoundOnJoiningNode() throws
Exception {
+ IgniteEx srv = startGrid(SERVER_NODE_WITH_EXT_CLASS_LOADER);
+ IgniteEx cli = startClientGrid(CLIENT_NODE_WITH_EXT_CLASS_LOADER);
+
+ ServiceConfiguration svcCfg = new ServiceConfiguration()
+ .setName("TestDeploymentService")
+
.setService(((Class<Service>)extClsLdr.loadClass(NOOP_SERVICE_CLS_NAME)).getDeclaredConstructor().newInstance())
+
.setNodeFilter(((Class<IgnitePredicate<ClusterNode>>)extClsLdr.loadClass(NODE_FILTER_CLS_NAME))
+ .getConstructor(UUID.class)
+ .newInstance(cli.context().localNodeId()))
+ .setTotalCount(1);
+
+ cli.services().deploy(svcCfg);
+
+ assertThrowsWithCause(() -> startGrid(SERVER_NODE),
IgniteCheckedException.class);
+
+ assertEquals(1, cli.services().serviceDescriptors().size());
+ assertEquals(1, srv.services().serviceDescriptors().size());
+ }
+
/**
* @return Service configuration.
* @throws Exception If failed.
diff --git
a/modules/core/src/test/java/org/apache/ignite/internal/processors/service/ServiceInfoSelfTest.java
b/modules/core/src/test/java/org/apache/ignite/internal/processors/service/ServiceInfoSelfTest.java
index 6233168a6e7..60b9531d45e 100644
---
a/modules/core/src/test/java/org/apache/ignite/internal/processors/service/ServiceInfoSelfTest.java
+++
b/modules/core/src/test/java/org/apache/ignite/internal/processors/service/ServiceInfoSelfTest.java
@@ -23,8 +23,11 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
import org.apache.ignite.services.Service;
import org.apache.ignite.services.ServiceConfiguration;
import org.apache.ignite.services.ServiceContext;
@@ -32,7 +35,6 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertSame;
/**
* Tests of {@link ServiceInfo} class.
@@ -48,15 +50,13 @@ public class ServiceInfoSelfTest {
private ServiceConfiguration cfg = configuration();
/** Subject under test. */
- private ServiceInfo sut = new ServiceInfo(nodeId, srvcId, cfg);
+ private ServiceInfo sut = serviceInfo(cfg);
/**
* Tests {@link ServiceInfo#configuration()}.
*/
@Test
public void testConfigurationEquality() {
- assertSame(cfg, sut.configuration());
-
assertEquals(cfg.getService().getClass(), sut.serviceClass());
assertEquals(cfg.getName(), sut.name());
@@ -138,6 +138,24 @@ public class ServiceInfoSelfTest {
return cfg;
}
+ /** */
+ private ServiceInfo serviceInfo(ServiceConfiguration cfg) {
+ try {
+ JdkMarshaller marsh = new JdkMarshaller();
+
+ byte[] srvcBytes = U.marshal(marsh, cfg.getService());
+ byte[] nodeFilterBytes = U.marshal(marsh, cfg.getNodeFilter());
+ byte[] interceptorsBytes = U.marshal(marsh, cfg.getInterceptors());
+
+ LazyServiceConfiguration lazyCfg = new
LazyServiceConfiguration(cfg, srvcBytes, nodeFilterBytes, interceptorsBytes);
+
+ return new ServiceInfo(nodeId, srvcId, lazyCfg);
+ }
+ catch (IgniteCheckedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/**
* Tests service implementation.
*/