00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.ssh;
00032
00033 import org.apache.log4j.Logger;
00034 import org.objectweb.proactive.core.ssh.SshTunnel;
00035 import org.objectweb.proactive.core.ssh.UnusedTunnel;
00036 import org.objectweb.proactive.core.util.log.Loggers;
00037 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00038
00039
00051 public class SshTunnelFactory {
00052 static Logger logger = ProActiveLogger.getLogger(Loggers.SSH);
00053 private java.util.Hashtable<String, UnusedTunnel> _unused;
00054 static private SshTunnelFactory _factory = null;
00055
00056 static private SshTunnelFactory getFactory() {
00057 if (_factory == null) {
00058 _factory = new SshTunnelFactory();
00059 }
00060 return _factory;
00061 }
00062
00063 static public SshTunnel createTunnel(String host, int port)
00064 throws java.io.IOException {
00065 return getFactory().create(host, port);
00066 }
00067
00068 static public void reportUnusedTunnel(SshTunnel tunnel)
00069 throws Exception {
00070 getFactory().reportUnused(tunnel);
00071 }
00072
00073 private SshTunnelFactory() {
00074 _unused = new java.util.Hashtable<String, UnusedTunnel>();
00075 if (SshParameters.getUseTunnelGC()) {
00076 Thread gcThread = new Thread() {
00077 public void run() {
00078 while (true) {
00079 try {
00080 sleep(1000);
00081 } catch (InterruptedException e) {
00082 }
00083 getFactory().GC();
00084 }
00085 }
00086 };
00087 gcThread.start();
00088 }
00089 }
00090
00091 private String getKey(String host, int port) {
00092 return host + port;
00093 }
00094
00095 private synchronized SshTunnel create(String host, int port)
00096 throws java.io.IOException {
00097 if (SshParameters.getUseTunnelGC()) {
00098 UnusedTunnel unused = _unused.get(getKey(host, port));
00099 SshTunnel tunnel;
00100 if (unused == null) {
00101 logger.debug("create tunnel " + host + ":" + port);
00102 tunnel = new SshTunnel(host, port);
00103 } else {
00104 logger.debug("reuse tunnel " + host + ":" + port);
00105 _unused.remove(getKey(host, port));
00106 tunnel = unused.getTunnel();
00107 }
00108 return tunnel;
00109 } else {
00110 return new SshTunnel(host, port);
00111 }
00112 }
00113
00114 private synchronized void reportUnused(SshTunnel tunnel)
00115 throws Exception {
00116 if (tunnel != null) {
00117 String host = tunnel.getDistantHost();
00118 int port = tunnel.getDistantPort();
00119 if (SshParameters.getUseTunnelGC()) {
00120 UnusedTunnel prev = _unused.get(getKey(host, port));
00121 if (prev != null) {
00122 prev.getTunnel().realClose();
00123 _unused.remove(getKey(host, port));
00124 }
00125 logger.debug("return unused tunnel " + host + ":" + port);
00126 _unused.put(getKey(host, port), new UnusedTunnel(tunnel));
00127 } else {
00128 logger.debug("kill unused tunnel " + host + ":" + port);
00129 tunnel.realClose();
00130 }
00131 }
00132 }
00133
00134 private synchronized void GC() {
00135 java.util.Enumeration<String> keys = _unused.keys();
00136 for (; keys.hasMoreElements();) {
00137 String key = keys.nextElement();
00138 UnusedTunnel tunnel = _unused.get(key);
00139 if (tunnel.isOldEnough()) {
00140 try {
00141 SshTunnel sshTunnel = tunnel.getTunnel();
00142 logger.debug("gc kill unused tunnel " +
00143 sshTunnel.getDistantHost() + ":" +
00144 sshTunnel.getDistantPort());
00145 sshTunnel.realClose();
00146 } catch (Exception e) {
00147 e.printStackTrace();
00148 }
00149 _unused.remove(key);
00150 }
00151 }
00152 }
00153 }