Skip to content
This repository has been archived by the owner on Aug 23, 2023. It is now read-only.

Commit

Permalink
Check SARL specification version before spawning an agent.
Browse files Browse the repository at this point in the history
see #115

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Nov 29, 2015
1 parent 4548133 commit e9f944d
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

package io.janusproject.kernel.services.jdk.spawn;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
Expand All @@ -29,14 +31,14 @@

import javax.inject.Inject;

import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.Service;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.name.Names;
import io.janusproject.kernel.bic.BuiltinCapacityUtil;
import io.janusproject.services.AbstractDependentService;
import io.janusproject.services.contextspace.ContextSpaceService;
Expand All @@ -48,9 +50,12 @@

import io.sarl.core.AgentKilled;
import io.sarl.core.AgentSpawned;
import io.sarl.lang.SARLVersion;
import io.sarl.lang.annotation.SarlSpecification;
import io.sarl.lang.core.Address;
import io.sarl.lang.core.Agent;
import io.sarl.lang.core.AgentContext;
import io.sarl.lang.core.BuiltinCapacitiesProvider;
import io.sarl.lang.core.EventSpace;
import io.sarl.lang.util.SynchronizedCollection;
import io.sarl.lang.util.SynchronizedSet;
Expand Down Expand Up @@ -97,14 +102,29 @@ public Collection<Class<? extends Service>> getServiceDependencies() {
return Arrays.<Class<? extends Service>>asList(ContextSpaceService.class);
}

private static void ensureSarlSpecificationVersion(Class<? extends Agent> agentClazz) {
SarlSpecification annotation = agentClazz.getAnnotation(SarlSpecification.class);
if (annotation != null) {
String value = annotation.value();
if (!Strings.isNullOrEmpty(value) && SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING.equals(value)) {
return;
}
}
throw new InvalidSarlSpecificationException(agentClazz);
}

@Override
public synchronized UUID spawn(AgentContext parent, UUID agentID, Class<? extends Agent> agentClazz, Object... params) {
if (isRunning()) {
try {
JustInTimeAgentInjectionModule agentInjectionModule = new JustInTimeAgentInjectionModule(parent.getID(), agentID);
// Check if the version of the SARL agent class is compatible.
ensureSarlSpecificationVersion(agentClazz);

JustInTimeAgentInjectionModule agentInjectionModule = new JustInTimeAgentInjectionModule(
this.injector, agentClazz, parent.getID(), agentID);

Injector agentInjector = this.injector.createChildInjector(agentInjectionModule);
Agent agent = agentInjector.getInstance(agentClazz);
Agent agent = agentInjector.getInstance(Agent.class);
assert (agent != null);
this.agents.put(agent.getID(), agent);
fireAgentSpawned(parent, agent, params);
Expand Down Expand Up @@ -372,6 +392,27 @@ public SpawnServiceStopException(UUID agentID) {

}

/**
* This exception is thrown when the agent to spawn is not generated according to a valid SARL specification version.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
public static class InvalidSarlSpecificationException extends RuntimeException {

private static final long serialVersionUID = -3194494637438344108L;

/**
* @param agentType the invalid type of agent.
*/
public InvalidSarlSpecificationException(Class<? extends Agent> agentType) {
super(Locale.getString(StandardSpawnService.class, "INVALID_SARL_SPECIFICATION", agentType.getName())); //$NON-NLS-1$
}

}

/**
* This exception is thrown when an agent cannot be spawned.
*
Expand Down Expand Up @@ -404,22 +445,42 @@ public CannotSpawnException(Class<? extends Agent> agentClazz, Throwable cause)
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
private static class JustInTimeAgentInjectionModule extends AbstractModule {
private static class JustInTimeAgentInjectionModule extends AbstractModule implements Provider<Agent> {

private final Injector injector;

private final Class<? extends Agent> agentType;

private final UUID parentID;

private final UUID agentID;

JustInTimeAgentInjectionModule(UUID parentID, UUID agentID) {
JustInTimeAgentInjectionModule(Injector injector, Class<? extends Agent> agentType, UUID parentID, UUID agentID) {
assert (injector != null);
assert (agentType != null);
assert (parentID != null);
this.injector = injector;
this.agentType = agentType;
this.parentID = parentID;
this.agentID = (agentID == null) ? UUID.randomUUID() : agentID;
}

@Override
public void configure() {
bind(Key.get(UUID.class, Names.named(Agent.PARENT_ID_KEY_NAME))).toInstance(this.parentID);
bind(Key.get(UUID.class, Names.named(Agent.AGENT_ID_KEY_NAME))).toInstance(this.agentID);
bind(Agent.class).toProvider(this);
}

@Override
public Agent get() {
try {
BuiltinCapacitiesProvider capacityProvider = this.injector.getInstance(BuiltinCapacitiesProvider.class);
Constructor<? extends Agent> constructor = this.agentType.getConstructor(
BuiltinCapacitiesProvider.class, UUID.class, UUID.class);
return constructor.newInstance(capacityProvider, this.parentID, this.agentID);
} catch (NoSuchMethodException | SecurityException | InstantiationException
| IllegalAccessException | IllegalArgumentException | InvocationTargetException exception) {
throw new CannotSpawnException(this.agentType, exception);
}
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
CANNOT_INSTANCIATE_AGENT = Cannot instanciate an agent of type {0} due to: {1}
SPAWN_DISABLED = The spawning of the agents is disabled. The spawning of {1} inside {0} is skipped.
KILL_DISABLED = The killing service of agents is disabled. The killing of {0} is skipped.
INVALID_SARL_SPECIFICATION = The SARL specification version that was used for generating the type {0} is not compatible with the specification version supported by Janus.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
CANNOT_INSTANCIATE_AGENT = Impossible d''instancier un agent de type {0} à cause de: {1}
SPAWN_DISABLED = Le lancement d''agents est désactivé. Le lancement de {1} dans {0} est ignoré.
KILL_DISABLED = Le service d''arrêt des agents est désactivé. L''arrêt de {0} est ignoré.
INVALID_SARL_SPECIFICATION = La version de la spécification SARL utilisée pour générer le type {0} n''est pas compatible avec la version des spécifications supportée par Janus.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@
import org.mockito.MockitoAnnotations;

import io.sarl.core.DefaultContextInteractions;
import io.sarl.lang.SARLVersion;
import io.sarl.lang.annotation.SarlSpecification;
import io.sarl.lang.core.Agent;
import io.sarl.lang.core.BuiltinCapacitiesProvider;

Expand Down Expand Up @@ -113,6 +115,7 @@ protected static String[] args(String... strings) {
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@SarlSpecification(SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING)
protected static class AgentMock extends Agent {
/**
*/
Expand Down Expand Up @@ -1099,13 +1102,13 @@ public void randomContextUUID() throws Exception {
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@SarlSpecification(SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING)
public static class RCAgent extends TestingAgent {

@Inject
public RCAgent(
BuiltinCapacitiesProvider provider,
@Named(Agent.PARENT_ID_KEY_NAME) UUID parentID,
@Named(Agent.AGENT_ID_KEY_NAME) UUID agentID) {
UUID parentID,
UUID agentID) {
super(provider, parentID, agentID);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import org.junit.Test;

import io.sarl.core.Lifecycle;
import io.sarl.lang.SARLVersion;
import io.sarl.lang.annotation.SarlSpecification;
import io.sarl.lang.core.Agent;
import io.sarl.lang.core.BuiltinCapacitiesProvider;

Expand Down Expand Up @@ -71,13 +73,13 @@ public void killMeInInit() throws Exception {
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@SarlSpecification(SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING)
public static class KilledInInitAgent extends TestingAgent {

@Inject
public KilledInInitAgent(
BuiltinCapacitiesProvider provider,
@Named(Agent.PARENT_ID_KEY_NAME) UUID parentID,
@Named(Agent.AGENT_ID_KEY_NAME) UUID agentID) {
UUID parentID,
UUID agentID) {
super(provider, parentID, agentID);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import org.junit.Before;
import org.junit.Test;

import io.sarl.lang.SARLVersion;
import io.sarl.lang.annotation.SarlSpecification;
import io.sarl.lang.core.Agent;
import io.sarl.lang.core.BuiltinCapacitiesProvider;

Expand Down Expand Up @@ -69,13 +71,13 @@ public void ExceptionInInit() throws Exception {
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
@SarlSpecification(SARLVersion.SPECIFICATION_RELEASE_VERSION_STRING)
public static class ExceptionInInitAgent extends TestingAgent {

@Inject
public ExceptionInInitAgent(
BuiltinCapacitiesProvider provider,
@Named(Agent.PARENT_ID_KEY_NAME) UUID parentID,
@Named(Agent.AGENT_ID_KEY_NAME) UUID agentID) {
UUID parentID,
UUID agentID) {
super(provider, parentID, agentID);
}

Expand Down

0 comments on commit e9f944d

Please sign in to comment.