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.bridge.component.impl.MessageComponentFeature 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.bridge.component.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import jadex.base.Starter;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.IComponentStep;
import jadex.bridge.IConnection;
import jadex.bridge.IInputConnection;
import jadex.bridge.IInternalAccess;
import jadex.bridge.IOutputConnection;
import jadex.bridge.SFuture;
import jadex.bridge.component.ComponentCreationInfo;
import jadex.bridge.component.IExecutionFeature;
import jadex.bridge.component.IMessageFeature;
import jadex.bridge.component.IMessageHandler;
import jadex.bridge.component.IMsgHeader;
import jadex.bridge.component.IUntrustedMessageHandler;
import jadex.bridge.component.streams.AbstractConnectionHandler;
import jadex.bridge.component.streams.AckInfo;
import jadex.bridge.component.streams.InitInfo;
import jadex.bridge.component.streams.InputConnection;
import jadex.bridge.component.streams.InputConnectionHandler;
import jadex.bridge.component.streams.OutputConnection;
import jadex.bridge.component.streams.OutputConnectionHandler;
import jadex.bridge.component.streams.StreamPacket;
import jadex.bridge.service.annotation.Security;
import jadex.bridge.service.annotation.Timeout;
import jadex.bridge.service.component.IInternalRequiredServicesFeature;
import jadex.bridge.service.component.IRequiredServicesFeature;
import jadex.bridge.service.types.cms.SComponentManagementService;
import jadex.bridge.service.types.security.ISecurityInfo;
import jadex.bridge.service.types.security.ISecurityService;
import jadex.bridge.service.types.serialization.ISerializationServices;
import jadex.bridge.service.types.transport.ITransportService;
import jadex.commons.SReflect;
import jadex.commons.SUtil;
import jadex.commons.TimeoutException;
import jadex.commons.Tuple2;
import jadex.commons.future.DelegationResultListener;
import jadex.commons.future.ExceptionDelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.FutureBarrier;
import jadex.commons.future.IFuture;
import jadex.commons.future.IResultListener;
import jadex.commons.future.ISubscriptionIntermediateFuture;
import jadex.commons.future.SubscriptionIntermediateFuture;
import jadex.commons.future.TerminationCommand;
import jadex.commons.transformation.annotations.Classname;
import jadex.commons.transformation.traverser.SCloner;
/**
* Feature to send messages and receive messages via handlers.
* Also implements reacting to incoming stream connections (only exposed in micro agents for now).
*/
public class MessageComponentFeature extends AbstractComponentFeature implements IMessageFeature, IInternalMessageFeature
{
//-------- constants ---------
/** Header marker for send-reply messages. */
public static final String SENDREPLY = "__sendreply__";
/** Exception header property for error messages. */
public static final String EXCEPTION = "__exception__";
//-------- attributes --------
/** The platform ID. */
protected IComponentIdentifier platformid;
/** The list of message handlers. */
protected Set messagehandlers;
/** The security service. */
protected ISecurityService secservice;
/** Messages awaiting reply. */
protected Map> awaitingmessages;
//-------- stream attributes --------
/** The initiator connections. */
protected Map icons = new HashMap();
/** The participant connections. */
protected Map pcons = new HashMap();
/** The alive checker. */
protected IComponentStep checker;
/** The execution feature. */
protected IExecutionFeature execfeat;
//-------- monitoring attributes --------
/** The current subscriptions. */
protected Set> subscriptions;
//-------- constructors --------
/**
* Create the feature.
*/
public MessageComponentFeature(IInternalAccess component, ComponentCreationInfo cinfo)
{
super(component, cinfo);
platformid = component.getId().getRoot();
}
/**
* Check if the feature potentially executed user code in body.
* Allows blocking operations in user bodies by using separate steps for each feature.
* Non-user-body-features are directly executed for speed.
* If unsure just return true. ;-)
*/
public boolean hasUserBody()
{
return false;
}
public IFuture init()
{
execfeat = component.getFeature(IExecutionFeature.class);
return super.init();
}
/**
* Cleanup on shutdown.
*/
@Override
public IFuture shutdown()
{
for(SubscriptionIntermediateFuture sub: SUtil.notNull(subscriptions))
{
sub.setFinished();
}
return IFuture.DONE;
}
//-------- IMessageFeature interface --------
/**
* Send a message.
* @param message The message.
* @param receiver The message receiver(s). At least one required unless given in message object (e.g. FipaMessage).
*
*/
public IFuture sendMessage(Object message, IComponentIdentifier... receiver)
{
return sendMessage(message, null, receiver);
}
/**
* Send a message.
* @param message The message.
* @param addheaderfields Additional header fields.
* @param receiver The message receiver(s). At least one required unless given in message object (e.g. FipaMessage).
*
*/
public IFuture sendMessage(Object message, Map addheaderfields, IComponentIdentifier... receiver)
{
final MsgHeader header = new MsgHeader();
if(addheaderfields != null)
for (Map.Entry entry : addheaderfields.entrySet())
header.addProperty(entry.getKey(), entry.getValue());
header.addProperty(IMsgHeader.SENDER, component.getId());
if(receiver!=null && receiver.length>0)
header.addProperty(IMsgHeader.RECEIVER, receiver.length==1 ? receiver[0] : receiver); // optimize send to one
return sendMessage(header, message);
}
/**
* Send a message and wait for a reply.
*
* @param receiver The message receiver.
* @param message The message.
*
* @return The reply.
*/
public IFuture sendMessageAndWait(IComponentIdentifier receiver, Object message)
{
return sendMessageAndWait(receiver, message, null);
}
/**
* Send a message and wait for a reply.
*
* @param receiver The message receiver.
* @param message The message.
* @param timeout The reply timeout.
*
* @return The reply.
*/
public IFuture sendMessageAndWait(IComponentIdentifier receiver, Object message, Long timeout)
{
final Future ret = new Future();
final String convid = SUtil.createUniqueId(component.getId().toString());
if (awaitingmessages == null)
awaitingmessages = new HashMap>();
awaitingmessages.put(convid, ret);
final MsgHeader header = new MsgHeader();
header.addProperty(IMsgHeader.SENDER, component.getId());
header.addProperty(IMsgHeader.RECEIVER, receiver);
header.addProperty(IMsgHeader.CONVERSATION_ID, convid);
header.addProperty(SENDREPLY, Boolean.TRUE);
sendMessage(header, message).addResultListener(new IResultListener()
{
public void resultAvailable(Void result)
{
// NOP
}
public void exceptionOccurred(Exception exception)
{
Future fut = awaitingmessages.remove(convid);
if (fut != null)
fut.setException(exception);
}
});
timeout = timeout == null ? Starter.getDefaultTimeout(platformid) : timeout;
execfeat.waitForDelay(timeout, new IComponentStep()
{
public IFuture execute(IInternalAccess ia)
{
Future fut = awaitingmessages.remove(convid);
if (fut != null)
{
fut.setException(new TimeoutException("Failed to receive reply for message awaiting reply: " + convid));
}
return IFuture.DONE;
}
}, Starter.isRealtimeTimeout(getComponent().getId(), true));
return ret;
}
/**
* Send a message reply.
* @param receivedmessageid ID of the received message that is being replied to.
* @param message The reply message.
*
*/
public IFuture sendReply(IMsgHeader msgheader, Object message)
{
// if (!(receivedmessageid instanceof Map))
// return new Future(new IllegalArgumentException("Cannot reply, illegal message ID or null."));
IComponentIdentifier rplyrec = (IComponentIdentifier) msgheader.getProperty(IMsgHeader.SENDER);
String convid = (String) msgheader.getProperty(IMsgHeader.CONVERSATION_ID);
if (rplyrec == null)
return new Future(new IllegalArgumentException("Cannot reply, reply receiver ID not found."));
if (convid == null)
return new Future(new IllegalArgumentException("Cannot reply, conversation ID not found."));
MsgHeader header = new MsgHeader();
header.addProperty(IMsgHeader.RECEIVER, rplyrec);
header.addProperty(IMsgHeader.SENDER, component.getId());
header.addProperty(IMsgHeader.CONVERSATION_ID, convid);
header.addProperty(SENDREPLY, Boolean.TRUE);
return sendMessage(header, message);
}
protected boolean isSecurityMessage(IMsgHeader header)
{
return Boolean.TRUE.equals(header.getProperty("__securitymessage__"));
}
/**
* Forwards the prepared message to the transport layer.
*
* @param header The message header.
* @param encryptedheader The encrypted header.
* @param encryptedbody The encrypted message body.
* @return Null, when done, exception if failed.
*/
public IFuture sendToTransports(final IMsgHeader header, final byte[] encheader, final byte[] encryptedbody)
{
final Future ret = new Future();
IComponentIdentifier rplat = ((IComponentIdentifier)header.getProperty(IMsgHeader.RECEIVER)).getRoot();
// Transport service is platform-level shared / no required proxy: manual decoupling
Tuple2 cachedtransport = getTransportCache(component.getId().getRoot()).get(rplat);
if(cachedtransport != null)
{
if(getComponent().getId().toString().indexOf("TerminateTest")!=-1)
System.out.println("sendToTransports: sending msg with: "+cachedtransport.getFirstEntity());
//if(isSecurityMessage(header))
// System.out.println("sending sec msg with: "+cachedtransport.getFirstEntity());
cachedtransport.getFirstEntity().sendMessage(header, encheader, encryptedbody).addResultListener(execfeat.createResultListener(new IResultListener()
{
public void resultAvailable(Integer result)
{
ret.setResultIfUndone(null);
}
public void exceptionOccurred(Exception exception)
{
getTransportCache(component.getId().getRoot()).remove(rplat);
sendToAllTransports(rplat, header, encheader, encryptedbody).addResultListener(new DelegationResultListener<>(ret, true));
}
}));
}
else
{
sendToAllTransports(rplat, header, encheader, encryptedbody).addResultListener(new DelegationResultListener<>(ret, true));
}
long timeout = Starter.getDefaultTimeout(platformid);
timeout = timeout != -1 ? timeout : 30000;
component.getFeature(IExecutionFeature.class).waitForDelay(timeout, new IComponentStep()
{
public IFuture execute(IInternalAccess ia)
{
// Check first to avoid creating an exception.
if(!ret.isDone())
{
@SuppressWarnings("serial")
Exception ex = new TimeoutException("Timeout occured by " + component.getId().toString() + " while sending message to " + header.getProperty(IMsgHeader.RECEIVER))// rplat)
{
@Override
public void printStackTrace()
{
super.printStackTrace();
}
};
ret.setExceptionIfUndone(ex);
}
return IFuture.DONE;
}
}, Starter.isRealtimeTimeout(getComponent().getId(), true));
return ret;
}
/**
* Add a message handler.
* @param The handler.
*/
public void addMessageHandler(final IMessageHandler handler)
{
if(messagehandlers==null)
{
messagehandlers = new LinkedHashSet();
}
messagehandlers.add(handler);
}
/**
* Remove a message handler.
* @param handler The handler.
*/
public void removeMessageHandler(IMessageHandler handler)
{
if(messagehandlers!=null)
{
messagehandlers.remove(handler);
}
}
//-------- IInternalMessageFeature interface --------
/**
* Inform the component that a message has arrived.
* Called from transports (i.e. remote messages).
*
* @param header The message header.
* @param bodydata The encrypted message that arrived.
*/
public void messageArrived(final IMsgHeader header, byte[] bodydata)
{
if(header != null && bodydata != null)
{
// System.out.println("Received message: "+header);
ISecurityService secserv = getSecurityService();
IComponentIdentifier sender = (IComponentIdentifier)header.getProperty(IMsgHeader.SENDER);
IFuture> fut = secserv.decryptAndAuth(sender, bodydata);
fut.addResultListener(
component.getFeature(IExecutionFeature.class).createResultListener(new IResultListener>()
{
public void resultAvailable(Tuple2 result)
{
// Check if SecurityService ok'd it at all.
if(result != null)
{
final ISecurityInfo secinf = result.getFirstEntity();
Object message;
try
{
message = deserializeMessage(header, result.getSecondEntity());
// System.out.println("decoded: "+message);
}
catch(Exception e)
{
getComponent().getLogger().warning("Could not decode message: "+header+", "+e);
// When decoding message fails -> allow agent to handle exception (e.g. useful for failed replies)
message = null;
header.addProperty(EXCEPTION, e);
}
messageArrived(secinf, header, message);
}
};
public void exceptionOccurred(Exception exception)
{
exception.printStackTrace();
}
}));
}
else
{
getComponent().getLogger().warning("Received empty message: "+header+" "+bodydata);
}
}
/**
* Inform the component that a message has arrived.
* Called directly for intra-platform message delivery (i.e. local messages)
* and indirectly for remote messages.
*
* @param secinfos The security meta infos.
* @param header The message header.
* @param body The message that arrived.
*/
public void messageArrived(final ISecurityInfo secinfos, final IMsgHeader header, Object body)
{
notifyMessageReceived(secinfos, header, body);
if(Boolean.TRUE.equals(header.getProperty(SENDREPLY)))
{
// send-reply message, check if reply.
String convid = (String) header.getProperty(IMsgHeader.CONVERSATION_ID);
Future fut = awaitingmessages != null ? awaitingmessages.remove(convid) : null;
if(fut != null)
{
Exception exception = (Exception) header.getProperty(EXCEPTION);
if(exception != null)
fut.setException(exception);
else
fut.setResult(body);
return;
}
else
{
handleMessage(secinfos, header, body);
}
}
else if(body instanceof StreamPacket)
{
handleStreamPacket((StreamPacket) body);
}
else
{
handleMessage(secinfos, header, body);
}
}
/**
* Forwards the prepared message to the transport layer using all transports.
*
* @param rplat The receiving platform.
* @param header The message header.
* @param encryptedbody The encrypted message body.
* @return Null, when done, exception if failed.
*/
protected IFuture sendToAllTransports(IComponentIdentifier rplat, IMsgHeader header, byte[] encheader, byte[] encryptedbody)
{
Future ret = new Future<>();
Collection transports = getAllTransports();
if(getComponent().getId().toString().indexOf("TerminateTest")!=-1)
System.out.println("sendToAllTransports0: sending sec msg with all: "+transports);
//if(isSecurityMessage(header))
// System.out.println("sending sec msg with all: "+transports);
if(transports.size()==0)
{
RuntimeException re = new RuntimeException("No message transport available: "+component.getId()+" "+header);
// re.printStackTrace();
ret.setException(re);
}
else
{
int[] cnt = new int[]{transports.size()};
for(final ITransportService transport : transports)
{
if(getComponent().getId().toString().indexOf("TerminateTest")!=-1)
System.out.println("sendToAllTransports1: sending msg with: "+transport);
// component.getLogger().info("sending msg with0: "+transport);
transport.sendMessage(header, encheader, encryptedbody).addResultListener(execfeat.createResultListener(new IResultListener()
{
public void resultAvailable(Integer result)
{
if(getComponent().getId().toString().indexOf("TerminateTest")!=-1)
System.out.println("sendToAllTransports2: sent msg with: "+transport+", "+result);
// component.getLogger().info("sending msg with1: "+transport);
// Successful sent, check if transport cache needs to be updated (to speedup further sending)
Map> cache = getTransportCache(platformid);
if(cache.get(rplat) == null || cache.get(rplat).getSecondEntity() < result)
{
cache.put(rplat, new Tuple2(transport, result));
}
ret.setResultIfUndone(null);
}
public void exceptionOccurred(Exception exception)
{
if(getComponent().getId().toString().indexOf("TerminateTest")!=-1)
System.out.println("sendToAllTransports3: sending msg failed with: "+transport+"\n"+SUtil.getExceptionStacktrace(exception));
// component.getLogger().info("sending msg with2: "+transport);
cnt[0]--;
// System.out.println("Transport failed: "+cnt+"/"+transports.size()+" "+exception);
//exception.printStackTrace();
if(cnt[0]==0)
{
if(getComponent().getId().toString().indexOf("TerminateTest")!=-1)
System.out.println("sendToAllTransports4: Finally failed to send message: "+transport);
component.getLogger().warning("Finally failed to send message: "+exception);
ret.setExceptionIfUndone(exception);
}
}
}));
}
}
return ret;
}
/**
* Gets the transport services cache.
*
* @param platformid The platform ID.
* @return The transport cache.
*/
@SuppressWarnings("unchecked")
protected Map> getTransportCache(IComponentIdentifier platformid)
{
return (Map>) Starter.getPlatformValue(platformid.getRoot(), Starter.DATA_TRANSPORTCACHE);
}
/**
* Gets all transports on the platform.
*
* @return All transports.
*/
protected Collection getAllTransports()
{
return ((IInternalRequiredServicesFeature)getComponent().getFeature(IRequiredServicesFeature.class)).getRawServices(ITransportService.class);
}
/**
* Handle message with user message handlers.
*
* @param secinf Security meta infos.
* @param header Message header.
* @param body
*/
protected void handleMessage(final ISecurityInfo secinf, final IMsgHeader header, final Object body)
{
boolean handled = false;
boolean trusted = isTrusted(secinf);
if(messagehandlers!=null)
{
for(Iterator it = messagehandlers.iterator(); it.hasNext(); )
{
final IMessageHandler handler = it.next();
if(handler.isRemove())
{
it.remove();
}
else if((handler instanceof IUntrustedMessageHandler || trusted) && handler.isHandling(secinf, header, body))
{
handled = true;
// component.getComponentFeature0(IExecutionFeature.class).scheduleStep(new IComponentStep()
// {
// public IFuture execute(IInternalAccess ia)
// {
handler.handleMessage(secinf, header, body);
// return IFuture.DONE;
// }
// });
}
}
}
if(!handled && trusted)
processUnhandledMessage(secinf, header, body);
}
/**
* Send the message to potentially multiple receivers.
*
* @param header The header.
* @param message The message.
* @return Null, when sent.
*/
protected IFuture sendMessage(final MsgHeader header, Object message)
{
preprocessMessage(header, message);
if(subscriptions!=null && !subscriptions.isEmpty() && header.getProperty(IMsgHeader.XID)==null)
header.addProperty(IMsgHeader.XID, SUtil.createUniqueId(null));
Object rec = header.getProperty(IMsgHeader.RECEIVER);
if(SReflect.isIterable(rec))
{
FutureBarrier fubar = new FutureBarrier();
for(Object orec: SReflect.getIterable(rec))
{
// Need to copy header, because receiver isn't exposed in transport interface.
MsgHeader copy = new MsgHeader();
copy.setProperties(new LinkedHashMap(header.getProperties()));
copy.addProperty(IMsgHeader.RECEIVER, orec);
fubar.addFuture(doSendMessage(copy, message));
}
if(fubar.getCount()>0)
{
return fubar.waitFor();
}
else
{
return new Future(new IllegalArgumentException("No receivers specified in message: "+header+", "+message));
}
}
else
{
return doSendMessage(header, message);
}
}
/**
* Send the message to a single receiver.
*
* @param header The header.
* @param message The message.
* @return Null, when sent.
*/
protected IFuture doSendMessage(final MsgHeader header, Object message)
{
// if(!component.getComponentFeature(IExecutionFeature.class).isComponentThread())
// throw new RuntimeException("wrooongMMMM");
// component.getLogger().info("doSendMessage: "+header+", "+message);
final Future ret = new Future();
Object rec = header.getProperty(IMsgHeader.RECEIVER);
if(!(rec instanceof IComponentIdentifier))
return new Future(new IllegalArgumentException("Messages must have receiver(s) of type IComponentIdentifier: "+message+", "+header));
IComponentIdentifier receiver = (IComponentIdentifier)rec;
notifyMessageSent(header, message);
if(receiver.getRoot().equals(platformid))
{
try
{
// Direct local delivery.
ClassLoader cl = SComponentManagementService.getLocalClassLoader(receiver);
final Object clonedmsg = SCloner.clone(message, cl);
SComponentManagementService.getLocalExternalAccess(receiver).scheduleStep(new IComponentStep()
{
public IFuture execute(IInternalAccess ia)
{
IMessageFeature imf = ia.getFeature0(IMessageFeature.class);
if (imf instanceof IInternalMessageFeature)
{
((IInternalMessageFeature)imf).messageArrived(null, header, clonedmsg);
return IFuture.DONE;
}
return new Future(new RuntimeException("Receiver " + ia.getId() + " has no messaging."));
}
}).addResultListener(new DelegationResultListener(ret));
}
catch(RuntimeException e)
{
// E.g. when receiver not found.
ret.setException(e);
}
}
else
{
try
{
ISerializationServices serialserv = getSerializationServices(platformid);
byte[] bheader = serialserv.encode(header, component, header);
byte[] body = serialserv.encode(header, component, message);
final ISecurityService secserv = getSecurityService();
//System.out.println("doSendMsg: "+header+" "+component+" "+message);
secserv.encryptAndSign(header, bheader).addResultListener(
component.getFeature(IExecutionFeature.class).createResultListener(new ExceptionDelegationResultListener((Future) ret)
{
public void customResultAvailable(final byte[] encheader) throws Exception
{
secserv.encryptAndSign(header, body).addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(byte[] body) throws Exception
{
sendToTransports(header, encheader, body).addResultListener(new DelegationResultListener(ret));
}
});
}
}));
}
catch(Exception e)
{
// Encode failed -> return exception
ret.setException(e);
}
}
return ret;
}
/**
* Called for all messages without matching message handlers.
* Can be overwritten by specific message feature implementations (e.g. micro or BDI).
*/
protected void processUnhandledMessage(final ISecurityInfo secinf, final IMsgHeader header, final Object body)
{
}
/**
* Deserialize the message.
*
* @param header The message header.
* @param serializedmsg The serialized message.
* @return The deserialized message.
*/
protected Object deserializeMessage(IMsgHeader header, byte[] serializedmsg)
{
return getSerializationServices(platformid).decode(header, component, serializedmsg);
}
/**
* Inform the component that a stream has arrived.
* @param con The stream that arrived.
*/
public void streamArrived(IConnection con)
{
// getComponent().getComponentFeature(IExecutionFeature.class)
// .scheduleStep(createHandleStreamStep(con))
// .addResultListener(new IResultListener()
// {
// public void resultAvailable(Void result)
// {
// // NOP
// }
//
// public void exceptionOccurred(Exception exception)
// {
// // Todo: fail fast components?
// StringWriter sw = new StringWriter();
// exception.printStackTrace(new PrintWriter(sw));
// getComponent().getLogger().severe("Exception during stream processing\n"+sw);
// }
// });
}
// /**
// * Create a new stream step.
// */
// public IComponentStep createHandleStreamStep(IConnection con)
// {
// return new HandleStreamStep(con);
// }
//
// /**
// * Step to handle a stream.
// * Must not do anything and just throw it away?
// */
// public class HandleStreamStep implements IComponentStep
// {
// private final IConnection con;
//
// public HandleStreamStep(IConnection con)
// {
// this.con = con;
// }
//
// public IFuture execute(IInternalAccess ia)
// {
// invokeHandlers(con);
// return IFuture.DONE;
// }
//
// /**
// * Extracted to allow overriding behaviour.
// * @return true, when at least one matching handler was found.
// */
// protected boolean invokeHandlers(IConnection con)
// {
// boolean ret = false;
// return ret;
// }
//
// public String toString()
// {
// return "messageArrived()_#"+this.hashCode();
// }
// }
/**
* Find a suitable transport service for a message.
*
* @param header The message header.
* @return A suitable transport service or exception if none is available.
*/
// protected IFuture getTransportService(IMsgHeader header)
// {
// final Future ret = new Future();
// IComponentIdentifier rplat = ((IComponentIdentifier) header.getProperty(IMsgHeader.RECEIVER)).getRoot();
//
// Tuple2 tup = getTransportCache(platformid).get(rplat);
// if (tup != null)
// {
// getTransportCache(platformid).put(rplat, tup);
// ret.setResult(tup.getFirstEntity());
// }
// else
// {
//// final Collection coll = SServiceProvider.getLocalServices(component, ITransportService.class, ServiceScope.PLATFORM);
// final Collection coll = getAllTransports();
// if (coll != null && coll.size() > 0)
// {
// final IComponentIdentifier receiverplatform = ((IComponentIdentifier) header.getProperty(IMsgHeader.RECEIVER)).getRoot();
// final int[] counter = new int[]{coll.size()};
// final MultiException mex = new MultiException();
// for(Iterator it = coll.iterator(); it.hasNext(); )
// {
// final ITransportService tp = it.next();
// tp.isReady(header).addResultListener(new IResultListener()
// {
// public void resultAvailable(Integer priority)
// {
// ret.setResultIfUndone(tp);
// Tuple2 tup = getTransportCache(platformid).get(receiverplatform);
// if (tup == null || tup.getSecondEntity() < priority)
// getTransportCache(platformid).put(receiverplatform, new Tuple2(tp, priority));
// }
//
// public void exceptionOccurred(Exception exception)
// {
// mex.addCause(exception);
// --counter[0];
// if(counter[0] == 0)
// {
// String error = component.getId()+" could not find working transport for receiver " + receiverplatform + ", tried:";
// for (ITransportService tp : coll)
// {
// error += " " + tp.toString();
// }
// ret.setException(mex);
//// ret.setException(new RuntimeException(error, exception));
// }
// }
// });
// }
// }
// else
// {
// ret.setException(new ServiceNotFoundException("No transport available.")
// {
// public void printStackTrace()
// {
// super.printStackTrace();
// }
// });
// }
// }
// return ret;
// }
/**
* Gets the security service.
*
* @return The security service.
*/
protected ISecurityService getSecurityService()
{
if (secservice == null)
secservice = ((IInternalRequiredServicesFeature)getComponent().getFeature(IRequiredServicesFeature.class)).getRawService(ISecurityService.class);
return secservice;
}
/**
* Gets the platform serialization services.
*
* @param platformid The platform ID.
* @return The serialization services.
*/
public static final ISerializationServices getSerializationServices(IComponentIdentifier platformid)
{
return (ISerializationServices) Starter.getPlatformValue(platformid.getRoot(), Starter.DATA_SERIALIZATIONSERVICES);
}
/**
* Creates a conversation ID.
*
* @return Large random conversation ID.
*/
protected static final long[] generateConversationId()
{
long[] convid = new long[4];
for (int i = 0; i < convid.length; ++i)
convid[i] = SUtil.getSecureRandom().nextLong();
return convid;
}
/**
* Get the participant input connection.
*/
public IInputConnection getParticipantInputConnection(int conid, IComponentIdentifier initiator, IComponentIdentifier participant, Map nonfunc)
{
return initInputConnection(conid, initiator, participant, nonfunc);
}
/**
* Get the participant output connection.
*/
public IOutputConnection getParticipantOutputConnection(int conid, IComponentIdentifier initiator, IComponentIdentifier participant, Map nonfunc)
{
return initOutputConnection(conid, initiator, participant, nonfunc);
}
/**
* Create a virtual output connection.
*/
public OutputConnection internalCreateOutputConnection(IComponentIdentifier sender, IComponentIdentifier receiver, Map nonfunc)
{
UUID uuconid = UUID.randomUUID();
int conid = uuconid.hashCode();
OutputConnectionHandler och = new OutputConnectionHandler(getInternalAccess(), nonfunc);
addOutputConnection(conid, och);
// icons.put(conid, och);
OutputConnection con = new OutputConnection(sender, receiver, conid, true, och);
// System.out.println("created ocon: "+component+", "+System.currentTimeMillis()+", "+och.getConnectionId());
return con;
}
/**
* Create a virtual output connection.
*/
public IFuture createOutputConnection(IComponentIdentifier sender, IComponentIdentifier receiver, Map nonfunc)
{
return new Future(internalCreateOutputConnection(sender, receiver, nonfunc));
}
/**
* Create a virtual input connection.
*/
public InputConnection internalCreateInputConnection(IComponentIdentifier sender, IComponentIdentifier receiver, Map nonfunc)
{
UUID uuconid = UUID.randomUUID();
int conid = uuconid.hashCode();
InputConnectionHandler ich = new InputConnectionHandler(getInternalAccess(), nonfunc);
addInputConnection(conid, ich);
// icons.put(conid, ich);
InputConnection con = new InputConnection(sender, receiver, conid, true, ich);
// System.out.println("created icon: "+component+", "+System.currentTimeMillis()+", "+ich.getConnectionId());
return con;
}
/**
* Create a virtual input connection.
*/
public IFuture createInputConnection(IComponentIdentifier sender, IComponentIdentifier receiver, Map nonfunc)
{
return new Future(internalCreateInputConnection(sender, receiver, nonfunc));
}
/**
* Create local input connection side after receiving a remote init output message.
* May be called multiple times and does nothing, if connection already exists.
*/
protected IInputConnection initInputConnection(final int conid, final IComponentIdentifier initiator,
final IComponentIdentifier participant, final Map nonfunc)
{
boolean created;
InputConnectionHandler ich = null;
InputConnection con = null;
synchronized(this)
{
// ich = (InputConnectionHandler)pcons.get(Integer.valueOf(conid));
ich = getInputConnection(Integer.valueOf(conid));
if(ich==null)
{
ich = new InputConnectionHandler(getInternalAccess(), nonfunc);
con = new InputConnection(initiator, participant, conid, false, ich);
addInputConnection(Integer.valueOf(conid), ich);
// pcons.put(Integer.valueOf(conid), ich);
// System.out.println("created for: "+conid+" "+pcons+" "+getComponent().getComponentIdentifier());
created = true;
}
else
{
con = ich.getInputConnection();
created = false;
}
}
if(created)
{
ich.initReceived();
final InputConnection fcon = con;
// final Future ret = new Future();
streamArrived(fcon);
// IInternalMessageFeature com = (IInternalMessageFeature)getComponent().getComponentFeature(IMessageFeature.class);
// if(com!=null)
// {
// com.streamArrived(fcon);
// }
// else
// {
// getComponent().getLogger().warning("Component received stream, but ha no communication feature: "+fcon);
// }
// component.getComponentFeature(IRequiredServicesFeature.class).searchService(new ServiceQuery<>( IComponentManagementService.class, ServiceScope.PLATFORM))
// .addResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(IComponentManagementService cms)
// {
// cms.getExternalAccess(participant).addResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(IExternalAccess ea)
// {
// ea.scheduleStep(new IComponentStep()
// {
// public IFuture execute(IInternalAccess ia)
// {
// IInternalMessageFeature com = (IInternalMessageFeature)ia.getComponentFeature(IMessageFeature.class);
// if(com!=null)
// {
// com.streamArrived(fcon);
// }
// else
// {
// ia.getLogger().warning("Component received stream, but ha no communication feature: "+fcon);
// }
//
// return IFuture.DONE;
// }
// });
// }
// });
// }
// });
}
else
{
// If connection arrives late
if(nonfunc!=null)
ich.setNonFunctionalProperties(nonfunc);
}
return con;
}
/**
* Create local output connection side after receiving a remote init input message.
* May be called multiple times and does nothing, if connection already exists.
*/
protected IOutputConnection initOutputConnection(final int conid, final IComponentIdentifier initiator,
final IComponentIdentifier participant, final Map nonfunc)
{
boolean created;
OutputConnectionHandler och;
OutputConnection con = null;
synchronized(this)
{
// och = (OutputConnectionHandler)pcons.get(Integer.valueOf(conid));
och = getOutputConnection(Integer.valueOf(conid));
if(och==null)
{
och = new OutputConnectionHandler(getInternalAccess(), nonfunc);
con = new OutputConnection(initiator, participant, conid, false, och);
addOutputConnection(Integer.valueOf(conid), och);
// pcons.put(Integer.valueOf(conid), och);
// System.out.println("created: "+con.hashCode());
created = true;
}
else
{
con = och.getOutputConnection();
created = false;
}
}
if(created)
{
och.initReceived();
final OutputConnection fcon = con;
// final Future ret = new Future();
streamArrived(fcon);
// IInternalMessageFeature com = (IInternalMessageFeature)getComponent().getComponentFeature(IMessageFeature.class);
// if(com!=null)
// {
// com.streamArrived(fcon);
// }
// else
// {
// getComponent().getLogger().warning("Component received stream, but ha no communication feature: "+fcon);
// }
// component.getComponentFeature(IRequiredServicesFeature.class).searchService(new ServiceQuery<>( IComponentManagementService.class, ServiceScope.PLATFORM))
// .addResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(IComponentManagementService cms)
// {
// cms.getExternalAccess(participant).addResultListener(new ExceptionDelegationResultListener(ret)
// {
// public void customResultAvailable(IExternalAccess ea)
// {
// ea.scheduleStep(new IComponentStep()
// {
// public IFuture execute(IInternalAccess ia)
// {
// IInternalMessageFeature com = (IInternalMessageFeature)ia.getComponentFeature(IMessageFeature.class);
// if(com!=null)
// {
// com.streamArrived(fcon);
// }
// else
// {
// ia.getLogger().warning("Component received stream, but ha no communication feature: "+fcon);
// }
//
// return IFuture.DONE;
// }
// });
// }
// });
// }
// });
}
else
{
// If connection arrives late
if(nonfunc!=null)
och.setNonFunctionalProperties(nonfunc);
}
return con;
}
/**
* Get a input connection.
* @param id The id.
* @return The input connection.
*/
protected InputConnectionHandler getInputConnection(int id)
{
return (InputConnectionHandler)(pcons!=null? pcons.get(id): null);
}
/**
* Get a output connection.
* @param id The id.
* @return The output connection.
*/
protected OutputConnectionHandler getOutputConnection(int id)
{
return (OutputConnectionHandler)(icons!=null? icons.get(id): null);
}
/**
* Add an output connection.
* @param id The id.
* @param och The handler.
*/
protected void addOutputConnection(int id, OutputConnectionHandler och)
{
if(icons==null)
icons = new HashMap();
icons.put(id, och);
if(getStreamCount()==1)
startStreamCheckAliveBehavior();
}
/**
* Add an input connection.
* @param id The id.
* @param ich The handler.
*/
protected void addInputConnection(int id, InputConnectionHandler ich)
{
if(pcons==null)
pcons = new HashMap();
pcons.put(id, ich);
if(getStreamCount()==1)
startStreamCheckAliveBehavior();
}
/**
* Remove an output connection.
* @param id The id.
*/
protected void removeOutputConnection(int id)
{
if(icons!=null)
icons.remove(id);
if(getStreamCount()==0)
stopStreamCheckAliveBehavior();
}
/**
* Remove an input connection.
* @param id The id.
* @param ich The handler.
*/
protected void removeInputConnection(int id)
{
if(pcons!=null)
pcons.remove(id);
if(getStreamCount()==0)
stopStreamCheckAliveBehavior();
}
/**
* Get the stream count.
* @return The number of streams.
*/
protected int getStreamCount()
{
return (icons!=null? icons.size(): 0)+(pcons!=null? pcons.size(): 0);
}
protected static final AbstractConnectionHandler[] EMPTY_HANDLER_ARRAY = new AbstractConnectionHandler[0];
/**
* Get all participant connections.
*/
protected AbstractConnectionHandler[] getParticipantConnections()
{
return pcons==null? EMPTY_HANDLER_ARRAY: (AbstractConnectionHandler[])pcons.values().toArray(new AbstractConnectionHandler[0]);
}
/**
* Get all initiator connections.
*/
protected AbstractConnectionHandler[] getInitiatorConnections()
{
return icons==null? EMPTY_HANDLER_ARRAY: (AbstractConnectionHandler[])icons.values().toArray(new AbstractConnectionHandler[0]);
}
/**
* Start the checker.
*/
public void startStreamCheckAliveBehavior()
{
final long lt = getMinLeaseTime(getComponent().getId());
// System.out.println("to is: "+lt);
if(lt==Timeout.NONE)
return;
if(checker==null)
{
checker = new IComponentStep()
{
@Classname("checkAlive")
public IFuture execute(IInternalAccess ia)
{
// End when I am not the current checker
if(checker!=this)
return IFuture.DONE;
AbstractConnectionHandler[] mypcons = getParticipantConnections();
for(int i=0; i
// {
// private final IConnection con;
//
// public HandleStreamStep(IConnection con)
// {
// this.con = con;
// }
//
// public IFuture execute(IInternalAccess ia)
// {
// invokeHandlers(con);
// return IFuture.DONE;
// }
//
// /**
// * Extracted to allow overriding behaviour.
// * @return true, when at least one matching handler was found.
// */
// protected boolean invokeHandlers(IConnection con)
// {
// boolean ret = false;
// // Todo: Stream handlers?
//// if(messagehandlers!=null)
//// {
//// for(int i=0; i, IMessagePreprocessor> preprocessors = Collections.synchronizedMap(new HashMap, IMessagePreprocessor>());
/**
* Preprocess a message before sending.
* Allows adding special treatment of certain user message types
* like FIPA messages.
* @param header The message header, may be changed by preprocessor.
* @param msg The user object, may be changed by preprocessor.
*/
protected static void preprocessMessage(IMsgHeader header, Object msg)
{
IMessagePreprocessor proc= getPreprocessor(msg);
if(proc!=null)
{
proc.preprocessMessage(header, msg);
}
}
/**
* Try to find a message preprocessor for the given object.
* A preprocessor has the same packe and class name, appending "Preprocessor"
* and implementing IMessagePreprocessor.
* Also checks superclasses and interfaces.
*/
protected static IMessagePreprocessor getPreprocessor(Object msg)
{
IMessagePreprocessor proc = null;
if(msg!=null)
{
Class> clazz = msg.getClass();
if(preprocessors.containsKey(clazz))
{
proc = preprocessors.get(clazz);
}
else
{
// Try class itself
proc = findPreprocessor(clazz);
// Try interfaces
if(proc==null)
{
for(Class> inter: clazz.getInterfaces())
{
proc = findPreprocessor(inter);
if(proc!=null)
{
break;
}
}
}
// Try super classes
if(proc==null)
{
Class> sup = clazz;
while(proc==null && sup.getSuperclass()!=null)
{
sup = sup.getSuperclass();
proc = findPreprocessor(sup);
}
}
preprocessors.put(clazz, proc);
}
}
return proc;
}
/**
* Try to load a message preprocessor for a given class.
*/
protected static IMessagePreprocessor findPreprocessor(Class> clazz)
{
IMessagePreprocessor ret = null;
try
{
@SuppressWarnings("unchecked")
Class extends IMessagePreprocessor> pclazz = (Class extends IMessagePreprocessor>)
Class.forName(clazz.getName()+"Preprocessor", true, clazz.getClassLoader());
ret = pclazz.getDeclaredConstructor().newInstance();
}
catch(ClassNotFoundException e)
{
// ignore
}
catch(NoClassDefFoundError e)
{
// ignore
}
catch(Throwable t)
{
// Class found, but e.g. instantiation or class cast exception
throw SUtil.throwUnchecked(t);
}
return ret;
}
//-------- monitoring --------
/**
* Called for each sent message.
*/
protected void notifyMessageSent(IMsgHeader header, Object body)
{
if(subscriptions!=null)
{
MessageEvent event = new MessageEvent(MessageEvent.Type.SENT, null, header, body);
for(SubscriptionIntermediateFuture sub: subscriptions)
{
sub.addIntermediateResult(event);
}
}
}
/**
* Called for each received message.
*/
protected void notifyMessageReceived(ISecurityInfo secinfos, IMsgHeader header, Object body)
{
if(subscriptions!=null)
{
MessageEvent event = new MessageEvent(MessageEvent.Type.RECEIVED, secinfos, header, body);
for(SubscriptionIntermediateFuture sub: subscriptions)
{
sub.addIntermediateResult(event);
}
}
}
/**
* Handles a stream packet.
*
* @param packet A stream packet.
*/
protected void handleStreamPacket(StreamPacket packet)
{
byte type = packet.getType();
int conid = packet.getConnectionId().intValue();
// System.out.println("rec stream msg: "+getComponent().getComponentIdentifier().getLocalName()+" "+type);
// Handle output connection participant side
if(type==AbstractConnectionHandler.INIT_OUTPUT_INITIATOR)
{
InitInfo ii = (InitInfo)packet.getData();
initInputConnection(conid, ii.getInitiator(), ii.getParticipant(), ii.getNonFunctionalProperties());
}
else if(type==AbstractConnectionHandler.ACKINIT_OUTPUT_PARTICIPANT)
{
// System.out.println("CCC: ack init");
OutputConnectionHandler och = getOutputConnection(Integer.valueOf(conid));
// (OutputConnectionHandler)icons.get(Integer.valueOf(conid));
if(och!=null)
{
och.ackReceived(AbstractConnectionHandler.INIT, packet.getData());
}
else
{
System.out.println("OutputStream not found (ackinit): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.DATA_OUTPUT_INITIATOR)
{
// System.out.println("received data");
// InputConnectionHandler ich = (InputConnectionHandler)pcons.get(Integer.valueOf(conid));
InputConnectionHandler ich = getInputConnection(Integer.valueOf(conid));
if(ich!=null)
{
ich.addData(packet.getSequenceNumber(), (byte[])packet.getData());
}
else
{
System.out.println("InputStream not found (dai): "+conid+" "+getParticipantConnections()+" "+getComponent().getId());
}
}
else if(type==AbstractConnectionHandler.CLOSE_OUTPUT_INITIATOR)
{
// System.out.println("CCC: close");
// InputConnectionHandler ich = (InputConnectionHandler)pcons.get(Integer.valueOf(conid));
InputConnectionHandler ich = getInputConnection(Integer.valueOf(conid));
if(ich!=null)
{
ich.closeReceived(SUtil.bytesToInt((byte[])packet.getData()));
}
else
{
System.out.println("InputStream not found (coi): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.ACKCLOSE_OUTPUT_PARTICIPANT)
{
// System.out.println("CCC: ackclose");
OutputConnectionHandler och = getOutputConnection(Integer.valueOf(conid));
// OutputConnectionHandler och = (OutputConnectionHandler)icons.get(Integer.valueOf(conid));
if(och!=null)
{
och.ackReceived(AbstractConnectionHandler.CLOSE, packet.getData());
}
else
{
System.out.println("OutputStream not found (ackclose): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.CLOSEREQ_OUTPUT_PARTICIPANT)
{
// System.out.println("CCC: closereq");
// OutputConnectionHandler och = (OutputConnectionHandler)icons.get(Integer.valueOf(conid));
OutputConnectionHandler och = getOutputConnection(Integer.valueOf(conid));
if(och!=null)
{
och.closeRequestReceived();
}
else
{
System.out.println("OutputStream not found (closereq): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.ACKCLOSEREQ_OUTPUT_INITIATOR)
{
// System.out.println("CCC: ackclosereq");
// InputConnectionHandler ich = (InputConnectionHandler)pcons.get(Integer.valueOf(conid));
InputConnectionHandler ich = getInputConnection(Integer.valueOf(conid));
if(ich!=null)
{
ich.ackReceived(AbstractConnectionHandler.CLOSEREQ, packet.getData());
// ich.ackCloseRequestReceived();
}
else
{
System.out.println("OutputStream not found (ackclosereq): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.ACKDATA_OUTPUT_PARTICIPANT)
{
// Handle input connection initiator side
// OutputConnectionHandler och = (OutputConnectionHandler)icons.get(Integer.valueOf(conid));
OutputConnectionHandler och = getOutputConnection(Integer.valueOf(conid));
if(och!=null)
{
AckInfo ackinfo = (AckInfo)packet.getData();
och.ackDataReceived(ackinfo);
}
else
{
System.out.println("OutputStream not found (ackdata): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.INIT_INPUT_INITIATOR)
{
InitInfo ii = (InitInfo)packet.getData();
initOutputConnection(conid, ii.getInitiator(), ii.getParticipant(), ii.getNonFunctionalProperties());
}
else if(type==AbstractConnectionHandler.ACKINIT_INPUT_PARTICIPANT)
{
// InputConnectionHandler ich = (InputConnectionHandler)icons.get(Integer.valueOf(conid));
InputConnectionHandler ich = getInputConnection(Integer.valueOf(conid));
if(ich!=null)
{
ich.ackReceived(AbstractConnectionHandler.INIT, packet.getData());
}
else
{
System.out.println("InputStream not found (ackinit): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.DATA_INPUT_PARTICIPANT)
{
// InputConnectionHandler ich = (InputConnectionHandler)icons.get(Integer.valueOf(conid));
InputConnectionHandler ich = getInputConnection(Integer.valueOf(conid));
if(ich!=null)
{
ich.addData(packet.getSequenceNumber(), (byte[])packet.getData());
}
else
{
System.out.println("InputStream not found (data input): "+conid);
}
}
else if(type==AbstractConnectionHandler.ACKDATA_INPUT_INITIATOR)
{
// OutputConnectionHandler och = (OutputConnectionHandler)pcons.get(Integer.valueOf(conid));
OutputConnectionHandler och = getOutputConnection(Integer.valueOf(conid));
if(och!=null)
{
AckInfo ackinfo = (AckInfo)packet.getData();
och.ackDataReceived(ackinfo);
}
else
{
System.out.println("OutputStream not found (ackdata): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.CLOSEREQ_INPUT_INITIATOR)
{
// OutputConnectionHandler och = (OutputConnectionHandler)pcons.get(Integer.valueOf(conid));
OutputConnectionHandler och = getOutputConnection(Integer.valueOf(conid));
if(och!=null)
{
och.closeRequestReceived();
}
else
{
System.out.println("InputStream not found (closereq): "+conid);
}
}
else if(type==AbstractConnectionHandler.ACKCLOSEREQ_INPUT_PARTICIPANT)
{
// InputConnectionHandler ich = (InputConnectionHandler)icons.get(Integer.valueOf(conid));
InputConnectionHandler ich = getInputConnection(Integer.valueOf(conid));
if(ich!=null)
{
ich.ackReceived(AbstractConnectionHandler.CLOSEREQ, packet.getData());
}
else
{
System.out.println("InputStream not found (ackclosereq): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.CLOSE_INPUT_PARTICIPANT)
{
// InputConnectionHandler ich = (InputConnectionHandler)icons.get(Integer.valueOf(conid));
InputConnectionHandler ich = getInputConnection(Integer.valueOf(conid));
if(ich!=null)
{
ich.closeReceived(SUtil.bytesToInt((byte[])packet.getData()));
}
else
{
System.out.println("OutputStream not found (closeinput): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
else if(type==AbstractConnectionHandler.ACKCLOSE_INPUT_INITIATOR)
{
// OutputConnectionHandler ich = (OutputConnectionHandler)pcons.get(Integer.valueOf(conid));
InputConnectionHandler ich = getInputConnection(Integer.valueOf(conid));
if(ich!=null)
{
ich.ackReceived(AbstractConnectionHandler.CLOSE, packet.getData());
}
else
{
System.out.println("InputStream not found (ackclose): "+component+", "+System.currentTimeMillis()+", "+conid);
}
}
// Handle lease time update
else if(type==AbstractConnectionHandler.ALIVE_INITIATOR)
{
// System.out.println("alive initiator");
// AbstractConnectionHandler con = (AbstractConnectionHandler)pcons.get(Integer.valueOf(conid));
OutputConnectionHandler con = getOutputConnection(Integer.valueOf(conid));
if(con!=null)
{
con.setAliveTime(System.currentTimeMillis());
}
// else
// {
// System.out.println("Stream not found (alive ini): "+component+", "+System.currentTimeMillis()+", "+conid);
// }
}
else if(type==AbstractConnectionHandler.ALIVE_PARTICIPANT)
{
// System.out.println("alive particpant");
// AbstractConnectionHandler con = (AbstractConnectionHandler)icons.get(Integer.valueOf(conid));
InputConnectionHandler con = getInputConnection(Integer.valueOf(conid));
if(con!=null)
{
con.setAliveTime(System.currentTimeMillis());
}
// else
// {
// System.out.println("Stream not found (alive par): "+component+", "+System.currentTimeMillis()+", "+conid);
// }
}
//
//// System.out.println("bbbb: "+mycnt+" "+getComponent().getComponentIdentifier());
// }
//// catch(Throwable e)
// catch(final Exception e)
// {
//// e.printStackTrace();
// getComponent().scheduleStep(new IComponentStep()
// {
// public IFuture execute(IInternalAccess ia)
// {
// ia.getLogger().warning("Exception in stream: "+e.getMessage());
// return IFuture.DONE;
// }
// });
// }
// }
// }
}
/**
* Tests if a message is considered "trusted".
*
* @param secinfos The security infos of the message.
* @return True, if trusted.
*/
protected boolean isTrusted(ISecurityInfo secinfos)
{
return secinfos == null || secinfos.getRoles().contains(Security.TRUSTED);
}
/**
* Listen to message events (send and receive).
*/
// Todo: message matching?
public ISubscriptionIntermediateFuture getMessageEvents()
{
if(subscriptions==null)
{
subscriptions = new LinkedHashSet>();
}
@SuppressWarnings("unchecked")
final SubscriptionIntermediateFuture ret = (SubscriptionIntermediateFuture)
SFuture.getNoTimeoutFuture(SubscriptionIntermediateFuture.class, getInternalAccess(), Starter.isRealtimeTimeout(getInternalAccess().getId(), true));
ret.setTerminationCommand(new TerminationCommand()
{
@Override
public void terminated(Exception reason)
{
subscriptions.remove(ret);
}
});
subscriptions.add(ret);
return ret;
}
}