Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jadex.base.Starter Maven / Gradle / Ivy
Go to download
Jadex bridge is a base package for kernels and platforms, i.e., it is used by both and provides commonly used interfaces and classes for active components and their management.
package jadex.base;
import java.lang.reflect.Constructor;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
import java.util.logging.Logger;
import jadex.bridge.ComponentIdentifier;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.IExternalAccess;
import jadex.bridge.IInternalAccess;
import jadex.bridge.ILocalResourceIdentifier;
import jadex.bridge.LocalResourceIdentifier;
import jadex.bridge.ResourceIdentifier;
import jadex.bridge.ServiceCall;
import jadex.bridge.VersionInfo;
import jadex.bridge.component.ComponentCreationInfo;
import jadex.bridge.component.IArgumentsResultsFeature;
import jadex.bridge.component.IComponentFeatureFactory;
import jadex.bridge.component.IExecutionFeature;
import jadex.bridge.component.impl.ExecutionComponentFeature;
import jadex.bridge.component.impl.IInternalExecutionFeature;
import jadex.bridge.modelinfo.IModelInfo;
import jadex.bridge.service.IInternalService;
import jadex.bridge.service.IService;
import jadex.bridge.service.component.IInternalRequiredServicesFeature;
import jadex.bridge.service.component.IProvidedServicesFeature;
import jadex.bridge.service.component.IRequiredServicesFeature;
import jadex.bridge.service.component.interceptors.CallAccess;
import jadex.bridge.service.component.interceptors.MethodInvocationInterceptor;
import jadex.bridge.service.search.ServiceQuery;
import jadex.bridge.service.search.ServiceRegistry;
import jadex.bridge.service.types.address.ITransportAddressService;
import jadex.bridge.service.types.address.TransportAddress;
import jadex.bridge.service.types.clock.IClockService;
import jadex.bridge.service.types.cms.CMSComponentDescription;
import jadex.bridge.service.types.cms.CmsState;
import jadex.bridge.service.types.cms.CmsState.CmsComponentState;
import jadex.bridge.service.types.cms.CreationInfo;
import jadex.bridge.service.types.cms.IBootstrapFactory;
import jadex.bridge.service.types.cms.PlatformComponent;
import jadex.bridge.service.types.cms.SComponentManagementService;
import jadex.bridge.service.types.execution.IExecutionService;
import jadex.bridge.service.types.factory.IComponentFactory;
import jadex.bridge.service.types.factory.IPlatformComponentAccess;
import jadex.bridge.service.types.monitoring.IMonitoringService.PublishEventLevel;
import jadex.bridge.service.types.serialization.ISerializationServices;
import jadex.bridge.service.types.settings.IPlatformSettings;
import jadex.bridge.service.types.transport.ITransportService;
import jadex.bytecode.vmhacks.VmHacks;
import jadex.commons.SReflect;
import jadex.commons.SUtil;
import jadex.commons.Tuple2;
import jadex.commons.collection.BlockingQueue;
import jadex.commons.collection.IBlockingQueue;
import jadex.commons.collection.IRwMap;
import jadex.commons.collection.LRU;
import jadex.commons.collection.RwMapWrapper;
import jadex.commons.concurrent.IThreadPool;
import jadex.commons.concurrent.JavaThreadPool;
import jadex.commons.future.DelegationResultListener;
import jadex.commons.future.ExceptionDelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.FutureHelper;
import jadex.commons.future.IFuture;
import jadex.commons.future.IResultListener;
import jadex.commons.transformation.traverser.TransformSet;
import jadex.javaparser.SJavaParser;
/**
* Starter class for starting the Jadex platform.
*/
public class Starter
{
//-------- This is platform specific data kept in a common memory --------
//-------- Platform data keys --------
/** Flag if copying parameters for local service calls is allowed. */
public static String DATA_PARAMETERCOPY = IPlatformConfiguration.PARAMETERCOPY;
/** Flag if local timeouts should be realtime (instead of clock dependent). */
public static String DATA_REALTIMETIMEOUT = IPlatformConfiguration.REALTIMETIMEOUT;
/** The local service registry data key. */
public static String DATA_SERVICEREGISTRY = "serviceregistry";
/** The serialization services for serializing and en/decoding objects including remote reference handling. */
public static String DATA_SERIALIZATIONSERVICES = "serialservs";
/** The transport cache used to . */
public static String DATA_TRANSPORTCACHE = "transportcache";
/** The used to store the current network names. */
public static String DATA_NETWORKNAMESCACHE = "networknamescache";
/** The CMS state. */
public static String DATA_CMSSTATE = "cmsstate";
/** Constant for default timeout name. */
public static String DATA_DEFAULT_TIMEOUT = "default_timeout";
/** The bootstrap component factory. */
public static String DATA_PLATFORMACCESS = "$platformaccess";
/** The platform settings. */
public static String DATA_PLATFORMSETTINGS = "$platformsettings";
/** The bootstrap component factory. */
public static String DATA_BOOTSTRAPFACTORY = "$bootstrapfactory";
/** The weak set of invoked init, start or shutdown methods - to not invoke twice. */
public static String DATA_INVOKEDMETHODS = "INVOKEDMETHODS";
/** The cache of component models found by scanning available resources. */
public static String DATA_COMPONENTMODELS = "componentmodels";
public static String DATA_KERNELFILTERS = "kernelfilters";
// todo: cannot be used because registry needs to know when superpeer changes (remap queries)
// /** Constant for the superpeer. */
// public static String DATA_SUPERPEER = "superpeer";
/** Global platform data. For each platform stored by */
protected static final IRwMap> platformmem =
new RwMapWrapper>(new HashMap>());
// protected static final Map> platformmem = new HashMap>();
// /** The shutdown in progress flag. */
// protected static boolean shutdown;
//-------- static methods --------
// /**
// * Test if shutdown is in progress.
// */
// public static boolean isShutdown()
// {
// return shutdown;
// }
// Try adding startcom ssl certificate
// Does not work because 'cacerts' file cannot be written in Java home (privileges) :-(
//
// https://forum.startcom.org/viewtopic.php?f=15&t=1815&st=0&sk=t&sd=a&sid=90c5f7662b53041a50063813eb121d98&start=15
// manual addition:
// wget http://www.startssl.com/certs/ca.crt
// keytool -import -trustcacerts -alias startcom.ca -file ca.crt
// // wget http://www.startssl.com/certs/sub.class1.server.ca.crt
// // keytool -import -alias startcom.ca.sub -file sub.class1.server.ca.crt
static
{
// set secure random to non-blocking entropy source
SUtil.ensureNonblockingSecureRandom();
// try
// {
// Class> cl = SReflect.findClass0("jadex.platform.service.security.SSecurity", null, null);
// if(cl!=null)
// {
// Method m = cl.getMethod("addStartSSLToTrustStore", new Class[]{String.class});
// m.invoke(null, new Object[]{"changeit"});
// System.out.println("Startssl certificate is installed in truststore.");
// }
// }
// catch(Exception e)
// {
// System.out.println("Error adding startssl certificate to truststore: "+e.getMessage());
// }
}
/**
* Unescape a string.
*/
protected static String unescape(String str)
{
StringBuffer buf = new StringBuffer(str);
int idx = buf.indexOf("\\");
while(idx!=-1 && buf.length()>idx+1)
{
if(buf.charAt(idx+1)=='b')
{
buf.replace(idx, idx+2, "\b");
}
else if(buf.charAt(idx+1)=='t')
{
buf.replace(idx, idx+2, "\t");
}
else if(buf.charAt(idx+1)=='n')
{
buf.replace(idx, idx+2, "\n");
}
else if(buf.charAt(idx+1)=='f')
{
buf.replace(idx, idx+2, "\f");
}
else if(buf.charAt(idx+1)=='r')
{
buf.replace(idx, idx+2, "\r");
}
else if(buf.charAt(idx+1)=='"')
{
buf.replace(idx, idx+2, "\"");
}
else if(buf.charAt(idx+1)=='\'')
{
buf.replace(idx, idx+2, "'");
}
else if(buf.charAt(idx+1)=='\\')
{
buf.replace(idx, idx+2, "\\");
}
idx = buf.indexOf("\\", idx+1);
}
// Todo: escape octal codes.
return buf.toString();
}
/**
* Main for starting the platform (with meaningful fallbacks)
* @param args The arguments.
* @throws Exception
*/
public static void main(String[] args)
{
// try
// {
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// }
// catch(Exception e)
// {
// e.printStackTrace();
// }
createPlatform(args).get();
// .scheduleStep(new IComponentStep()
// {
// public IFuture execute(IInternalAccess ia)
// {
// String remoteaddr = "tcp-mtp://"+"ec2-54-190-58-166.us-west-2.compute.amazonaws.com"+":36000";
// String platformname = "Allie-Jadex_720F614FB6ED061A";
// IComponentIdentifier remotecid = new ComponentIdentifier(platformname, new String[]{remoteaddr});
//
// // Create proxy for remote platform such that remote services are found
// Map args = new HashMap();
// args.put("component", remotecid);
// CreationInfo ci = new CreationInfo(args);
// ci.setDaemon(true);
// IComponentManagementService cms = ia.getComponentFeature(IRequiredServicesFeature.class).getLocalService(new ServiceQuery<>( IComponentManagementService.class, ServiceScope.PLATFORM));
// cms.createComponent(platformname, "jadex/platform/service/remote/ProxyAgent.class", ci).getFirstResult();
// return IFuture.DONE;
// }
// });
// IExternalAccess access = createPlatform(args).get();
// Runtime.getRuntime().addShutdownHook(new Thread()
// {
// public void run()
// {
// try
// {
//// System.out.println("killing: "+access.getComponentIdentifier().getPlatformName());
// shutdown = true;
// access.killComponent().get(new ThreadSuspendable(), TERMINATION_TIMEOUT);
//// System.out.println("killed: "+access.getComponentIdentifier().getPlatformName());
// }
// catch(ComponentTerminatedException cte)
// {
// // Already killed.
// }
// catch(Throwable t)
// {
// t.printStackTrace();
// }
// }
// });
// // Continuously run garbage collector and finalizers.
// Timer gctimer = new Timer();
// gctimer.scheduleAtFixedRate(new TimerTask()
// {
// public void run()
// {
// System.gc();
// System.runFinalization();
// }
// }, 1000, 1000);
// Test CTRL-C shutdown behavior.
// Timer timer = new Timer();
// timer.schedule(new TimerTask()
// {
// public void run()
// {
// System.out.println(getClass().getName()+": Calling System.exit() for testing.");
// System.exit(0);
// }
// }, 5000);
}
/**
* Create the platform.
* @param args The command line arguments.
* @return The external access of the root component.
*/
public static IFuture createPlatform(Map args)
{
return createPlatform(null, (Map)args);
}
/**
* Create the platform.
* @param args The command line arguments.
* @return The external access of the root component.
*/
public static IFuture createPlatform(String... args)
{
return createPlatform(null, parseArgs(args));
}
/**
* Create the platform.
* @return The external access of the root component.
*/
public static IFuture createPlatform(IPlatformConfiguration config)
{
return createPlatform(config, (Map)null);
}
/**
* Create the platform.
* @return The external access of the root component.
*/
public static IFuture createPlatform()
{
return createPlatform(null, (Map)null);
}
/**
* Create the platform.
* @param config The PlatformConfiguration object.
* @return The external access of the root component.
*/
public static IFuture createPlatform(IPlatformConfiguration pconfig, String... args)
{
return createPlatform(pconfig, parseArgs(args));
}
/**
* Get a boolean value from args (otherwise return default value passed as arg).
* Any non-boolean, non-null value (e.g. a string) is also considered 'true'.
* @param args The args map.
* @param argname The argument name.
* @param conf The platform config.
* @return The arg value.
*/
public static boolean getBooleanValueWithArgs(Map args, String argname, IPlatformConfiguration conf)
{
Object val = null;
if(args!=null)
{
val = args.get(argname);
}
if(val==null)
{
val = conf.getValue(argname, null);
if(val instanceof String)
{
try
{
val = SJavaParser.evaluateExpression((String)val, null);
}
catch(Exception e)
{
// System.out.println("Argument parse exception using as string: " + argname + " \"" + val + "\"");
}
}
}
return val instanceof Boolean ? (Boolean)val : val!=null;
}
/**
* Create the platform.
* @param config The PlatformConfiguration object.
* @return The external access of the root component.
*/
public static IFuture createPlatform(final IPlatformConfiguration pconfig, Map pargs)
{
// When already on other component's thread -> run new platform component init on extra executor to avoid conflicts (i.e. which local cid is correct!?)
if(IInternalExecutionFeature.LOCAL.get()!=null)
{
// TODO: service call for platform creation used anywhere?
ServiceCall sc = CallAccess.getCurrentInvocation();
ServiceCall scn = CallAccess.getNextInvocation();
Future ret = new Future();
getExecutionService(IInternalExecutionFeature.LOCAL.get()).execute(() ->
{
CallAccess.setCurrentInvocation(sc);
CallAccess.setNextInvocation(scn);
createPlatform(pconfig, pargs).addResultListener(new DelegationResultListener(ret));
return false;
});
return ret;
}
// Make all argument keys lower case.
final Map args = pargs != null ? new HashMap<>() : null;
if (args != null)
{
for (Map.Entry entry : pargs.entrySet())
args.put(entry.getKey() != null ? entry.getKey().toLowerCase() : null, entry.getValue());
}
// System.out.println("Java Version: " + System.getProperty("java.version"));
final IPlatformConfiguration config = pconfig!=null? pconfig: PlatformConfigurationHandler.getDefault();
// Once a config is used to create a platform it must not be altered (performance optimization to avoid unnecessary copying of configs).
PlatformConfigurationHandler.makeImmutable(config);
if(config.getExtendedPlatformConfiguration().isDropPrivileges())
VmHacks.get().tryChangeUser(null);
// IRootComponentConfiguration rootconf = config.getRootConfig();
// pass configuration parameters to static fields:
MethodInvocationInterceptor.DEBUG = getBooleanValueWithArgs(args, "debugservices", config);
ExecutionComponentFeature.DEBUG = getBooleanValueWithArgs(args, "debugsteps", config);
Future.NO_STACK_COMPACTION = getBooleanValueWithArgs(args, "nostackcompaction", config);
// Future.NO_STACK_COMPACTION = true;
Future.DEBUG = getBooleanValueWithArgs(args, "debugfutures", config);
// new FastClasspathScanner(new String[]
// {"com.xyz.widget", "com.xyz.gizmo" }) // Whitelisted package prefixes
// .matchSubclassesOf(DBModel.class,
// // c is a subclass of DBModel
// c -> System.out.println("Found subclass of DBModel: " + c.getName()))
// .matchClassesImplementing(Runnable.class,
// // c is a class that implements Runnable
// c -> System.out.println("Found Runnable: " + c.getName()))
// .matchClassesWithAnnotation(RestHandler.class,
// // c is a class annotated with @RestHandler
// c -> System.out.println("Found RestHandler annotation on class: "
// + c.getName()))
// .matchFilenamePattern("^template/.*\\.html",
// // templatePath is a path on the classpath that matches the above pattern;
// // inputStream is a stream opened on the file or zipfile entry.
// // No need to close inputStream before exiting, it is closed by caller.
// (templatePath, inputStream) -> {
// try {
// String template = IOUtils.toString(inputStream, "UTF-8");
// System.out.println("Found template: " + absolutePath
// + " (size " + template.length() + ")");
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// })
// .scan();
// final Object args, final Map cmdargs, final Map compargs, final List components
// Fix below doesn't work. WLAN address is missing :-(
// // ANDROID: Selector.open() causes an exception in a 2.2
// // emulator due to IPv6 addresses, see:
// // http://code.google.com/p/android/issues/detail?id=9431
// // Also fixes Java bug on windows 7 regarding network prefix:
// // http://bugs.sun.com/view_bug.do?bug_id=6707289
// java.lang.System.setProperty("java.net.preferIPv4Stack", "true");
// java.lang.System.setProperty("java.net.preferIPv6Addresses", "false");
// System.out.println("Arguments: "+args.length/2+" "+SUtil.arrayToString(args));
Future ret = new Future();
final Future fret = ret;
try
{
// Absolute start time (for testing and benchmarking).
final long starttime = System.currentTimeMillis();
// Load the platform (component) model.
final ClassLoader cl = Starter.class.getClassLoader();
final String configfile = config.getExtendedPlatformConfiguration().getConfigurationFile();
String cfclname = config.getExtendedPlatformConfiguration().getComponentFactory();
Class> cfclass = SReflect.classForName(cfclname, cl);
// The providerid for this service is not important as it will be thrown away
// after loading the first component model.
final IComponentFactory cfac = (IComponentFactory)cfclass.getConstructor(new Class[]{String.class})
.newInstance(new Object[]{"rootid"});
// Hack: what to use as rid? should not have dependency to standalone.
// final ResourceIdentifier rid = new ResourceIdentifier(null,
// "org.activecomponents.jadex:jadex-standalone-launch:2.1");
// System.out.println("Using config file: "+configfile);
final IModelInfo model = cfac.loadModel(configfile, null, null, null).get(); // No execution yet, can only work if method is synchronous.
if(model.getReport()!=null)
{
ret.setException(new RuntimeException("Error loading model:\n"+model.getReport().getErrorText()));
}
else
{
// config.checkConsistency(); // todo?
// ClassInfo ci = config.getExtendedPlatformConfiguration().getPlatformComponent();
// Class> pc = ci.getType(cl);
// Object pc = config.getValue(RootComponentConfiguration.PLATFORM_COMPONENT);
// rootConfig.setValue(RootComponentConfiguration.PLATFORM_COMPONENT, pc);
// if(pc==null)
// {
// ret.setException(new RuntimeException("No platform component class found."));
// }
// else
// {
// Build platform name.
String pfname = args!=null && args.containsKey(IPlatformConfiguration.PLATFORM_NAME)? (String)args.get(IPlatformConfiguration.PLATFORM_NAME): config.getPlatformName();
// Object pfname = config.getValue(RootComponentConfiguration.PLATFORM_NAME);
// rootConfig.setValue(RootComponentConfiguration.PLATFORM_NAME, pfname);
final IComponentIdentifier cid = createPlatformIdentifier(pfname!=null? pfname: null,
Boolean.TRUE.equals(config.getValue("uniquename", model)));
assert IComponentIdentifier.LOCAL.get()==null;
IComponentIdentifier.LOCAL.set(cid);
boolean readonlysettings = Boolean.TRUE.equals(config.getValue("settings.readonly", model))
|| args!=null && Boolean.TRUE.equals(args.get("settings.readonly"));
IPlatformSettings settings = (IPlatformSettings) SReflect.newInstance("jadex.platform.service.settings.PlatformSettings", cid, readonlysettings);
putPlatformValue(cid, DATA_PLATFORMSETTINGS, settings);
// Check if platform with same name exists in VM
if(getPlatformValue(cid, DATA_PLATFORMACCESS)!=null)
{
ret.setException(new IllegalArgumentException("Platform already exists: "+cid));
return ret;
}
// Class> pcclass = pc instanceof Class ? (Class>)pc : SReflect.classForName(pc.toString(), cl);
// final IPlatformComponentAccess component = (IPlatformComponentAccess)pcclass.newInstance();
final IPlatformComponentAccess component = SComponentManagementService.createPlatformComponent(cl);
// CmsComponentState compstate = new CmsComponentState();
// ((CmsState) getPlatformValue(cid, DATA_CMSSTATE)).getComponentMap().put(cid, compstate);
// rootconf.setPlatformAccess(component);
putPlatformValue(cid, DATA_PLATFORMACCESS, component);
putPlatformValue(cid, DATA_BOOTSTRAPFACTORY, cfac);
// putPlatformValue(cid, IPlatformConfiguration.PLATFORMARGS, args);
putPlatformValue(cid, IPlatformConfiguration.PLATFORMCONFIG, config);
putPlatformValue(cid, IPlatformConfiguration.PLATFORMMODEL, model);
putPlatformValue(cid, DATA_CMSSTATE, new CmsState());
CmsComponentState compstate = new CmsComponentState();
compstate.setAccess(component);
((CmsState) getPlatformValue(cid, DATA_CMSSTATE)).getComponentMap().put(cid, compstate);
putPlatformValue(cid, DATA_INVOKEDMETHODS, Collections.synchronizedMap(new WeakHashMap>()));
// does not work as create with subscomponents is recursive
// /** The sequentializer to execute getNewFactory() one by one and not interleaved. */
// CallSequentializer cmscaller = new CallSequentializer();
// cmscaller.addCommand("create", new IResultCommand, Object[]>()
// {
// public IFuture execute(Object[] args)
// {
//// SComponentManagementService.createComponent(oname, modelname, info, resultlistener, agent)
// return (IFuture)SComponentManagementService.createComponentInternal((String)args[0], (String)args[1], (CreationInfo)args[2], (IResultListener>>)args[3], (IInternalAccess)args[4]);
// }
// });
// cmscaller.addCommand("kill", new IResultCommand, Object[]>()
// {
// public IFuture execute(Object[] args)
// {
//// SComponentManagementService.createComponent(oname, modelname, info, resultlistener, agent)
// return (IFuture)SComponentManagementService.destroyComponentInternal((IComponentIdentifier)args[0], (IInternalAccess)args[1]);
// }
// });
// putPlatformValue(cid, DATA_CMSSEQ, cmscaller);
// rootconf.setBootstrapFactory(cfac);
// config.setPlatformModel(model);
// Perform manual switch to allow users specify next call properties
ServiceCall sc = CallAccess.getCurrentInvocation();
ServiceCall scn = CallAccess.getNextInvocation();
if(sc==null)
{
if(scn==null)
{
scn = CallAccess.getOrCreateNextInvocation();
}
// if(scn.getCause()==null)
// {
// scn.setCause(new Cause((String)null, "createPlatform"));
// }
CallAccess.setCurrentInvocation(scn);
sc = scn;
}
// Hack: change rid afterwards?!
ResourceIdentifier rid = (ResourceIdentifier)model.getResourceIdentifier();
ILocalResourceIdentifier lid = rid.getLocalIdentifier();
rid.setLocalIdentifier(new LocalResourceIdentifier(cid, lid.getUri()));
String ctype = cfac.getComponentType(configfile, null, model.getResourceIdentifier()).get();
IComponentIdentifier caller = sc==null? null: sc.getCaller();
// Cause cause = sc==null? null: sc.getCause();
// assert cause!=null;
// Boolean autosd = config.getExtendedPlatformConfiguration().getAutoShutdown();
// Boolean autosd = (Boolean)config.getValue(RootComponentConfiguration.AUTOSHUTDOWN);
// rootConfig.setValue(RootComponentConfiguration.AUTOSHUTDOWN, autosd);
PublishEventLevel monitoring = config.getExtendedPlatformConfiguration().getMonitoring();
// final CMSComponentDescription desc = new CMSComponentDescription(cid, ctype, false, false,
// autosd!=null ? autosd.booleanValue() : false, false, false, monitoring, model.getFullName(),
// null, model.getResourceIdentifier(), System.currentTimeMillis(), caller, false);
final CMSComponentDescription desc = new CMSComponentDescription(cid).setType(ctype).setModelName(model.getFullName())
.setResourceIdentifier(model.getResourceIdentifier()).setCreationTime(System.currentTimeMillis()).setCreator(caller)
.setMonitoring(monitoring).setFilename(model.getFilename()).setSystemComponent(SComponentManagementService.isSystemComponent(model, null, null));
putPlatformValue(cid, DATA_REALTIMETIMEOUT, config.getValue(DATA_REALTIMETIMEOUT, model));
// rootConfig.setValue(PlatformConfiguration.DATA_REALTIMETIMEOUT, config.getValue(PlatformConfiguration.DATA_REALTIMETIMEOUT));
putPlatformValue(cid, DATA_PARAMETERCOPY, config.getValue(DATA_PARAMETERCOPY, model));
// rootConfig.setValue(PlatformConfiguration.DATA_PARAMETERCOPY, config.getValue(PlatformConfiguration.DATA_PARAMETERCOPY));
putPlatformValue(cid, DATA_NETWORKNAMESCACHE, new TransformSet());
putPlatformValue(cid, DATA_SERVICEREGISTRY, new ServiceRegistry());
try
{
Class> serialservclass = Class.forName("jadex.platform.service.serialization.SerializationServices", true, cl);
ISerializationServices servs = (ISerializationServices)serialservclass.getConstructor(IComponentIdentifier.class).newInstance(cid);
putPlatformValue(cid, DATA_SERIALIZATIONSERVICES, servs);
}
catch (Exception e)
{
e.printStackTrace();
}
putPlatformValue(cid, DATA_TRANSPORTCACHE, Collections.synchronizedMap(new LRU>(2000)));
putPlatformValue(cid, DATA_DEFAULT_TIMEOUT, config.getDefaultTimeout());
Map argsmap = config==null? new HashMap(): config.getValues();
if(args!=null)
{
for(Map.Entry arg: args.entrySet())
{
argsmap.put(arg.getKey(), arg.getValue());
}
// Must not use putAll() here because special map overrides put() to add also namemapped entries
// argsmap.putAll(args);
}
putPlatformValue(cid, IPlatformConfiguration.PLATFORMARGS, argsmap);
ComponentCreationInfo cci = new ComponentCreationInfo(model, config.getConfigurationName(), argsmap, desc, null, null);
Collection features = cfac.getComponentFeatures(model, null).get(); // no pojo in config possible?!
component.create(cci, features);
// Required for bootstrapping init.
IInternalExecutionFeature exe = (IInternalExecutionFeature)component.getInternalAccess().getFeature(IExecutionFeature.class);
exe.setManual(true);
IBootstrapFactory fac = (IBootstrapFactory)SComponentManagementService.getComponentFactory(cid);
// Empty init can be overridden by users
if(config.getInitCommand()!=null)
config.getInitCommand().execute(cid);
fac.startService(component.getInternalAccess(), rid).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(Void result)
{
// SComponentManagementService.removeInitInfo(cid);
// CmsComponentState compstate = new CmsComponentState();
// ((CmsState) getPlatformValue(cid, DATA_CMSSTATE)).getComponentMap().put(cid, compstate);
// compstate.setAccess(component);
// SComponentManagementService.getComponents(cid).put(cid, component);
component.init().addResultListener(new ExceptionDelegationResultListener(fret)
{
public void customResultAvailable(Void result)
{
@SuppressWarnings("rawtypes")
List comps = config.getComponents();
if(args!=null && args.containsKey("component"))
{
comps = (List>)args.get("component");
if(config.getComponents()!=null)
{
comps.addAll((List>)config.getComponents());
}
}
IFuture fut = startComponents(0, comps, component.getInternalAccess());
fut.addResultListener(new ExceptionDelegationResultListener(fret)
{
public void customResultAvailable(Void result)
{
if(Boolean.TRUE.equals(config.getValue(IPlatformConfiguration.WELCOME, model)))
{
long startup = System.currentTimeMillis() - starttime;
// platform.logger.info("Platform startup time: " + startup + " ms.");
System.out.println(VersionInfo.getInstance().toString()+'\n'+desc.getName()+" platform startup time: " + startup + " ms.");
// System.out.println(desc.getName()+" platform startup time: " + "799 ms.");
}
fret.setResult(component.getInternalAccess().getExternalAccess());
}
public void exceptionOccurred(Exception exception)
{
// On exception in init: kill platform.
component.getInternalAccess().getExternalAccess().killComponent();
super.exceptionOccurred(exception);
}
});
}
});
}
});
// Manually bootstrap platform execution until execution service is available
boolean inited = false;
boolean execute = true;
IProvidedServicesFeature prov = component.getInternalAccess().getFeature(IProvidedServicesFeature.class);
while(execute && !inited)
{
execute = exe.execute();
inited = prov.getProvidedService(IExecutionService.class)!=null
&& ((IService)prov.getProvidedService(IExecutionService.class)).isValid().get().booleanValue();
}
if(!inited)
{
// execution stopped before init complete!?
throw new IllegalStateException("Boostrapping failed: "+component.getInternalAccess());
}
// Rare case when createPlatform called from non-component future listener notification
// Run scheduled init steps before starting platform executor to avoid parallel execution
FutureHelper.notifyStackedListeners();
// End bootstrapping and kick of platform executor
exe.setManual(false);
// Rescue thread is shared by all components of platform and used e.g.
// for component termination listener notification after component executor is already stopped
initRescueThread(cid, config);
exe.wakeup();
}
// System.out.println("Model: "+model);
}
catch(Exception e)
{
// e.printStackTrace();
if(!ret.setExceptionIfUndone(e))
{
ret = new Future(e);
}
}
if(config.isPrintExceptions())
{
ret.addResultListener(new IResultListener()
{
public void exceptionOccurred(Exception exception)
{
System.out.println(exception.getMessage());
if(Future.DEBUG)
exception.printStackTrace();
}
public void resultAvailable(IExternalAccess result)
{
}
});
}
return ret;
}
/** Counters for generating unique names of platforms. */
protected static Map UNIQUENAMES = new HashMap<>();
/**
* Internal method to create a component identifier.
* @param pfname The platform name.
* @param unique When true, keeps track of already created names and creates a name that is unique in this VM.
*/
public static IComponentIdentifier createPlatformIdentifier(String pfname, boolean unique)
{
// Build platform name.
String platformname = null;
if(pfname==null)
{
try
{
platformname = InetAddress.getLocalHost().getHostName();
platformname += "_*";
}
catch(UnknownHostException e)
{
}
}
else
{
platformname = pfname.toString();
}
// Replace special characters used in component ids.
if(platformname!=null)
{
platformname = platformname.replace(':', '$'); // Dot in host name on Mac !?
platformname = platformname.replace('@', '$');
}
else
{
platformname = "platform_*";
}
if(unique)
{
Integer num;
synchronized(UNIQUENAMES)
{
num = UNIQUENAMES.get(platformname);
if(num==null)
{
num = 0;
}
else
{
num++;
}
UNIQUENAMES.put(platformname, num);
}
platformname += "_$"+num;
}
else
{
Random rnd = new Random();
StringBuffer buf = new StringBuffer();
StringTokenizer stok = new StringTokenizer(platformname, "*+", true);
while(stok.hasMoreTokens())
{
String tok = stok.nextToken();
if(tok.equals("+"))
{
buf.append(Integer.toString(rnd.nextInt(36), 36));
}
else if(tok.equals("*"))
{
buf.append(Integer.toString(rnd.nextInt(36), 36));
buf.append(Integer.toString(rnd.nextInt(36), 36));
buf.append(Integer.toString(rnd.nextInt(36), 36));
}
else
{
buf.append(tok);
}
}
platformname = SUtil.intern(buf.toString());
}
// Create an instance of the component.
return new ComponentIdentifier(platformname).getRoot();
}
/**
* Loop for starting components.
* @param i Number to start.
* @param components The list of components.
* @param instance The instance.
* @return True, when done.
*/
protected static IFuture startComponents(final int i, final List components, final IInternalAccess instance)
{
final Future ret = new Future();
if(components!=null && i oargs = null;
// check if name:type are both present (to not find last : check that no ( before)
int i1 = comp.indexOf(':');
int i11 = comp.indexOf('(');
if(i1!=-1 && (i11==-1 || i11>i1))
{
name = comp.substring(0, i1);
comp = comp.substring(i1+1);
}
// check if (config:args) part is present
int i2 = comp.indexOf('(');
if(i2!=-1)
{
// must end with )
// must have : if both are presents otherwise all is configname
if(!comp.endsWith(")"))
{
throw new RuntimeException("Component specification does not match scheme [:][([:])] : "+components.get(i));
}
int i3 = comp.indexOf(":");
if(i3!=-1)
{
if(comp.length()-i3>1)
args = comp.substring(i3+1, comp.length()-1);
if(i3-i2>1)
config = comp.substring(i2+1, i3-1);
}
else
{
config = comp.substring(i2+1, comp.length()-1);
}
comp = comp.substring(0, i2);
}
// System.out.println("comp: "+comp+" config: "+config+" args: "+args);
if(args!=null)
{
try
{
// args = args.replace("\\\"", "\"");
Object o = SJavaParser.evaluateExpression(args, null);
if(!(o instanceof Map))
{
throw new RuntimeException("Arguments must evaluate to Map"+args);
}
oargs = (Map)o;
}
catch(Exception e)
{
// System.out.println("args: "+args);
// e.printStackTrace();
throw new RuntimeException("Arguments evaluation error: "+e);
}
}
CreationInfo ci = new CreationInfo(config, oargs);
ci.setName(name);
ci.setFilename(comp);
instance.createComponent(ci)
.addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IExternalAccess result)
{
startComponents(i+1, components, instance)
.addResultListener(new DelegationResultListener(ret));
}
});
// cms.createComponent(name, comp, new CreationInfo(config, oargs), null)
// .addResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(IComponentIdentifier result)
// {
// startComponents(i+1, components, instance)
// .addResultListener(new DelegationResultListener(ret));
// }
// });
}
else
{
ret.setResult(null);
}
return ret;
}
/** The rescue threads - per platform. */
protected static Map> rescuethreads;
/**
* Init the rescue thread for a platform..
*/
public synchronized static void initRescueThread(IComponentIdentifier cid, IPlatformConfiguration rootconfig)
{
IThreadPool tp = null;
if(rootconfig.getExtendedPlatformConfiguration().getThreadpoolClass()!=null)
{
try
{
tp = (IThreadPool)SReflect.classForName(
rootconfig.getExtendedPlatformConfiguration().getThreadpoolClass(), Starter.class.getClassLoader()).getConstructor().newInstance();
}
catch(Exception e)
{
e.printStackTrace();
}
}
assert cid.getParent()==null;
if(rescuethreads==null)
rescuethreads = new HashMap>();
final BlockingQueue bq = new BlockingQueue();
final IComponentIdentifier fcid = cid;
Runnable run = new Runnable()
{
public void run()
{
try
{
while(true)
{
Runnable next = (Runnable)bq.dequeue();
try
{
next.run();
}
catch(Throwable t)
{
Logger.getLogger(fcid.getLocalName()).severe("Exception during step on rescue thread: "+SUtil.getExceptionStacktrace(t));
}
}
}
catch(IBlockingQueue.ClosedException bqce)
{
}
}
};
if(tp!=null)
{
tp.execute(run);
}
else
{
Thread rescuethread = new Thread(run, "rescue_thread_"+cid.getName());
Tuple2 tup = new Tuple2(bq, rescuethread);
rescuethreads.put(cid, tup);
// rescue thread must not be daemon, otherwise shutdown code like writing platform settings might be interrupted by vm exit.
// rescuethread.setDaemon(true);
rescuethread.start();
}
}
/**
* Schedule a rescue step.
* @param cid The id of a component of the platform.
* @param run The runnable to execute.
*/
public synchronized static void scheduleRescueStep(IComponentIdentifier cid, Runnable run)
{
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
// System.out.println("rescue step for "+cid+" called from "+ste[2]);
Tuple2 tup = rescuethreads!=null ? rescuethreads.get(cid.getRoot()) : null;
if(tup!=null)
{
tup.getFirstEntity().enqueue(run);
}
else
{
// Rescue thread after platform shutdown -> just execute
run.run();
}
}
/**
* Test if the current thread is the rescue thread of the platform.
* @param cid The id of a component of the platform.
* @return True, if is the rescue thread.
*/
public static synchronized boolean isRescueThread(IComponentIdentifier cid)
{
boolean ret = false;
Tuple2 tup = rescuethreads==null? null: rescuethreads.get(cid.getRoot());
if(tup!=null)
{
ret = Thread.currentThread().equals(tup.getSecondEntity());
}
return ret;
}
/**
* Shutdown the rescue thread of a platform.
*/
public static synchronized void shutdownRescueThread(IComponentIdentifier cid)
{
assert cid.getParent()==null : cid;
Tuple2 tup = rescuethreads==null? null: rescuethreads.remove(cid.getRoot());
if(tup!=null)
{
List steps = tup.getFirstEntity().setClosed(true);
for(Runnable next: steps)
{
try
{
next.run();
}
catch(Exception e)
{
Logger.getLogger(cid.getLocalName()).severe("Exception during step on rescue thread: "+SUtil.getExceptionStacktrace(e));
}
}
}
}
/**
* Create a proxy for the remote platform.
*/
public static IFuture createProxy(final IExternalAccess local, final IExternalAccess remote)
{
final Future ret = new Future();
remote.searchService( new ServiceQuery<>(ITransportAddressService.class)).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(ITransportAddressService remotetas) throws Exception
{
remotetas.getAddresses().addResultListener(new ExceptionDelegationResultListener, IExternalAccess>(ret)
{
public void customResultAvailable(final List remoteaddrs) throws Exception
{
local.searchService( new ServiceQuery<>(ITransportAddressService.class)).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(ITransportAddressService localtas) throws Exception
{
localtas.addManualAddresses(remoteaddrs).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(Void result) throws Exception
{
Map args = new HashMap();
args.put("component", remote.getId().getRoot());
CreationInfo ci = new CreationInfo(args);
local.createComponent(ci.setFilename("\"jadex/platform/service/remote/ProxyAgent.class\"")).addResultListener(new DelegationResultListener(ret));
// local.searchService( new ServiceQuery<>(IComponentManagementService.class))
// .addResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(final IComponentManagementService localcms)
// {
// Map args = new HashMap();
// args.put("component", remote.getId().getRoot());
// CreationInfo ci = new CreationInfo(args);
// localcms.createComponent(null, "jadex/platform/service/remote/ProxyAgent.class", ci, null).addResultListener(new DelegationResultListener(ret));
// }
// });
}
});
}
});
}
});
}
});
/*remote.searchService( new ServiceQuery<>( ITransportAddressService.class, ServiceScope.PLATFORM)).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(ITransportAddressService remotetas) throws Exception
{
remotetas.getAddresses().addResultListener(new ExceptionDelegationResultListener, IComponentIdentifier>(ret)
{
public void customResultAvailable(final List remoteaddrs) throws Exception
{
local.searchService( new ServiceQuery<>( ITransportAddressService.class, ServiceScope.PLATFORM)).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(ITransportAddressService localtas) throws Exception
{
localtas.addManualAddresses(remoteaddrs).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(Void result) throws Exception
{
local.searchService( new ServiceQuery<>( IComponentManagementService.class, ServiceScope.PLATFORM))
.addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(final IComponentManagementService localcms)
{
Map args = new HashMap();
args.put("component", remote.getComponentIdentifier().getRoot());
CreationInfo ci = new CreationInfo(args);
localcms.createComponent(null, "jadex/platform/service/remote/ProxyAgent.class", ci, null).addResultListener(new DelegationResultListener(ret));
}
});
}
});
}
});
}
});
}
});*/
// Add remote addresses to local address book
// TransportAddressBook tab1 = TransportAddressBook.getAddressBook(local.getComponentIdentifier());
// TransportAddressBook tab2 = TransportAddressBook.getAddressBook(remote.getComponentIdentifier());
// tab1.addPlatformAddresses(remote.getComponentIdentifier(), "tcp",
// tab2.getPlatformAddresses(remote.getComponentIdentifier(), "tcp"));
// System.out.println("adresses from "+agent+" to "+exta+": "+tab2.getPlatformAddresses(exta.getComponentIdentifier(), "tcp"));
return ret;
}
/**
* Get a global platform value.
*
* @param platform The platform name.
* @param key The key.
* @return The value.
*/
public static Object getPlatformValue(IComponentIdentifier platform, String key)
{
//System.out.println("getPV: "+platform.getRoot()+" "+key);
Object ret = null;
IRwMap mem = platformmem.get(platform.getRoot());
if(mem != null)
ret = mem.get(key);
return ret;
}
/**
* Get a platform argument, i.e. global Jadex setting value as defined by arguments of jadex.platform.PlatformAgent.
*
* @param platform An id of any component on the platform.
* @param arg The argument name.
* @return The value.
*/
public static Object getPlatformArgument(IComponentIdentifier cid, String arg)
{
IPlatformComponentAccess platform = (IPlatformComponentAccess)getPlatformValue(cid, DATA_PLATFORMACCESS);
return platform.getInternalAccess().getArgument(arg);
}
/**
* Get a global platform value.
*
* @param platform The platform name.
* @param key The key.
* @param value The value.
*/
public static void putPlatformValue(IComponentIdentifier platform, String key, Object value)
{
IRwMap mem = platformmem.get(platform.getRoot());
if(mem == null)
{
platformmem.getWriteLock().lock();
mem = platformmem.get(platform.getRoot());
if (mem == null)
{
mem = new RwMapWrapper(new HashMap());
platformmem.put(platform, mem);
}
platformmem.getWriteLock().unlock();
}
mem.put(key, value);
}
/**
* Get a global platform value.
*
* @param platform The platform name.
* @param key The key.
* @return The value.
*/
public static boolean hasPlatformValue(IComponentIdentifier platform, String key)
{
boolean ret = false;
Map mem = platformmem.get(platform.getRoot());
if(mem != null)
ret = mem.containsKey(key);
return ret;
}
/**
* Get a global platform value.
*
* @param platform The platform name.
*/
public static void removePlatformMemory(IComponentIdentifier platform)
{
platformmem.remove(platform.getRoot());
}
public static final IPlatformSettings getPlatformSettings(IComponentIdentifier platform)
{
return (IPlatformSettings) getPlatformValue(platform, DATA_PLATFORMSETTINGS);
}
/**
* Get the default timeout.
*/
public static long getDefaultTimeout(IComponentIdentifier platform)
{
Long platform_timeout = platform!=null ? (Long)getPlatformValue(platform, DATA_DEFAULT_TIMEOUT) : null;
return platform_timeout!=null
? platform_timeout.longValue()
: SUtil.DEFTIMEOUT;
}
/**
* Get the scaled default timeout.
*/
public static long getScaledDefaultTimeout(IComponentIdentifier platform, double scale)
{
long ret = getDefaultTimeout(platform);
return ret == -1 ? -1 : (long)(ret * scale);
}
/**
* Set the default timeout.
*/
public static void setDefaultTimeout(IComponentIdentifier platform, long timeout)
{
putPlatformValue(platform, DATA_DEFAULT_TIMEOUT, timeout);
}
/**
* Check if the real time / non-real time timeout flag is set for a platform.
* By default some timeouts are real time (e.g. network communication) and others are clock dependent (e.g. agent.waitFor...).
* The "realtimetimeout" platform setting (default=null) allows forcing all timeouts to real time (true) or clock dependent (false).
* @param cid Use platform setting of the given component.
* @param def The default value to be returned when flag is null in platform config.
*/
public static boolean isRealtimeTimeout(IComponentIdentifier cid, boolean def)
{
Object val = getPlatformValue(cid, DATA_REALTIMETIMEOUT);
return val==null ? def : Boolean.TRUE.equals(val);
}
/**
* Check if the parameter copy flag is set for a platform.
*/
public static boolean isParameterCopy(IComponentIdentifier platform)
{
// not equals false to make true the default.
return !Boolean.FALSE.equals(getPlatformValue(platform, DATA_PARAMETERCOPY));
}
/**
* Create a platform configuration.
*
* @param args The command line arguments.
* @return StarterConfiguration
*/
public static Map parseArgs(String args)
{
return parseArgs(args.split("\\s+"));
}
/**
*
* @param args
* @param config
*/
public static Map parseArgs(String[] args)
{
Map ret = new HashMap();
for(int i=0; args!=null && i < args.length; i+=2)
{
parseArg(args[i], args[i + 1], ret);
}
return ret;
}
/**
*
* @param okey
* @param val
* @param config
*/
public static void parseArg(String okey, String val, Map vals)
{
String key = okey.startsWith("-") ? okey.substring(1) : okey;
Object value = val;
// if(!IStarterConfiguration.RESERVED.contains(key))
// {
// if not reserved, value is parsed and written to root config.
try
{
value = SJavaParser.evaluateExpression(val, null);
}
catch(Exception e)
{
System.out.println("Argument parse exception using as string: " + key + " \"" + val + "\"");
}
// Hack!!! Allow multiple "component" args, TODO: other "multi" args?
if("component".equals(key))
{
@SuppressWarnings("unchecked")
List comps = (List)vals.get(key);
if(comps==null)
{
comps = new ArrayList();
vals.put(key, comps);
}
if(value instanceof Class)
{
comps.add(((Class>)value).getName()+".class");
}
else
{
comps.add(value.toString());
}
}
else
{
Object prev = vals.put(key, value);
if(prev!=null)
{
System.out.println("Duplicate argument '"+key+"': ignoring value '"+prev+"' and using value '"+value+"'");
}
}
// config.getRootConfig().setValue(key, value);
// }
// config.getStarterConfig().parseArg(key, val, value);
}
// /**
// * Create a platform configuration.
// *
// * @param args The command line arguments.
// * @return StarterConfiguration
// */
// public static IPlatformConfiguration processArgs(String[] args)
// {
// IPlatformConfiguration config = PlatformConfigurationHandler.getPlatformConfiguration(args);
// if(args != null)
// {
// for(int i = 0; args != null && i + 1 < args.length; i += 2)
// {
// parseArg(args[i], args[i + 1], config);
// }
// }
// config.getRootConfig().setProgramArguments(args);
//
// return config;
// }
// /**
// * Create a platform configuration.
// *
// * @param args The command line arguments.
// * @return StarterConfiguration
// */
// public static IPlatformConfiguration processArgs(String[] args)
// {
// IPlatformConfiguration config = PlatformConfigurationHandler.getPlatformConfiguration(args);
// if(args != null)
// {
// for(int i = 0; args != null && i + 1 < args.length; i += 2)
// {
// parseArg(args[i], args[i + 1], config);
// }
// }
// config.getRootConfig().setProgramArguments(args);
//
// return config;
// }
// /**
// * Create a platform configuration.
// *
// * @param args The command line arguments.
// * @return StarterConfiguration
// * @deprecated since 3.0.7. Use other processArgs methods instead.
// */
// @Deprecated
// public static IPlatformConfiguration processArgs(Map args)
// {
// IPlatformConfiguration config = PlatformConfigurationHandler.getPlatformConfiguration();
// // ?! hmm needs to be passed as parameter also?
// if(args != null)
// {
// for(Map.Entry arg : args.entrySet())
// {
// parseArg(arg.getKey(), arg.getValue(), config);
// }
// }
// return config;
// }
// public static void parseArg(String key, String stringValue,
// PlatformConfiguration config) {
// config.parseArg(key, stringValue);
// }
// /**
// *
// * @param args
// */
// public static void parseArgs(String[] args)
// {
// parseArgs(args, this);
// }
//
// /**
// *
// * @param key
// * @param val
// */
// public static void parseArg(String key, String val)
// {
// parseArg(key, val, this);
// }
//-------- Helper methods for no platform mode --------
// moved to BaseService
/**
* Create the necessary platform service replacements.
* @return The services (execution and clock).
* /
public static Tuple2 createServices()
{
IComponentIdentifier pcid = Starter.createPlatformIdentifier(null);
IThreadPool threadpool = new JavaThreadPool(true);
ExecutionService es = new ExecutionService(pcid, threadpool);
es.startService().get();
ClockService cs = new ClockService(pcid, null, threadpool);
cs.startService().get();
return new Tuple2(es, cs);
}*/
/**
* Create an agent based on filename, agent factory and platform services.
* @param filename The model filename.
* @param es The execution service.
* @param cs The clock service.
* @return External access of the created agent.
*/
public static IFuture createAgent(String filename, IComponentFactory cfac, IExecutionService es, IClockService cs)
{
Future ret = new Future<>();
IComponentIdentifier pcid = ((IService)es).getServiceId().getProviderId();
if(Starter.getPlatformValue(pcid, IExecutionService.class.getName())==null)
Starter.putPlatformValue(pcid, IExecutionService.class.getName(), es);
if(Starter.getPlatformValue(pcid, IClockService.class.getName())==null)
Starter.putPlatformValue(pcid, IClockService.class.getName(), cs);
if(Starter.getPlatformValue(pcid, Starter.DATA_INVOKEDMETHODS)==null)
Starter.putPlatformValue(pcid, Starter.DATA_INVOKEDMETHODS, Collections.synchronizedMap(new WeakHashMap>()));
IModelInfo model = cfac.loadModel(filename, null, null, null).get();
String ctype = cfac.getComponentType(filename, null, model.getResourceIdentifier()).get();
ComponentIdentifier cid = new ComponentIdentifier(SUtil.createPlainRandomId(filename, 6)+"@"+pcid);
CMSComponentDescription desc = new CMSComponentDescription(cid).setType(ctype).setModelName(model.getFullName())
.setResourceIdentifier(model.getResourceIdentifier()).setCreationTime(System.currentTimeMillis())
.setFilename(model.getFilename()).setSystemComponent(SComponentManagementService.isSystemComponent(model, null, null));
// create component from model
ComponentCreationInfo cci = new ComponentCreationInfo(model, null, null, desc, null, null);
Collection features = cfac.getComponentFeatures(model, null).get();
IPlatformComponentAccess component = SComponentManagementService.createPlatformComponent(Starter.class.getClassLoader(),
new PlatformComponent()
{
public IFuture> killComponent(IComponentIdentifier cid)
{
Future> ret = new Future<>();
//agent.getLogger().info("Terminating component: "+cid.getName());
IResultListener cc = new IResultListener()
{
public void resultAvailable(Void result)
{
//System.out.println("Killed: " + cid);
cont();
}
public void exceptionOccurred(Exception exception)
{
exception.printStackTrace();
ret.setException(exception);
}
protected void cont()
{
IArgumentsResultsFeature arf = getFeature0(IArgumentsResultsFeature.class);
if(arf!=null)
{
ret.setResult(arf.getResults());
}
else
{
ret.setResult(Collections.EMPTY_MAP);
}
}
};
shutdown().addResultListener(cc);
return ret;
}
});
component.create(cci, features);
component.init().then(x ->
{
//long end = System.currentTimeMillis();
//System.out.println("init took "+(end-start)+" ms, thread: "+Thread.currentThread());
ret.setResult(component.getInternalAccess());
component.body().get();
// Shutdown is called via killComponent()
//component.shutdown().get();
}).catchEx(ret);
return ret;
}
/**
* Test if agent runs in no platform mode.
* @param agent The agent.
* @return True, if runs in no platform mode.
*/
public static boolean isNoPlatformMode(IInternalAccess agent)
{
return Starter.getPlatformValue(agent.getId().getRoot(), IExecutionService.class.getName())!=null;
}
/**
* Get the clock service.
* @return The clock service.
*/
public static IClockService getClockService(IInternalAccess ia)
{
IInternalRequiredServicesFeature rs = ((IInternalRequiredServicesFeature)ia.getFeature0(IRequiredServicesFeature.class));
if(rs!=null)
{
return rs.getRawService(IClockService.class);
}
else
{
// no platform variant
return (IClockService)Starter.getPlatformValue(ia.getId().getRoot(), IClockService.class.getName());
}
}
/**
* Get the execution service.
* @return The execution service.
*/
public static IExecutionService getExecutionService(IInternalAccess ia)
{
IInternalRequiredServicesFeature rs = ((IInternalRequiredServicesFeature)ia.getFeature0(IRequiredServicesFeature.class));
if(rs!=null)
{
return rs.getRawService(IExecutionService.class);
}
else
{
// no platform variant
return (IExecutionService)Starter.getPlatformValue(ia.getId().getRoot(), IExecutionService.class.getName());
}
}
/**
* Create the necessary platform service replacements.
* @return The services (execution and clock).
*/
public static Tuple2 createServices()
{
try
{
IComponentIdentifier pcid = Starter.createPlatformIdentifier(null, false);
IThreadPool threadpool = new JavaThreadPool(true);
Class esc = SReflect.findClass("jadex.noplatform.services.ExecutionService", null, Starter.class.getClassLoader());
Constructor ces = esc.getConstructor(new Class[]{IComponentIdentifier.class, IThreadPool.class});
IExecutionService es = ces.newInstance(new Object[]{pcid, threadpool});
((IInternalService)es).startService().get();
Class ccs = SReflect.findClass("jadex.noplatform.services.ClockService", null, Starter.class.getClassLoader());
Constructor>[] cocs = ccs.getConstructors();
IClockService cs = (IClockService)cocs[0].newInstance(new Object[]{pcid, null, threadpool});
((IInternalService)cs).startService().get();
//ExecutionService es = new ExecutionService(pcid, threadpool);
//es.startService().get();
//ClockService cs = new ClockService(pcid, null, threadpool);
//cs.startService().get();
return new Tuple2(es, cs);
}
catch(Exception e)
{
throw SUtil.throwUnchecked(e);
}
}
/**
* Creating a platform with minimal overhead
*/
/*public static IFuture createPlatform()
{
Future ret = new Future<>();
Logger rootlogger = LogManager.getLogManager().getLogger("");
rootlogger.setLevel(Level.SEVERE);
long start = System.currentTimeMillis();
IComponentIdentifier cid = Starter.createPlatformIdentifier(null);
//System.out.println("platfrom cid: "+cid);
// create helper stuff: service registry, serialization
Map argsmap = new HashMap();
Starter.putPlatformValue(cid, IPlatformConfiguration.PLATFORMARGS, argsmap);
ServiceRegistry reg = new ServiceRegistry();
Starter.putPlatformValue(cid, Starter.DATA_SERVICEREGISTRY, reg);
Starter.putPlatformValue(cid, Starter.DATA_SERIALIZATIONSERVICES, new SerializationServices(cid));
CmsState cmsstate = new CmsState();
Starter.putPlatformValue(cid, Starter.DATA_CMSSTATE, cmsstate);
Starter.putPlatformValue(cid, Starter.DATA_INVOKEDMETHODS, Collections.synchronizedMap(new WeakHashMap>()));
// Create necessary platform services
IThreadPool threadpool = new JavaThreadPool(false);
ExecutionService es = new ExecutionService(cid, threadpool);
es.startService().get();
reg.addLocalService(es);
ClockService cs = new ClockService(cid, null, threadpool);
cs.startService().get();
reg.addLocalService(cs);
//LibraryService ls = new LibraryService(cid);
//ls.startService().get();
//reg.addLocalService(ls);
// create platform component
// load model
//String modelname = "jadex.micro.MinimalAgent";
String modelname = "jadex.micro.KernelMicroAgent";
IComponentFactory cfac = new MicroAgentFactory("rootid");
IModelInfo model = cfac.loadModel(modelname, null, null).get();
String ctype = cfac.getComponentType(modelname, null, model.getResourceIdentifier()).get();
CMSComponentDescription desc = new CMSComponentDescription(cid).setType(ctype).setModelName(model.getFullName())
.setResourceIdentifier(model.getResourceIdentifier()).setCreationTime(System.currentTimeMillis())
.setFilename(model.getFilename()).setSystemComponent(SComponentManagementService.isSystemComponent(model, null, null));
// create component from model
ComponentCreationInfo cci = new ComponentCreationInfo(model, null, null, desc, null, null);
Collection features = cfac.getComponentFeatures(model).get();
IPlatformComponentAccess component = SComponentManagementService.createPlatformComponent(NoPlatformStarter.class.getClassLoader());
// needed for cms
CmsComponentState coms = new CmsComponentState();
coms.setAccess(component);
cmsstate.getComponentMap().put(cid, coms);
component.create(cci, features);
component.init().thenAccept(x ->
{
ret.setResult(component.getPlatformComponent().getExternalAccess());
long end = System.currentTimeMillis();
System.out.println("platform start took "+(end-start)+" ms, thread: "+Thread.currentThread());
component.body().get();
//System.out.println("platform shutdown");
//component.shutdown().get();
//System.out.println("platform end");
}).exceptionally(ret);
//return
return ret;
}*/
}