Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ private void cancelDeployedServices() {
ServiceProcessorCommonDiscoveryData clusterData = (ServiceProcessorCommonDiscoveryData)data.commonData();

for (ServiceInfo desc : clusterData.registeredServices())
registeredServices.put(desc.serviceId(), desc);
registerService(desc);
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -383,7 +383,7 @@ private void cancelDeployedServices() {
oldDesc = lookupInRegisteredServices(desc.name());

if (oldDesc == null) {
registeredServices.put(desc.serviceId(), desc);
registerService(desc);

continue;
}
Expand Down Expand Up @@ -1513,7 +1513,7 @@ private boolean isLocalNodeCoordinator() {
// 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;
Expand Down Expand Up @@ -1556,8 +1556,13 @@ public ServiceDeploymentManager deployment() {
}
}

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;
Expand Down Expand Up @@ -1615,7 +1620,7 @@ else if (req instanceof ServiceUndeploymentRequest)
else {
ServiceInfo desc = new ServiceInfo(snd.id(), reqSrvcId, cfg);

registeredServices.put(reqSrvcId, desc);
registerService(desc);

toDeploy.put(reqSrvcId, desc);
}
Expand Down Expand Up @@ -1669,6 +1674,15 @@ else if (req instanceof ServiceUndeploymentRequest) {
}
}

/**
* @param desc Service descriptor.
*/
private void registerService(ServiceInfo desc) {
desc.context(ctx);

registeredServices.put(desc.serviceId(), desc);
}

/**
* @param msg Message.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
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;
Expand All @@ -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;

Expand All @@ -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.
Expand All @@ -76,6 +84,15 @@ public ServiceInfo(@NotNull UUID originNodeId, @NotNull IgniteUuid srvcId, @NotN
this.staticCfg = staticCfg;
}

/**
* Sets kernal context.
*
* @param ctx Context.
*/
public void context(GridKernalContext ctx) {
this.ctx = ctx;
}

/**
* Sets service's new topology snapshot.
*
Expand Down Expand Up @@ -116,15 +133,30 @@ public IgniteUuid serviceId() {
}

/** {@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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@
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;
Expand Down Expand Up @@ -79,11 +85,70 @@ public void cleanup() {
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");

Expand All @@ -99,8 +164,12 @@ public void serviceHotRedeploymentTest() throws Exception {
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());
Expand All @@ -111,14 +180,26 @@ public void serviceHotRedeploymentTest() throws Exception {
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();
}
}

/** */
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 {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -98,6 +102,25 @@ public void testTopologySnapshotEquality() {
assertNotSame(top, sut.topologySnapshot());
}

/**
* 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.
*/
Expand Down