package edu.washington.cs.oneswarm.f2f.servicesharing; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; import org.gudy.azureus2.core3.config.COConfigurationManager; import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint; import com.aelitis.azureus.core.networkmanager.NetworkConnection; import com.aelitis.azureus.core.networkmanager.NetworkConnection.ConnectionListener; import com.aelitis.azureus.core.networkmanager.NetworkManager; import com.aelitis.azureus.core.networkmanager.impl.tcp.ProtocolEndpointTCP; import edu.washington.cs.oneswarm.f2f.servicesharing.DataMessage.RawMessageDecoder; import edu.washington.cs.oneswarm.f2f.servicesharing.DataMessage.RawMessageEncoder; import edu.washington.cs.oneswarm.ui.gwt.rpc.SharedServiceDTO; public class SharedService implements Comparable<SharedService> { // Time the service is disabled after a failed connect attempt; public static final long FAILURE_BACKOFF = 60 * 1000; public static final String CONFIGURATION_PREFIX = "SHARED_SERVICE_"; private long lastFailedConnect; private int activeConnections = 0; final long searchKey; SharedService(long searchKey) { this.searchKey = searchKey; } public String getName() { return COConfigurationManager.getStringParameter(getNameKey()); } private String getNameKey() { return CONFIGURATION_PREFIX + searchKey + "_name"; } InetSocketAddress getAddress() { try { int port = COConfigurationManager.getIntParameter(getPortKey(), -1); String ip = COConfigurationManager.getStringParameter(getIpKey()); return new InetSocketAddress(InetAddress.getByName(ip), port); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } private String getPortKey() { return CONFIGURATION_PREFIX + searchKey + "_port"; } private String getIpKey() { return CONFIGURATION_PREFIX + searchKey + "_ip"; } public void setName(String name) { COConfigurationManager.setParameter(getNameKey(), name); } public void setAddress(InetSocketAddress address) { COConfigurationManager.setParameter(getPortKey(), address.getPort()); COConfigurationManager.setParameter(getIpKey(), address.getAddress().getHostAddress()); } @Override public int compareTo(SharedService that) { return this.getName().compareTo(that.getName()); } private ConnectionListener getMonitoringListener(final NetworkConnection conn) { final SharedService self = this; return new ConnectionListener() { @Override public void connectFailure(Throwable failure_msg) { self.activeConnections--; self.lastFailedConnect = System.currentTimeMillis(); } @Override public void connectStarted() { self.activeConnections++; } @Override public void connectSuccess(ByteBuffer remaining_initial_data) { } @Override public void exceptionThrown(Throwable error) { self.activeConnections--; } @Override public String getDescription() { return "Shared Service Listener"; } }; } public NetworkConnection createConnection() { InetSocketAddress address = getAddress(); ConnectionEndpoint target = new ConnectionEndpoint(address); target.addProtocol(new ProtocolEndpointTCP(address)); NetworkConnection conn = NetworkManager.getSingleton().createConnection(target, new RawMessageEncoder(), new RawMessageDecoder(), false, false, new byte[0][0]); return new ListenedNetworkConnection(conn, this.getMonitoringListener(conn)); } public boolean isEnabled() { long lastFailedAge = System.currentTimeMillis() - lastFailedConnect; if (activeConnections > 0) { return true; } boolean enabled = lastFailedAge > FAILURE_BACKOFF; if (!enabled) { ServiceSharingManager.logger.finer(String.format( "Service %s is disabled, last failure: %d seconds ago", getName(), lastFailedAge)); } return enabled; } public SharedServiceDTO toDTO() { InetSocketAddress address = getAddress(); return new SharedServiceDTO(getName(), Long.toHexString(searchKey), address.getAddress() .getHostAddress(), address.getPort()); } @Override public String toString() { InetSocketAddress address = getAddress(); return "key=" + searchKey + getName() + " " + address + " enabled=" + isEnabled(); } public void clean() { COConfigurationManager.removeParameter(getPortKey()); COConfigurationManager.removeParameter(getIpKey()); COConfigurationManager.removeParameter(getNameKey()); } }