Skip to main content
Announcements
Introducing a new Enhanced File Management feature in Qlik Cloud! GET THE DETAILS!
cancel
Showing results for 
Search instead for 
Did you mean: 
Anonymous
Not applicable

Close anSSH tunnel connection

Hi,
currently we work on the exchange component tSshTunnel to open a tunnel with a forwarding port (L string) to secure a non secure data base.(SSL solution is not possible).
It works fine one shot but the tunnel keep open during a few minutes (15-30) and I can't reopen the same ssh tunnel forwarding: I can't serialize job execution, and more not paralyze.
The tSshTunnel use the librairy Jsch. It creates a connection session. It applies  connect() to open the tunnel but don't close them at the end of component use with  disconnect().
I'm not java developer but how can I use the disconnect() method to the session object creates in the component ?
Other method to close is to identify the process ID and kill them.
Regards
Jeremie

---------------------------------------------------------------------
JAVA code component bloc in the job
public void tSshTunnel_1Process(
final java.util.Map<String, Object> globalMap)
throws TalendException {
globalMap.put("tSshTunnel_1_SUBPROCESS_STATE", 0);
final boolean execStat = this.execStat;
String iterateId = "";
String currentComponent = "";
java.util.Map<String, Object> resourceMap = new java.util.HashMap<String, Object>();
try {
String currentMethodName = new java.lang.Exception()
.getStackTrace().getMethodName();
boolean resumeIt = currentMethodName.equals(resumeEntryMethodName);
if (resumeEntryMethodName == null || resumeIt || globalResumeTicket) {// start
// the
// resume
globalResumeTicket = true;
/**
* start
*/
ok_Hash.put("tSshTunnel_1", false);
start_Hash.put("tSshTunnel_1", System.currentTimeMillis());
currentComponent = "tSshTunnel_1";
int tos_count_tSshTunnel_1 = 0;
java.util.Hashtable<String, com.jcraft.jsch.Session> tunnels_tSshTunnel_1 = new java.util.Hashtable<String, com.jcraft.jsch.Session>();
boolean useKey_tSshTunnel_1_0 = false;
if (!((String) globalMap.get("tCreateTemporaryFile_1_FILEPATH"))
.equals(""))
useKey_tSshTunnel_1_0 = true;
if (!tunnels_tSshTunnel_1
.containsKey(context.connection_sshtunnel_username
+ "@" + context.connection_sshtunnel_hostname
+ ":" + context.connection_sshtunnel_port)) {
com.jcraft.jsch.JSch j = new com.jcraft.jsch.JSch();
if (useKey_tSshTunnel_1_0)
j.addIdentity(((String) globalMap
.get("tCreateTemporaryFile_1_FILEPATH")));
com.jcraft.jsch.Session session = j
.getSession(
context.connection_sshtunnel_username,
context.connection_sshtunnel_hostname,
Integer.parseInt(context.connection_sshtunnel_port));
java.util.Hashtable<String, String> config = new java.util.Hashtable<String, String>();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
if (!useKey_tSshTunnel_1_0) {
session.setPassword(context.connection_sshtunnel_password);
}
session.connect();
String[] credentials = context.connection_sshtunnel_ltunnelstring
.split(":");
session.setPortForwardingL(
Integer.parseInt(credentials), credentials,
Integer.parseInt(credentials));
tunnels_tSshTunnel_1.put(
context.connection_sshtunnel_username + "@"
+ context.connection_sshtunnel_hostname
+ ":" + context.connection_sshtunnel_port,
session);
} else {
com.jcraft.jsch.Session session = tunnels_tSshTunnel_1
.get(context.connection_sshtunnel_username + "@"
+ context.connection_sshtunnel_hostname
+ ":" + context.connection_sshtunnel_port);
String[] credentials = context.connection_sshtunnel_ltunnelstring
.split(":");
session.setPortForwardingL(
Integer.parseInt(credentials), credentials,
Integer.parseInt(credentials));
}
globalMap.put("tunnels_tSshTunnel_1", tunnels_tSshTunnel_1);
/**
* stop
*/
/**
* start
*/
currentComponent = "tSshTunnel_1";
tos_count_tSshTunnel_1++;
/**
* stop
*/
/**
* start
*/
currentComponent = "tSshTunnel_1";
ok_Hash.put("tSshTunnel_1", true);
end_Hash.put("tSshTunnel_1", System.currentTimeMillis());
tSystem_1Process(globalMap);
/**
* stop
*/
}// end the resume
} catch (java.lang.Exception e) {
if (!(e instanceof TalendException)) {
log.fatal(currentComponent + " " + e.getMessage());
}
TalendException te = new TalendException(e, currentComponent,
globalMap);
throw te;
} catch (java.lang.Error error) {
throw error;
} finally {
try {
/**
* start
*/
currentComponent = "tSshTunnel_1";
/**
* stop
*/
} catch (java.lang.Exception e) {
// ignore
} catch (java.lang.Error error) {
// ignore
}
resourceMap = null;
}
globalMap.put("tSshTunnel_1_SUBPROCESS_STATE", 1);
}
Labels (4)
5 Replies
Anonymous
Not applicable
Author

Anonymous
Not applicable
Author

Hi  Jeremie
I think you should close the session after the component, for example:
tSSHTunnel
   |
onsubjobok
    |
do your business 
  |
tJava
on tJava, close the session.

com.jcraft.jsch.Session session=(com.jcraft.jsch.Session)globalMap.get("session");
session.disconnect();

In order to get the session on another component,  you need to modify the source file of component, open the tSshTunnel_begin.javajet file and edit it as below:
<%@ jet 
imports="
org.talend.core.model.process.INode
org.talend.designer.codegen.config.CodeGeneratorArgument
org.talend.core.model.process.ElementParameterParser
java.util.List
java.util.Map
"
%>
<%
CodeGeneratorArgument codeGenArgument = (CodeGeneratorArgument) argument;
INode node = (INode)codeGenArgument.getArgument();
String cid = node.getUniqueName();
List<Map<String, String>> lines = (List<Map<String, String>>)ElementParameterParser.getObjectValue(node, "__TUNNELS__");

%>
com.jcraft.jsch.Session session;
java.util.Hashtable<String,com.jcraft.jsch.Session> tunnels_<%=cid %> = new java.util.Hashtable<String,com.jcraft.jsch.Session>();
<%
for (int i=0; i<lines.size(); i++) {
Map<String, String> line = lines.get(i);

%>
boolean useKey_<%=cid %>_<%=i%>=false;
if (!<%=line.get("KEYFILE")%>.equals(""))
useKey_<%=cid %>_<%=i%>=true;

if (!tunnels_<%=cid %>.containsKey(<%=line.get("USERNAME")%>+"@"+<%=line.get("HOST")%>+":"+<%=line.get("PORT")%>)) {
com.jcraft.jsch.JSch j=new com.jcraft.jsch.JSch();
if(useKey_<%=cid %>_<%=i%>)
j.addIdentity(<%=line.get("KEYFILE")%>);
session=j.getSession(<%=line.get("USERNAME")%>,<%=line.get("HOST")%>,Integer.parseInt(<%=line.get("PORT")%>));
java.util.Hashtable<String, String> config = new java.util.Hashtable<String, String>();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
if (!useKey_<%=cid %>_<%=i%>) {
session.setPassword(<%=line.get("PASSWORD")%>);
}
session.connect();
String[] credentials = <%=line.get("L_TUNNEL_STRING")%>.split(":");
session.setPortForwardingL(Integer.parseInt(credentials), credentials, Integer.parseInt(credentials));
tunnels_<%=cid %>.put(<%=line.get("USERNAME")%>+"@"+<%=line.get("HOST")%>+":"+<%=line.get("PORT")%>,session);

} else {
session = tunnels_<%=cid %>.get(<%=line.get("USERNAME")%>+"@"+<%=line.get("HOST")%>+":"+<%=line.get("PORT")%>);
String[] credentials = <%=line.get("L_TUNNEL_STRING")%>.split(":");
session.setPortForwardingL(Integer.parseInt(credentials), credentials, Integer.parseInt(credentials));
}
globalMap.put("session",session);
globalMap.put("tunnels_<%=cid %>",tunnels_<%=cid %>);
<%
}
%>

Regards
Shong
Anonymous
Not applicable
Author

Hi,
I use the component on Talend Exchange
thanks for all information and code, I have test them with succeed.
I think I can include the java code in the  tSshTunnel_end.javajet ?
Best regards
Jeremie
Anonymous
Not applicable
Author

Hi 
The session should be closed after your business processing, so you can create a new component such as tSSHClose to close the session, such as tMysqlClose. 
Anonymous
Not applicable
Author

Thanks
Jeremie