package kg.apc.perfmon.client; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; import java.io.IOException; import java.net.DatagramSocket; import java.net.Socket; import java.net.SocketAddress; import java.nio.channels.DatagramChannel; import java.nio.channels.SocketChannel; /** * Factory used to obtain instances of PerfMon Agent Connections (Transports) * * @author undera * @see Transport */ public class TransportFactory { private static final Logger log = LoggingManager.getLoggerForClass(); /** * Primary transport getting method. Tries to connect and test UDP Transport. * If UDP failed, tries TCP transport. If it fails, too, throws IOException * * @param addr * @return Transport instance * @throws IOException */ public static Transport getTransport(SocketAddress addr) throws IOException { Transport trans; try { log.debug("Connecting TCP"); trans = TCPInstance(addr); if (!trans.test()) { throw new IOException("Agent is unreachable via TCP"); } return trans; } catch (IOException e) { log.info("Can't connect TCP transport for host: " + addr.toString(), e); try { log.debug("Connecting UDP"); trans = UDPInstance(addr); if (!trans.test()) { throw new IOException("Agent is unreachable via UDP"); } return trans; } catch (IOException ex) { log.info("Can't connect UDP transport for host: " + addr.toString(), ex); throw ex; } } } /** * @param addr * @return transport instance * @throws IOException * @deprecated because of instability */ public static Transport NIOUDPInstance(SocketAddress addr) throws IOException { DatagramChannel channel = DatagramChannel.open(); channel.connect(addr); NIOTransport ret = new NIOTransport(); ret.setChannels(channel, channel); return ret; } /** * @param addr * @return transport instance * @throws IOException * @deprecated because of instability */ public static Transport NIOTCPInstance(SocketAddress addr) throws IOException { SocketChannel channel = SocketChannel.open(); channel.connect(addr); NIOTransport ret = new NIOTransport(); ret.setChannels(channel, channel); return ret; } /** * Returns TCP transport instance, connected to specified address * * @param addr * @return Transport instance * @throws IOException */ public static Transport TCPInstance(SocketAddress addr) throws IOException { Socket sock = new Socket(); sock.setSoTimeout(getTimeout()); sock.connect(addr); StreamTransport trans = new StreamTransport(); trans.setStreams(sock.getInputStream(), sock.getOutputStream()); trans.setAddressLabel(addr.toString()); return trans; } private static int getTimeout() { return 500; } /** * Returns new UDP Transport instance * connected to specified socket address * * @param addr * @return connected Transport * @throws IOException */ public static Transport UDPInstance(SocketAddress addr) throws IOException { DatagramSocket sock = new DatagramSocket(); sock.setSoTimeout(getTimeout()); sock.connect(addr); StreamTransport trans = new StreamTransport(); trans.setStreams(new UDPInputStream(sock), new UDPOutputStream(sock)); trans.setAddressLabel(addr.toString()); return trans; } }