You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by da...@apache.org on 2020/12/04 10:08:05 UTC

[ignite] branch master updated: IGNITE-13633 Fixed ServiceDescriptor#serviceClass failure in case of service deployed through UriDeploymentSpi (#8431)

This is an automated email from the ASF dual-hosted git repository.

daradurvs 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 dac3706  IGNITE-13633 Fixed ServiceDescriptor#serviceClass failure in case of service deployed through UriDeploymentSpi (#8431)
dac3706 is described below

commit dac370614be8c660601c881c2fc7bc79f9089df9
Author: Aleksey Plekhanov <Pl...@gmail.com>
AuthorDate: Fri Dec 4 13:07:41 2020 +0300

    IGNITE-13633 Fixed ServiceDescriptor#serviceClass failure in case of service deployed through UriDeploymentSpi (#8431)
---
 .../processors/service/IgniteServiceProcessor.java | 26 ++++--
 .../internal/processors/service/ServiceInfo.java   | 36 ++++++++-
 ...ServiceHotRedeploymentViaDeploymentSpiTest.java | 93 ++++++++++++++++++++--
 .../processors/service/ServiceInfoSelfTest.java    | 23 ++++++
 4 files changed, 164 insertions(+), 14 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 c25a87e..e3ad553 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
@@ -350,7 +350,7 @@ public class IgniteServiceProcessor extends ServiceProcessorAdapter implements I
         ServiceProcessorCommonDiscoveryData clusterData = (ServiceProcessorCommonDiscoveryData)data.commonData();
 
         for (ServiceInfo desc : clusterData.registeredServices())
-            registeredServices.put(desc.serviceId(), desc);
+            registerService(desc);
     }
 
     /** {@inheritDoc} */
@@ -383,7 +383,7 @@ public class IgniteServiceProcessor extends ServiceProcessorAdapter implements I
             oldDesc = lookupInRegisteredServices(desc.name());
 
             if (oldDesc == null) {
-                registeredServices.put(desc.serviceId(), desc);
+                registerService(desc);
 
                 continue;
             }
@@ -1513,7 +1513,7 @@ public class IgniteServiceProcessor extends ServiceProcessorAdapter implements I
             // First node start, method onGridDataReceived(DiscoveryDataBag.GridDiscoveryData) has not been called.
             ArrayList<ServiceInfo> staticServicesInfo = staticallyConfiguredServices(false);
 
-            staticServicesInfo.forEach(desc -> registeredServices.put(desc.serviceId(), desc));
+            staticServicesInfo.forEach(this::registerService);
         }
 
         ServiceDeploymentActions depActions = null;
@@ -1556,8 +1556,13 @@ public class IgniteServiceProcessor extends ServiceProcessorAdapter implements I
                 }
             }
 
-            for (ServiceConfiguration srvcCfg : prepCfgs.cfgs)
-                staticServicesInfo.add(new ServiceInfo(ctx.localNodeId(), IgniteUuid.randomUuid(), srvcCfg, true));
+            for (ServiceConfiguration srvcCfg : prepCfgs.cfgs) {
+                ServiceInfo serviceInfo = new ServiceInfo(ctx.localNodeId(), IgniteUuid.randomUuid(), srvcCfg, true);
+
+                serviceInfo.context(ctx);
+
+                staticServicesInfo.add(serviceInfo);
+            }
         }
 
         return staticServicesInfo;
@@ -1615,7 +1620,7 @@ public class IgniteServiceProcessor extends ServiceProcessorAdapter implements I
                         else {
                             ServiceInfo desc = new ServiceInfo(snd.id(), reqSrvcId, cfg);
 
-                            registeredServices.put(reqSrvcId, desc);
+                            registerService(desc);
 
                             toDeploy.put(reqSrvcId, desc);
                         }
@@ -1670,6 +1675,15 @@ public class IgniteServiceProcessor extends ServiceProcessorAdapter implements I
     }
 
     /**
+     * @param desc Service descriptor.
+     */
+    private void registerService(ServiceInfo desc) {
+        desc.context(ctx);
+
+        registeredServices.put(desc.serviceId(), desc);
+    }
+
+    /**
      * @param msg Message.
      */
     private void processChangeGlobalStateRequest(ChangeGlobalStateMessage msg) {
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 2360eda..67a94c5 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
@@ -21,6 +21,8 @@ import java.util.Collections;
 import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.managers.deployment.GridDeployment;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.lang.IgniteUuid;
@@ -37,6 +39,9 @@ public class ServiceInfo implements ServiceDescriptor {
     /** */
     private static final long serialVersionUID = 0L;
 
+    /** Context. */
+    private transient volatile GridKernalContext ctx;
+
     /** Origin node ID. */
     private final UUID originNodeId;
 
@@ -53,6 +58,9 @@ public class ServiceInfo implements ServiceDescriptor {
     @GridToStringInclude
     private volatile Map<UUID, Integer> top;
 
+    /** Service class. */
+    private transient volatile Class<? extends Service> srvcCls;
+
     /**
      * @param originNodeId Initiating node id.
      * @param srvcId Service id.
@@ -77,6 +85,15 @@ public class ServiceInfo implements ServiceDescriptor {
     }
 
     /**
+     * Sets kernal context.
+     *
+     * @param ctx Context.
+     */
+    public void context(GridKernalContext ctx) {
+        this.ctx = ctx;
+    }
+
+    /**
      * Sets service's new topology snapshot.
      *
      * @param top Topology snapshot.
@@ -116,15 +133,30 @@ public class ServiceInfo implements ServiceDescriptor {
     }
 
     /** {@inheritDoc} */
-    @SuppressWarnings("unchecked")
     @Override public Class<? extends Service> serviceClass() {
         if (cfg instanceof LazyServiceConfiguration) {
+            if (srvcCls != null)
+                return srvcCls;
+
             String clsName = ((LazyServiceConfiguration)cfg).serviceClassName();
 
             try {
-                return (Class<? extends Service>)Class.forName(clsName);
+                srvcCls = (Class<? extends Service>)Class.forName(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);
+
+                        if (srvcCls != null)
+                            return srvcCls;
+                    }
+                }
+
                 throw new IgniteException("Failed to find service class: " + clsName, e);
             }
         }
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
index 7ac558a..c108224 100644
--- 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
@@ -24,12 +24,18 @@ import java.net.URLClassLoader;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.function.ToIntFunction;
 import javax.tools.JavaCompiler;
 import javax.tools.ToolProvider;
 import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.ClientConfiguration;
 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.services.ServiceDescriptor;
 import org.apache.ignite.spi.deployment.DeploymentSpi;
 import org.apache.ignite.spi.deployment.local.LocalDeploymentSpi;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
@@ -79,11 +85,70 @@ public class ServiceHotRedeploymentViaDeploymentSpiTest extends GridCommonAbstra
         U.delete(srcTmpDir);
     }
 
+    /** */
+    @Test
+    public void testServiceDeploymentViaDeploymentSpi() 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);
+
+            ignite.configuration().getDeploymentSpi().register(clsLdr, cls);
+
+            ignite.services().deployClusterSingleton(SERVICE_NAME, srvc);
+
+            Class<?> srvcCls = serviceClass(ignite, SERVICE_NAME);
+
+            assertSame(cls, srvcCls);
+
+            assertEquals(1, ignite.services().serviceProxy(SERVICE_NAME, MyRenewService.class, false)
+                .version());
+
+            Ignite ignite1 = startGrid(1);
+
+            ignite1.configuration().getDeploymentSpi().register(clsLdr, cls);
+
+            srvcCls = serviceClass(ignite1, SERVICE_NAME);
+
+            assertSame(cls, srvcCls);
+
+            assertEquals(1, ignite1.services().serviceProxy(SERVICE_NAME, MyRenewService.class, false)
+                .version());
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /** */
+    @Test
+    public void testServiceHotRedeploymentNode() throws Exception {
+        serviceHotRedeploymentTest(
+            ignite -> ignite.services().serviceProxy(SERVICE_NAME, MyRenewService.class, false).version());
+    }
+
+    /** */
+    @Test
+    public void testServiceHotRedeploymentThinClient() throws Exception {
+        serviceHotRedeploymentTest(ignite -> {
+            try (IgniteClient client = Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10800"))) {
+                return client.services().serviceProxy(SERVICE_NAME, MyRenewService.class).version();
+            }
+            catch (Exception e) {
+                throw new IgniteException(e);
+            }
+        });
+    }
+
     /**
      * @throws Exception If failed.
      */
-    @Test
-    public void serviceHotRedeploymentTest() throws Exception {
+    private void serviceHotRedeploymentTest(ToIntFunction<Ignite> srvcFunc) throws Exception {
         URLClassLoader clsLdr = prepareClassLoader(1);
         Class<?> cls = clsLdr.loadClass("MyRenewServiceImpl");
 
@@ -99,8 +164,12 @@ public class ServiceHotRedeploymentViaDeploymentSpiTest extends GridCommonAbstra
             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());
+
+            Class<?> srvcCls = serviceClass(ignite, SERVICE_NAME);
+
+            assertSame(cls, srvcCls);
+
+            assertEquals(1, srvcFunc.applyAsInt(ignite));
 
             ignite.services().cancel(SERVICE_NAME);
             depSpi.unregister(srvc.getClass().getName());
@@ -111,8 +180,10 @@ public class ServiceHotRedeploymentViaDeploymentSpiTest extends GridCommonAbstra
             depSpi.register(clsLdr, srvc.getClass());
 
             ignite.services().deployClusterSingleton(SERVICE_NAME, srvc);
-            proxy = ignite.services().serviceProxy(SERVICE_NAME, MyRenewService.class, false);
-            assertEquals(2, proxy.version());
+
+            assertNotSame(srvcCls, serviceClass(ignite, SERVICE_NAME));
+
+            assertEquals(2, srvcFunc.applyAsInt(ignite));
         }
         finally {
             stopAllGrids();
@@ -120,6 +191,16 @@ public class ServiceHotRedeploymentViaDeploymentSpiTest extends GridCommonAbstra
     }
 
     /** */
+    private Class<?> serviceClass(Ignite ignite, String srvcName) {
+        for (ServiceDescriptor desc : ignite.services().serviceDescriptors()) {
+            if (srvcName.equals(desc.name()))
+                return desc.serviceClass();
+        }
+
+        return null;
+    }
+
+    /** */
     public interface MyRenewService extends Service {
         /**
          * @return Service's version.
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 4d557f5..6233168 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
@@ -17,6 +17,10 @@
 
 package org.apache.ignite.internal.processors.service;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.util.HashMap;
 import java.util.UUID;
 import org.apache.ignite.cluster.ClusterNode;
@@ -99,6 +103,25 @@ public class ServiceInfoSelfTest {
     }
 
     /**
+     * Tests serialization/deserialization of ServiceInfo.
+     */
+    @Test
+    public void testSerializeDeserialize() throws Exception {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+        new ObjectOutputStream(os).writeObject(sut);
+
+        ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(os.toByteArray()));
+
+        ServiceInfo srvcInfo = (ServiceInfo)is.readObject();
+
+        assertEquals(sut.name(), srvcInfo.name());
+        assertEquals(sut.originNodeId(), srvcInfo.originNodeId());
+        assertEquals(sut.serviceId(), srvcInfo.serviceId());
+        assertEquals(sut.serviceClass(), srvcInfo.serviceClass());
+    }
+
+    /**
      * @return Service configuration.
      */
     private ServiceConfiguration configuration() {