package org.jdiameter.client.impl.transport.tcp; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.util.concurrent.ConcurrentLinkedQueue; import org.jdiameter.api.AvpDataException; import org.jdiameter.api.Configuration; import org.jdiameter.api.InternalException; import org.jdiameter.api.OverloadException; import org.jdiameter.client.api.IMessage; import org.jdiameter.client.api.io.IConnection; import org.jdiameter.client.api.io.IConnectionListener; import org.jdiameter.client.api.io.TransportError; import org.jdiameter.client.api.io.TransportException; import org.jdiameter.client.api.parser.IMessageParser; public class TCPClientConnection implements IConnection { private final long createdTime; private TCPTransportClient client; protected IMessageParser parser; protected final Object lock = new Object(); protected ConcurrentLinkedQueue<IConnectionListener> listeners = new ConcurrentLinkedQueue<IConnectionListener>(); protected TCPClientConnection (IMessageParser parser) { this.createdTime = System.currentTimeMillis(); this.parser = parser; client = new TCPTransportClient(this); } public TCPClientConnection(Configuration config, Socket socket, IMessageParser parser, String ref) throws Exception { this(parser); client = new TCPTransportClient(this); client.initialize(socket); client.start(); } public TCPClientConnection(Configuration config, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IMessageParser parser, String ref) { this(parser); client.setDestAddress(new InetSocketAddress(remoteAddress, remotePort)); client.setOrigAddress(new InetSocketAddress(localAddress, localPort)); this.parser = parser; } public TCPClientConnection(Configuration config, InetAddress remoteAddress, int remotePort, InetAddress localAddress, int localPort, IConnectionListener listener, IMessageParser parser, String ref) { this(parser); client.setDestAddress(new InetSocketAddress(remoteAddress, remotePort)); client.setOrigAddress(new InetSocketAddress(localAddress, localPort)); listeners.add(listener); this.parser = parser; } public long getCreatedTime() { return createdTime; } public void connect() throws TransportException { try { getClient().initialize(); getClient().start(); } catch(IOException e) { throw new TransportException("Cannot init transport: ", TransportError.NetWorkError, e); } catch (Exception e) { throw new TransportException("Cannot init transport: ", TransportError.Internal, e); } } public void disconnect() throws InternalError { try { if(getClient() != null) { getClient().stop(); } } catch (Exception e) { throw new InternalError("Error while stopping transport: " + e.getMessage()); } } public void release() throws IOException { try { if (getClient() != null) { getClient().release(); } } catch (Exception e) { throw new IOException(e.getMessage()); } finally { parser = null; listeners = null; } } public void sendMessage(IMessage message) throws TransportException, OverloadException { try { if (getClient() != null) { getClient().sendMessage(parser.encodeMessage(message)); } } catch (Exception e) { throw new TransportException("Cannot send message: ", TransportError.FailedSendMessage, e); } } protected TCPTransportClient getClient() { return client; } public boolean isNetworkInitiated() { return false; } public boolean isConnected() { return getClient() != null && getClient().isConnected(); } public InetAddress getRemoteAddress() { return getClient().getDestAddress().getAddress(); } public int getRemotePort() { return getClient().getDestAddress().getPort(); } public void addConnectionListener(IConnectionListener listener) { if (listeners != null) { listeners.add(listener); notifyListeners(); } } public void remAllConnectionListener() { listeners.clear(); } public void remConnectionListener(IConnectionListener listener) { if (listeners != null) { listeners.remove(listener); } } public boolean isWrapperFor(Class<?> aClass) throws InternalException { return false; } public <T> T unwrap(Class<T> aClass) throws InternalException { return null; } public String getKey() { return "aaa://" + getRemoteAddress().getHostName() + ":" + getRemotePort(); } void onDisconnect() { if (listeners != null) { waitListeners(); for (IConnectionListener listener : listeners) { listener.connectionClosed(getKey(), null); } } } void onMessageReveived(ByteBuffer message) throws AvpDataException { if (listeners != null) { waitListeners(); for (IConnectionListener listener : listeners) { listener.messageReceived(getKey(), parser.createMessage(message)); } } } void onAvpDataException(AvpDataException e) { if (listeners != null) { waitListeners(); for (IConnectionListener listener : listeners) { listener.internalError(getKey(), null, new TransportException("Avp Data Exception:", TransportError.ReceivedBrokenMessage, e)); } } } void onConnected() { if (listeners != null) { waitListeners(); for (IConnectionListener listener : listeners) { listener.connectionOpened(getKey()); } } } void notifyListeners() { if (listeners != null && listeners.size() == 0) { synchronized (lock) { lock.notifyAll(); } } } void waitListeners() { if (listeners != null && listeners.size() == 0) { synchronized (lock) { try { lock.wait(500); } catch (InterruptedException e) {} } } } }