package org.tmatesoft.svn.core.internal.io.svn.ssh; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import org.tmatesoft.svn.util.SVNDebugLog; import org.tmatesoft.svn.util.SVNLogType; import com.trilead.ssh2.ServerHostKeyVerifier; import com.trilead.ssh2.auth.AgentProxy; public class SshSessionPool { private static final long PURGE_INTERVAL = 10*1000; private Map<String, SshHost> myPool; private Timer myTimer; public SshSessionPool() { myPool = new HashMap<String, SshHost>(); myTimer = new Timer(true); myTimer.schedule(new TimerTask() { @Override public void run() { synchronized (myPool) { Collection<SshHost> hosts = new ArrayList<SshHost>(myPool.values()); for (SshHost host : hosts) { if (host.purge()) { myPool.remove(host.getKey()); } SVNDebugLog.getDefaultLog().logFinest(SVNLogType.NETWORK, "SSH pool, purged: " + host); } } } }, PURGE_INTERVAL, PURGE_INTERVAL); } public void shutdown() { synchronized (myPool) { Collection<SshHost> hosts = new ArrayList<SshHost>(myPool.values()); for (SshHost host : hosts) { try { host.lock(); host.setDisposed(true); myPool.remove(host.getKey()); } finally { host.unlock(); } } } } public SshSession openSession(String host, int port, String userName, char[] privateKey, char[] passphrase, char[] password, AgentProxy agentProxy, ServerHostKeyVerifier verifier, int connectTimeout, int readTimeout) throws IOException { final SshHost newHost = new SshHost(host, port); newHost.setCredentials(userName, privateKey, passphrase, password, agentProxy); newHost.setConnectionTimeout(connectTimeout); newHost.setHostVerifier(verifier); newHost.setReadTimeout(readTimeout); SshSession session = null; final String hostKey = newHost.getKey(); while(session == null) { SshHost sshHost; synchronized (myPool) { sshHost = myPool.get(hostKey); if (sshHost == null) { sshHost = newHost; myPool.put(hostKey, newHost); } } try { session = sshHost.openSession(); } catch (SshHostDisposedException e) { // host has been removed from the pool. synchronized (myPool) { myPool.remove(hostKey); } continue; } break; } return session; } }