Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Join us to spark ideas for how to put the latest capabilities into action. Register here!
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