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;
}
}