jadex.bridge.component.impl.MonitoringComponentFeature Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-platform-bridge Show documentation
Show all versions of jadex-platform-bridge Show documentation
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.LinkedHashMap;
import java.util.List;
import java.util.Map;
import jadex.bridge.BulkMonitoringEvent;
import jadex.bridge.IInternalAccess;
import jadex.bridge.SFuture;
import jadex.bridge.component.ComponentCreationInfo;
import jadex.bridge.component.IExecutionFeature;
import jadex.bridge.component.IMonitoringComponentFeature;
import jadex.bridge.service.ServiceScope;
import jadex.bridge.service.component.interceptors.ServiceGetter;
import jadex.bridge.service.types.monitoring.IMonitoringEvent;
import jadex.bridge.service.types.monitoring.IMonitoringService;
import jadex.bridge.service.types.monitoring.IMonitoringService.PublishEventLevel;
import jadex.bridge.service.types.monitoring.IMonitoringService.PublishTarget;
import jadex.bridge.service.types.monitoring.MonitoringEvent;
import jadex.commons.IFilter;
import jadex.commons.Tuple2;
import jadex.commons.future.DelegationResultListener;
import jadex.commons.future.ExceptionDelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.commons.future.ISubscriptionIntermediateFuture;
import jadex.commons.future.ITerminationCommand;
import jadex.commons.future.SubscriptionIntermediateFuture;
/**
*
*/
public class MonitoringComponentFeature extends AbstractComponentFeature implements IMonitoringComponentFeature
{
/** The subscriptions (subscription future -> subscription info). */
protected Map, Tuple2, PublishEventLevel>> subscriptions;
/** The monitoring service getter. */
protected ServiceGetter getter;
/** The event emit level for subscriptions. */
protected PublishEventLevel emitlevelsub;
/**
* Create the feature.
*/
public MonitoringComponentFeature(IInternalAccess component, ComponentCreationInfo cinfo)
{
super(component, cinfo);
this.emitlevelsub = cinfo.getComponentDescription().getMonitoring();
if(emitlevelsub==null)
emitlevelsub = PublishEventLevel.OFF;
// System.out.println("mon is: "+cinfo.getComponentDescription().getName()+" "+emitlevelsub);
}
/**
* Publish a monitoring event. This event is automatically send
* to the monitoring service of the platform (if any).
*/
public IFuture publishEvent(IMonitoringEvent event, PublishTarget pt)
{
// if(event.getCause()==null)
// {
// ServiceCall call = CallAccess.getCurrentInvocation();
// if(call!=null)
// {
//// System.out.println("injecting call cause: "+call.getCause());
// event.setCause(call.getCause());
// }
// else if(getComponent().getDescription().getCause()!=null)
// {
//// System.out.println("injecting root cause: "+call.getCause());
// event.setCause(getComponent().getDescription().getCause().createNext());//event.getSourceIdentifier().toString()));
// }
// }
// Publish to local subscribers
publishLocalEvent(event);
// // Publish to monitoring service if monitoring is turned on
// if((PublishTarget.TOALL.equals(pt) || PublishTarget.TOMONITORING.equals(pt)
// && event.getLevel().getLevel()<=getPublishEmitLevelMonitoring().getLevel()))
// {
return publishEvent(event, getMonitoringServiceGetter());
// }
// else
// {
// return IFuture.DONE;
// }
}
/**
* 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;
}
/**
* Publish a monitoring event to the monitoring service.
*/
public static IFuture publishEvent(final IMonitoringEvent event, final ServiceGetter getter)
{
// return IFuture.DONE;
final Future ret = new Future();
if(getter!=null)
{
getter.getService().addResultListener(new ExceptionDelegationResultListener(ret)
{
public void customResultAvailable(IMonitoringService monser)
{
if(monser!=null)
{
// System.out.println("Published: "+event);
monser.publishEvent(event).addResultListener(new DelegationResultListener(ret)
{
public void exceptionOccurred(Exception exception)
{
getter.resetService();
ret.setException(exception);
}
});
}
else
{
// System.out.println("Could not publish: "+event);
ret.setResult(null);
}
}
});
}
else
{
ret.setResult(null);
}
return ret;
}
/**
* Get the monitoring event emit level for subscriptions. Is the maximum
* level of all subscriptions (cached for speed).
*/
public PublishEventLevel getPublishEmitLevelSubscriptions()
{
return emitlevelsub;
}
/**
* Get the monitoring service getter.
*
* @return The monitoring service getter.
*/
public ServiceGetter getMonitoringServiceGetter()
{
if(getter == null)
getter = new ServiceGetter(getInternalAccess(), IMonitoringService.class, ServiceScope.PLATFORM);
return getter;
}
/**
* Forward event to all currently registered subscribers.
*/
public void publishLocalEvent(IMonitoringEvent event)
{
if(subscriptions != null)
{
for(SubscriptionIntermediateFuture sub : subscriptions.keySet().toArray(new SubscriptionIntermediateFuture[0]))
{
publishLocalEvent(event, sub);
}
}
}
/**
* Forward event to one subscribers.
*/
protected void publishLocalEvent(IMonitoringEvent event, SubscriptionIntermediateFuture sub)
{
Tuple2, PublishEventLevel> tup = subscriptions.get(sub);
try
{
PublishEventLevel el = tup.getSecondEntity();
// System.out.println("rec ev: "+event);
if(event.getLevel().getLevel() <= el.getLevel())
{
IFilter fil = tup.getFirstEntity();
if(fil == null || fil.filter(event))
{
// System.out.println("forward to: "+event+" "+sub);
if(!sub.addIntermediateResultIfUndone(event))
{
subscriptions.remove(sub);
}
}
}
}
catch(Exception e)
{
// catch filter exceptions
e.printStackTrace();
}
}
/**
* Check if event targets exist.
*/
public boolean hasEventTargets(PublishTarget pt, PublishEventLevel pi)
{
boolean ret = false;
if(pi.getLevel() <= getPublishEmitLevelSubscriptions().getLevel() && (PublishTarget.TOALL.equals(pt) || PublishTarget.TOSUBSCRIBERS.equals(pt)))
{
ret = subscriptions != null && !subscriptions.isEmpty();
}
if(!ret && pi.getLevel() <= getPublishEmitLevelMonitoring().getLevel() && (PublishTarget.TOALL.equals(pt) || PublishTarget.TOMONITORING.equals(pt)))
{
ret = true;
}
return ret;
}
/**
* Get the monitoring event emit level.
*/
public PublishEventLevel getPublishEmitLevelMonitoring()
{
return getComponent().getDescription().getMonitoring() != null ? getComponent().getDescription().getMonitoring() : PublishEventLevel.OFF;
// return emitlevelmon;
}
/**
* Subscribe to monitoring events.
*
* @param filter An optional filter.
*/
public ISubscriptionIntermediateFuture subscribeToEvents(IFilter filter, boolean initial, PublishEventLevel emitlevel)
{
final SubscriptionIntermediateFuture ret = (SubscriptionIntermediateFuture)SFuture.getNoTimeoutFuture(SubscriptionIntermediateFuture.class,
getInternalAccess());
ITerminationCommand tcom = new ITerminationCommand()
{
public void terminated(Exception reason)
{
removeSubscription(ret);
}
public boolean checkTermination(Exception reason)
{
return true;
}
};
ret.setTerminationCommand(tcom);
// Signal that subscription has been done
MonitoringEvent subscribed = new MonitoringEvent(getComponent().getId(), getComponent().getDescription().getCreationTime(), IMonitoringEvent.TYPE_SUBSCRIPTION_START, System.currentTimeMillis(),
PublishEventLevel.COARSE);
boolean post = false;
try
{
post = filter == null || filter.filter(subscribed);
}
catch(Exception e)
{
}
if(post)
{
ret.addIntermediateResult(subscribed);
}
addSubscription(ret, filter, emitlevel);
if(initial)
{
List evs = getCurrentStateEvents();
if(evs != null && evs.size() > 0)
{
BulkMonitoringEvent bme = new BulkMonitoringEvent(evs.toArray(new IMonitoringEvent[evs.size()]));
ret.addIntermediateResult(bme);
}
}
return ret;
}
/**
* Add a new subscription.
*
* @param future The subscription future.
* @param si The subscription info.
*/
protected void addSubscription(SubscriptionIntermediateFuture future, IFilter filter, PublishEventLevel emitlevel)
{
if(subscriptions == null)
subscriptions = new LinkedHashMap, Tuple2, PublishEventLevel>>();
if(emitlevel.getLevel() > emitlevelsub.getLevel())
emitlevelsub = emitlevel;
subscriptions.put(future, new Tuple2, PublishEventLevel>(filter, emitlevel));
}
/**
* Remove an existing subscription.
*
* @param fut The subscription future to remove.
*/
protected void removeSubscription(SubscriptionIntermediateFuture fut)
{
if(subscriptions == null || !subscriptions.containsKey(fut))
throw new RuntimeException("Subscriber not known: " + fut);
subscriptions.remove(fut);
emitlevelsub = PublishEventLevel.OFF;
for(Tuple2, PublishEventLevel> tup : subscriptions.values())
{
if(tup.getSecondEntity().getLevel() > emitlevelsub.getLevel())
emitlevelsub = tup.getSecondEntity();
if(PublishEventLevel.COARSE.equals(emitlevelsub))
break;
}
}
/**
* Get the current state as events.
*/
public List getCurrentStateEvents()
{
List ret = null;
IExecutionFeature exef = getComponent().getFeature0(IExecutionFeature.class);
if(exef instanceof ExecutionComponentFeature)
ret = ((ExecutionComponentFeature)exef).getCurrentStateEvents();
return ret;
}
}