All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.bridge.component.impl.MonitoringComponentFeature 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.

There is a newer version: 4.0.267
Show newest version
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;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy