📄 agentmobilityservice.java
字号:
}
else if(cmdName.equals(AgentMobilitySlice.H_TRANSFERIDENTITY)) {
AID agentID = (AID)params[0];
Location src = (Location)params[1];
Location dest = (Location)params[2];
cmd.setReturnValue(new Boolean(transferIdentity(agentID, src, dest)));
}
else if(cmdName.equals(AgentMobilitySlice.H_HANDLETRANSFERRESULT)) {
AID agentID = (AID)params[0];
boolean transferResult = ((Boolean)params[1]).booleanValue();
List messages = (List)params[2];
handleTransferResult(agentID, transferResult, messages);
}
else if(cmdName.equals(AgentMobilitySlice.H_CLONEDAGENT)) {
GenericCommand gCmd = new GenericCommand(AgentMobilityHelper.INFORM_CLONED, AgentMobilitySlice.NAME, null);
AID agentID = (AID)params[0];
ContainerID cid = (ContainerID)params[1];
Credentials creds = (Credentials)params[2];
gCmd.addParam(agentID);
gCmd.addParam(cid);
gCmd.addParam(creds);
result = gCmd;
}
//#J2ME_EXCLUDE_BEGIN
else if(cmdName.equals(AgentMobilitySlice.H_CLONECODELOCATORENTRY)) {
AID oldAgentID = (AID)params[0];
AID newAgentID = (AID)params[1];
handleCloneCodeLocatorEntry(oldAgentID, newAgentID);
}
else if(cmdName.equals(AgentMobilitySlice.H_REMOVECODELOCATORENTRY)) {
AID agentID = (AID)params[0];
handleRemoveCodeLocatorEntry(agentID);
}
//#J2ME_EXCLUDE_END
}
catch(Throwable t) {
cmd.setReturnValue(t);
if(result != null) {
result.setReturnValue(t);
}
}
return result;
}
private void createAgent(AID agentID, byte[] serializedInstance, String classSiteName, boolean isCloned, boolean startIt) throws IMTPException, ServiceException, NotFoundException, NameClashException, JADESecurityException {
try {
//log("Incoming agent " + agentID, 1);
if(myLogger.isLoggable(Logger.CONFIG))
myLogger.log(Logger.CONFIG,"Incoming agent " + agentID.getName());
// Reconstruct the serialized agent
//#DOTNET_EXCLUDE_BEGIN
ObjectInputStream in = new Deserializer(new ByteArrayInputStream(serializedInstance), agentID.getName(), classSiteName, myContainer.getServiceFinder());
Agent instance = (Agent)in.readObject();
//#DOTNET_EXCLUDE_END
/*#DOTNET_INCLUDE_BEGIN
ubyte[] ubyteSerializedInstance = new ubyte[serializedInstance.length];
System.Buffer.BlockCopy(serializedInstance, 0, ubyteSerializedInstance, 0, serializedInstance.length);
ByteArrayInputStream in = new ByteArrayInputStream(serializedInstance);
ObjectInputStream decoder = new ObjectInputStream(in);
Object obj = decoder.readObject();
Agent instance = (Agent) obj;
#DOTNET_INCLUDE_END*/
//log("Agent " + agentID + " reconstructed", 2);
if(myLogger.isLoggable(Logger.FINE))
myLogger.log(Logger.FINE,"Agent " + agentID + " reconstructed");
/* --- This code should go into the Security Service ---
// agent is about to be created on the destination Container,
// let's check for permissions before
// does the agent come from a MOVE or a CLONE ?
switch (instance.getState()) {
case Agent.AP_TRANSIT: // MOVED
// checking CONTAINER_MOVE_TO...
myContainer.getAuthority().checkAction(
Authority.CONTAINER_MOVE_TO,
myContainer.getContainerPrincipal(),
instance.getCertificateFolder() );
break;
case Agent.AP_COPY: // CLONED
// checking CONTAINER_CLONE_TO...
myContainer.getAuthority().checkAction(
Authority.CONTAINER_CLONE_TO,
myContainer.getContainerPrincipal(),
instance.getCertificateFolder() );
break;
} // end switch
log("Permissions for agent " + agentID + " OK", 2);
// --- End of code that should go into the Security Service ---
*/
Credentials agentCerts = null;
//#MIDP_EXCLUDE_BEGIN
//CertificateFolder agentCerts = instance.getCertificateFolder();
//#MIDP_EXCLUDE_END
/*# MIDP_INCLUDE_BEGIN
CertificateFolder agentCerts = new CertificateFolder();
# MIDP_INCLUDE_END*/
if(isCloned) {
// Notify the main slice that a new agent is born
AgentMobilitySlice mainSlice = (AgentMobilitySlice)getSlice(MAIN_SLICE);
try {
mainSlice.clonedAgent(agentID, myContainer.getID(), agentCerts);
}
catch(IMTPException imtpe) {
// Try to get a newer slice and repeat...
mainSlice = (AgentMobilitySlice)getFreshSlice(MAIN_SLICE);
mainSlice.clonedAgent(agentID, myContainer.getID(), agentCerts);
}
}
// Store the container where the classes for this agent can be
// retrieved
sites.put(instance, classSiteName);
// Connect the new instance to the local container
Agent old = myContainer.addLocalAgent(agentID, instance);
if(startIt) {
// Actually start the agent thread
myContainer.powerUpLocalAgent(agentID);
}
//log("Agent " + agentID + " inserted into LADT", 1);
if(myLogger.isLoggable(Logger.FINE))
myLogger.log(Logger.FINE,"Agent " + agentID.getName() + " inserted into LADT");
}
catch(IOException ioe) {
throw new IMTPException("An I/O error occurred during de-serialization", ioe);
}
catch(ClassNotFoundException cnfe) {
throw new IMTPException("A class was not found during de-serialization", cnfe);
}
catch(Throwable t) {
t.printStackTrace();
throw new IMTPException("Unexpected error.", t);
}
}
private byte[] fetchClassFile(String className, String agentName) throws IMTPException, ClassNotFoundException {
if (myLogger.isLoggable(Logger.FINE))
myLogger.log(Logger.FINE, "Fetching class " + className);
String fileName = className.replace('.', '/') + ".class";
int length = -1;
InputStream classStream = getClass().getClassLoader().getResourceAsStream(fileName);
if (classStream == null) {
// This is likely redundant, but...
classStream = ClassLoader.getSystemResourceAsStream(fileName);
}
if (classStream == null) {
// In PJAVA for some misterious reason getSystemResourceAsStream()
// does not work --> Try to do it by hand
if (myLogger.isLoggable(Logger.FINER))
myLogger.log(Logger.FINER, "Class not found as a system resource. Try manually");
String currentCp = System.getProperty("java.class.path");
StringTokenizer st = new StringTokenizer(currentCp, File.pathSeparator);
while (st.hasMoreTokens()) {
try {
String path = st.nextToken();
if (myLogger.isLoggable(Logger.FINER)) {
myLogger.log(Logger.FINER, "Searching in path " + path);
}
if (path.endsWith(".jar")) {
if (myLogger.isLoggable(Logger.FINER)) {
myLogger.log(Logger.FINER, "It's a jar file");
}
ClassInfo info = getClassStreamFromJar(fileName, path);
if (info != null) {
classStream = info.getClassStream();
length = info.getLength();
break;
}
}
else {
if (myLogger.isLoggable(Logger.FINER)) {
myLogger.log(Logger.FINER, "Trying file " + path + "/" + fileName);
}
File f = new File(path + "/" + fileName);
if (f.exists()) {
if (myLogger.isLoggable(Logger.FINER)) {
myLogger.log(Logger.FINER, "File exists");
}
classStream = new FileInputStream(f);
break;
}
}
}
catch (Exception e) {
if (myLogger.isLoggable(Logger.WARNING)) {
myLogger.log(Logger.WARNING, e.toString());
}
}
}
}
//#J2ME_EXCLUDE_BEGIN
if (classStream == null && agentName != null) {
// Maybe the agent was loaded from a separate Jar file
try {
AgentManagementService amSrv = (AgentManagementService) myFinder.findService(AgentManagementService.NAME);
ClassLoader cLoader = amSrv.getCodeLocator().getAgentClassLoader(new AID(agentName, AID.ISGUID));
InputStream is = cLoader.getResourceAsStream(fileName);
// We assign length -1 because in a generic InputStream
// the length is not known a priori.
ClassInfo info = new ClassInfo(is, -1);
classStream = info.getClassStream();
length = info.getLength();
}
catch (NullPointerException npe) {
// No jarfile or class not found in jarfile. Ignore
}
catch (Exception e) {
// Should never happen since findService() never throws exceptions
e.printStackTrace();
}
}
//#J2ME_EXCLUDE_END
if (classStream == null) {
if (myLogger.isLoggable(Logger.WARNING)) {
myLogger.log(Logger.WARNING, "Class " + className + " not found");
}
throw new ClassNotFoundException(className);
}
try {
// Length is used no more because we read until the end of the stream.
//if (length == -1) {
// length = (int) classStream.available();
//}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[SIZE_JAR_BUFFER];
int read = 0;
if (myLogger.isLoggable(Logger.FINER)) {
myLogger.log(Logger.FINER, "Class " + className + " fetched. Length is " + length);
}
DataInputStream dis = new DataInputStream(classStream);
while ((read = dis.read(bytes)) >= 0) {
baos.write(bytes, 0, read);
}
dis.close();
return (baos.toByteArray());
}
catch (IOException ioe) {
throw new ClassNotFoundException("IOException reading class bytes. " + ioe.getMessage());
}
}
private ClassInfo getClassStreamFromJar(String classFileName, String jarName) throws IOException {
File f = new File(jarName);
if (f.exists()) {
if (myLogger.isLoggable(Logger.FINER)) {
myLogger.log(Logger.FINER, "Jar file exists");
}
}
ZipFile zf = new ZipFile(f);
ZipEntry e = zf.getEntry(classFileName);
if (e != null) {
if (myLogger.isLoggable(Logger.FINER)) {
myLogger.log(Logger.FINER, "Entry " + classFileName + " found");
}
return new ClassInfo(zf.getInputStream(e), (int) e.getSize());
}
return null;
}
/**
* Inner class ClassInfo
* This utility bean class is used only to keep together some pieces of information related to a class
*/
private class ClassInfo {
private InputStream classStream;
private int length = -1;
public ClassInfo(InputStream is, int l) {
classStream = is;
length = l;
}
public InputStream getClassStream() {
return classStream;
}
public int getLength() {
return length;
}
} // END of inner class ClassInfo
private void handleTransferResult(AID agentID, boolean result, List messages) throws IMTPException, NotFoundException {
//log("Activating incoming agent "+agentID, 1);
if(myLogger.isLoggable(Logger.FINER))
myLogger.log(Logger.FINER,"Activating incoming agent "+agentID);
try {
Agent agent = myContainer.acquireLocalAgent(agentID);
if ((agent == null) || (agent.getState() != AP_TRANSIT)) {
throw new NotFoundException("handleTransferResult() unable to find a suitable agent.");
}
if (result == TRANSFER_ABORT) {
myContainer.removeLocalAgent(agentID);
}
else {
// Insert received messages at the start of the queue
for (int i = messages.size(); i > 0; i--) {
agent.putBack((ACLMessage)messages.get(i - 1));
}
myContainer.powerUpLocalAgent(agentID);
//log("Incoming agent " + agentID + " activated", 1);
if(myLogger.isLoggable(Logger.CONFIG))
myLogger.log(Logger.CONFIG,"Incoming agent " + agentID.getName() + " activated");
}
}
finally {
myContainer.releaseLocalAgent(agentID);
}
}
private boolean prepare() {
// Just return 'true', because this method is simply used as a 'ping', for now...
return true;
}
private boolean transferIdentity(AID agentID, Location src, Location dest) throws IMTPException, NotFoundException {
//log("Transferring identity of agent "+agentID+" from "+src.getName()+" to "+dest.getName(), 2);
if(myLogger.isLoggable(Logger.FINE))
myLogger.log(Logger.FINE,"Transferring identity of agent "+agentID+" from "+src.getName()+" to "+dest.getName());
MainContainer impl = myContainer.getMain();
if(impl != null) {
AgentDescriptor ad = impl.acquireAgentDescriptor(agentID);
if (ad != null) {
try {
AgentMobilitySlice srcSlice = (AgentMobilitySlice)getSlice(src.getName());
AgentMobilitySlice destSlice = (AgentMobilitySlice)getSlice(dest.getName());
boolean srcReady = false;
boolean destReady = false;
try {
srcReady = srcSlice.prepare();
}
catch(IMTPException imtpe) {
srcSlice = (AgentMobilitySlice)getFreshSlice(src.getName());
srcReady = srcSlice.prepare();
}
//log("Source "+src.getName()+" "+srcReady, 2);
if(myLogger.isLoggable(Logger.FINE))
myLogger.log(Logger.FINE,"Source "+src.getName()+" "+srcReady);
try {
destReady = destSlice.prepare();
}
catch(IMTPException imtpe) {
destSlice = (AgentMobilitySlice)getFreshSlice(dest.getName());
destReady = destSlice.prepare();
}
//log("Destination "+dest.getName()+" "+destReady, 2);
if(myLogger.isLoggable(Logger.FINE))
myLogger.log(Logger.FINE,"Destination "+dest.getName()+" "+destReady);
if(srcReady && destReady) {
// FIXME: We should issue a TRANSFER_IDENTITY V-Command to allow migration tracing and prevention
// Commit transaction
impl.movedAgent(agentID, (ContainerID)src, (ContainerID)dest);
return true;
}
else {
// Problems on a participant slice: abort transaction
return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -