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

jadex.base.service.awareness.discovery.ipscanner.ScannerDiscoveryAgent Maven / Gradle / Ivy

Go to download

The Jadex platform base package contains functionality useful for constructing platforms.

The newest version!
package jadex.base.service.awareness.discovery.ipscanner;

import jadex.base.service.awareness.discovery.ConnectionException;
import jadex.base.service.awareness.discovery.DiscoveryAgent;
import jadex.base.service.awareness.discovery.MasterSlaveDiscoveryAgent;
import jadex.base.service.awareness.discovery.ReceiveHandler;
import jadex.base.service.awareness.discovery.SendHandler;
import jadex.bridge.ComponentTerminatedException;
import jadex.bridge.service.types.awareness.AwarenessInfo;
import jadex.commons.SUtil;
import jadex.commons.future.DefaultResultListener;
import jadex.micro.annotation.Agent;
import jadex.micro.annotation.AgentArgument;
import jadex.micro.annotation.Argument;
import jadex.micro.annotation.Arguments;
import jadex.micro.annotation.Description;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;

/**
 *  Agent that sends multicasts to locate other Jadex awareness agents.
 */
@Description("This agent looks for other awareness agents in the local net.")
@Arguments(
{
	@Argument(name="port", clazz=int.class, defaultvalue="55668", description="The port used for finding other agents."),
	@Argument(name="scanfactor", clazz=long.class, defaultvalue="1", description="The delay between scanning as factor of delay time, e.g. 1=10000, 2=20000."),
	@Argument(name="buffersize", clazz=int.class, defaultvalue="1024*1024", description="The size of the send buffer (determines the number of messages that can be sent at once).")
})
@Agent
public class ScannerDiscoveryAgent extends MasterSlaveDiscoveryAgent
{
	/** The receiver port. */
	@AgentArgument
	protected int port;
	
	/** The scan delay factor. */
	@AgentArgument
	protected int scanfactor;
	
	/** The buffer size. */
	@AgentArgument
	protected int buffersize;

	/** The socket to receive. */
	protected DatagramChannel channel;
	protected Selector selector;
	

	/**
	 *  Create the send handler.
	 */
	public SendHandler createSendHandler()
	{
		return new ScannerSendHandler(this);
	}
	
	/**
	 *  Create the receive handler.
	 */
	public ReceiveHandler createReceiveHandler()
	{
		return new ScannerReceiveHandler(this);
	}
	
	/**
	 *  Get the scanfactor.
	 *  @return the scanfactor.
	 */
	public int getScanFactor()
	{
		return scanfactor;
	}

	/**
	 *  Get the port.
	 *  @return the port.
	 */
	public int getPort()
	{
		return port;
	}

	/**
	 *  Test if is master.
	 */
	protected boolean isMaster()
	{
		return getChannel()!=null && this.port==getChannel().socket().getLocalPort();
	}
	
	/**
	 *  Create the master id.
	 */
	protected String createMasterId()
	{
		return isMaster()? createMasterId(SUtil.getInetAddress(),
			getChannel().socket().getLocalPort()): null;
	}
	
	/**
	 *  Get the local master id.
	 */
	protected String getMyMasterId()
	{
		return createMasterId(SUtil.getInetAddress(), port);
	}
	
	/**
	 *  Create the master id.
	 */
	protected String createMasterId(InetAddress address, int port)
	{
		return address+":"+port;
	}
	
	/**
	 *  (Re)init receiving.
	 */
	public synchronized void initNetworkRessource()
	{
		try
		{
			terminateNetworkRessource();
			getChannel();
		}
		catch(Exception e)
		{
		}
	}
	
	/**
	 *  Terminate receiving.
	 */
	protected synchronized void terminateNetworkRessource()
	{
		try
		{
			if(channel!=null)
			{
				channel.close();
				channel = null;
			}
		}
		catch(Exception e)
		{
		}
	}
	
	/**
	 *  Get or create a channel.
	 */
	protected synchronized DatagramChannel getChannel()
	{
		if(!isKilled())
		{
			if(channel==null)
			{
				try
				{
					channel = DatagramChannel.open();
					channel.configureBlocking(false);
					channel.socket().bind(new InetSocketAddress(port));
					channel.socket().setSendBufferSize(buffersize);
					// Register blocks when other thread waits in it.
					// Must be synchronized due to selector wakeup freeing other thread.
					synchronized(this)
					{
						if(selector==null)
							selector = Selector.open();
						selector.wakeup();
						channel.register(selector, SelectionKey.OP_READ);
					}
//					System.out.println("local master at: "+SUtil.getInet4Address()+" "+port);
				}
				catch(Exception e)
				{
					try
					{
						// In case the receiversocket cannot be opened
						// open another local socket at an arbitrary port
						// and send this port to the master.
						channel = DatagramChannel.open();
						channel.configureBlocking(false);
						channel.socket().bind(new InetSocketAddress(0));
						channel.socket().setSendBufferSize(buffersize);
						synchronized(this)
						{
							if(selector==null)
								selector = Selector.open();
							selector.wakeup();
							channel.register(selector, SelectionKey.OP_READ);
						}
						
						createAwarenessInfo(AwarenessInfo.STATE_ONLINE, createMasterId())
							.addResultListener(agent.createResultListener(new DefaultResultListener(agent.getLogger())
						{
							public void resultAvailable(AwarenessInfo info)
							{
								InetAddress address = SUtil.getInetAddress();
//								byte[] data = DiscoveryState.encodeObject(info, getMicroAgent().getModel().getClassLoader());
								byte[] data = DiscoveryAgent.encodeObject(info, getDefaultCodecs(), getMicroAgent().getClassLoader());
								((ScannerSendHandler)sender).send(data, address, port);
							}
							
							public void exceptionOccurred(Exception exception)
							{
								if(!(exception instanceof ComponentTerminatedException))
									super.exceptionOccurred(exception);
							}
						}));
						
//						AwarenessInfo info = createAwarenessInfo(AwarenessInfo.STATE_OFFLINE, createMasterId());
////						byte[] data = DiscoveryState.encodeObject(info, getMicroAgent().getModel().getClassLoader());
//						byte[] data = DiscoveryAgent.encodeObject(info, getMicroAgent().getClassLoader());
//						((ScannerSendHandler)sender).send(data, address, port);
						
//						System.out.println("local slave at: "+SUtil.getInet4Address()+" "+channel.socket().getLocalPort());
//						getLogger().warning("Running in local mode: "+e);
					}
					catch(Exception e2)
					{
//						e2.printStackTrace();
						getMicroAgent().getLogger().warning("Channel problem: "+e2);
						throw new ConnectionException(e2);
					}
				}
			}
		}
		
		return channel;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy