add method

This commit is contained in:
Looly
2019-10-14 17:28:57 +08:00
parent d41b917006
commit ab4f58bb31
14 changed files with 472 additions and 292 deletions

View File

@@ -14,7 +14,7 @@ import cn.hutool.setting.Setting;
*
*/
public class UploadSetting {
private static Log log = StaticLog.get();
private static final Log log = Log.get();
/** 默认的配置文件路径相对ClassPath */
public final static String DEFAULT_SETTING_PATH = "config/upload.setting";

View File

@@ -1,42 +1,44 @@
package cn.hutool.extra.ssh;
import cn.hutool.core.util.StrUtil;
import com.jcraft.jsch.Session;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import com.jcraft.jsch.Session;
import cn.hutool.core.util.StrUtil;
/**
* Jsch会话池
*
* @author looly
*
* @author looly
*/
public enum JschSessionPool {
INSTANCE;
/** SSH会话池keyhostvalueSession对象 */
private Map<String, Session> sessionPool = new ConcurrentHashMap<String, Session>();
/** 锁 */
/**
* SSH会话池keyhostvalueSession对象
*/
private Map<String, Session> sessionPool = new ConcurrentHashMap<>();
/**
* 锁
*/
private static final Object lock = new Object();
/**
* 获取Session不存在返回null
*
*
* @param key 键
* @return Session
*/
public Session get(String key) {
return sessionPool.get(key);
}
/**
* 获得一个SSH跳板机会话重用已经使用的会话
*
*
* @param sshHost 跳板机主机
* @param sshPort 跳板机端口
* @param sshUser 跳板机用户名
@@ -58,10 +60,35 @@ public enum JschSessionPool {
return session;
}
/**
* 获得一个SSH跳板机会话重用已经使用的会话
*
* @param sshHost 跳板机主机
* @param sshPort 跳板机端口
* @param sshUser 跳板机用户名
* @param prvkey 跳板机私钥路径
* @param passphrase 跳板机私钥密码
* @return SSH会话
*/
public Session getSession(String sshHost, int sshPort, String sshUser, String prvkey, byte[] passphrase) {
final String key = StrUtil.format("{}@{}:{}", sshUser, sshHost, sshPort);
Session session = get(key);
if (null == session || false == session.isConnected()) {
synchronized (lock) {
session = get(key);
if (null == session || false == session.isConnected()) {
session = JschUtil.openSession(sshHost, sshPort, sshUser, prvkey, passphrase);
put(key, session);
}
}
}
return session;
}
/**
* 加入Session
*
* @param key 键
*
* @param key
* @param session Session
*/
public void put(String key, Session session) {
@@ -70,7 +97,7 @@ public enum JschSessionPool {
/**
* 关闭SSH连接会话
*
*
* @param key 主机格式为user@host:port
*/
public void close(String key) {
@@ -80,20 +107,20 @@ public enum JschSessionPool {
}
sessionPool.remove(key);
}
/**
* 移除指定Session
*
*
* @param session Session会话
* @since 4.1.15
*/
public void remove(Session session) {
if(null != session) {
if (null != session) {
final Iterator<Entry<String, Session>> iterator = this.sessionPool.entrySet().iterator();
Entry<String, Session> entry;
while(iterator.hasNext()) {
while (iterator.hasNext()) {
entry = iterator.next();
if(session.equals(entry.getValue())) {
if (session.equals(entry.getValue())) {
iterator.remove();
break;
}

View File

@@ -1,43 +1,41 @@
package cn.hutool.extra.ssh;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.net.LocalPortGenerater;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import com.jcraft.jsch.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.net.LocalPortGenerater;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
/**
* Jsch工具类<br>
* Jsch是Java Secure Channel的缩写。JSch是一个SSH2的纯Java实现。<br>
* 它允许你连接到一个SSH服务器并且可以使用端口转发X11转发文件传输等。<br>
*
*
* @author Looly
* @since 4.0.0
*/
public class JschUtil {
/** 不使用SSH的值 */
/**
* 不使用SSH的值
*/
public final static String SSH_NONE = "none";
/** 本地端口生成器 */
/**
* 本地端口生成器
*/
private static final LocalPortGenerater portGenerater = new LocalPortGenerater(10000);
/**
* 生成一个本地端口,用于远程端口映射
*
*
* @return 未被使用的本地端口
*/
public static int generateLocalPort() {
@@ -46,7 +44,7 @@ public class JschUtil {
/**
* 获得一个SSH会话重用已经使用的会话
*
*
* @param sshHost 主机
* @param sshPort 端口
* @param sshUser 用户名
@@ -57,9 +55,23 @@ public class JschUtil {
return JschSessionPool.INSTANCE.getSession(sshHost, sshPort, sshUser, sshPass);
}
/**
* 获得一个SSH会话重用已经使用的会话
*
* @param sshHost 主机
* @param sshPort 端口
* @param sshUser 用户名
* @param privateKeyPath 私钥路径
* @param passphrase 私钥密码
* @return SSH会话
*/
public static Session getSession(String sshHost, int sshPort, String sshUser, String privateKeyPath, byte[] passphrase) {
return JschSessionPool.INSTANCE.getSession(sshHost, sshPort, sshUser, privateKeyPath, passphrase);
}
/**
* 打开一个新的SSH会话
*
*
* @param sshHost 主机
* @param sshPort 端口
* @param sshUser 用户名
@@ -77,39 +89,103 @@ public class JschUtil {
}
/**
* 新建一个新的SSH会话
*
* @param sshHost 主机
* @param sshPort 端口
* @param sshUser 用户名
* @param sshPass 密码
* 打开一个新的SSH会话
*
* @param sshHost 主机
* @param sshPort 端口
* @param sshUser 用户名
* @param privateKeyPath 私钥的路径
* @param passphrase 私钥文件的密码可以为null
* @return SSH会话
* @since 4.5.2
*/
public static Session createSession(String sshHost, int sshPort, String sshUser, String sshPass) {
if (StrUtil.isEmpty(sshHost) || sshPort < 0 || StrUtil.isEmpty(sshUser) || StrUtil.isEmpty(sshPass)) {
return null;
}
Session session;
public static Session openSession(String sshHost, int sshPort, String sshUser, String privateKeyPath, byte[] passphrase) {
final Session session = createSession(sshHost, sshPort, sshUser, privateKeyPath, passphrase);
try {
session = new JSch().getSession(sshUser, sshHost, sshPort);
session.setPassword(sshPass);
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
} catch (JSchException e) {
throw new JschRuntimeException(e);
}
return session;
}
/**
* 新建一个新的SSH会话此方法并不打开会话既不调用connect方法
*
* @param sshHost 主机
* @param sshPort 端口
* @param sshUser 用户名如果为null默认root
* @param sshPass 密码
* @return SSH会话
* @since 4.5.2
*/
public static Session createSession(String sshHost, int sshPort, String sshUser, String sshPass) {
Assert.notEmpty(sshHost, "SSH Host must be not empty!");
Assert.isTrue(sshPort < 0, "SSH Host must be not empty!");
// 默认root用户
if (StrUtil.isEmpty(sshUser)) {
sshUser = "root";
}
final JSch jsch = new JSch();
Session session;
try {
session = jsch.getSession(sshUser, sshHost, sshPort);
} catch (JSchException e) {
throw new JschRuntimeException(e);
}
if (StrUtil.isNotEmpty(sshPass)) {
session.setPassword(sshPass);
}
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
return session;
}
/**
* 新建一个新的SSH会话此方法并不打开会话既不调用connect方法
*
* @param sshHost 主机
* @param sshPort 端口
* @param sshUser 用户名如果为null默认root
* @param privateKeyPath 私钥的路径
* @param passphrase 私钥文件的密码可以为null
* @return SSH会话
* @since 5.0.0
*/
public static Session createSession(String sshHost, int sshPort, String sshUser, String privateKeyPath, byte[] passphrase) {
Assert.notEmpty(sshHost, "SSH Host must be not empty!");
Assert.isTrue(sshPort < 0, "SSH Host must be not empty!");
Assert.notEmpty(privateKeyPath, "PrivateKey Path must be not empty!");
// 默认root用户
if (StrUtil.isEmpty(sshUser)) {
sshUser = "root";
}
final JSch jsch = new JSch();
Session session;
try {
jsch.addIdentity(privateKeyPath, passphrase);
session = jsch.getSession(sshUser, sshHost, sshPort);
} catch (JSchException e) {
throw new JschRuntimeException(e);
}
// 设置第一次登录的时候提示,可选值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
return session;
}
/**
* 绑定端口到本地。 一个会话可绑定多个端口
*
* @param session 需要绑定端口的SSH会话
*
* @param session 需要绑定端口的SSH会话
* @param remoteHost 远程主机
* @param remotePort 远程端口
* @param localPort 本地端口
* @param localPort 本地端口
* @return 成功与否
* @throws JschRuntimeException 端口绑定失败异常
*/
@@ -127,8 +203,8 @@ public class JschUtil {
/**
* 解除端口映射
*
* @param session 需要解除端口映射的SSH会话
*
* @param session 需要解除端口映射的SSH会话
* @param localPort 需要解除的本地端口
* @return 解除成功与否
*/
@@ -143,8 +219,8 @@ public class JschUtil {
/**
* 打开SSH会话并绑定远程端口到本地的一个随机端口
*
* @param sshConn SSH连接信息对象
*
* @param sshConn SSH连接信息对象
* @param remoteHost 远程主机
* @param remotePort 远程端口
* @return 映射后的本地端口
@@ -162,7 +238,7 @@ public class JschUtil {
/**
* 打开SFTP连接
*
*
* @param session Session会话
* @return {@link ChannelSftp}
* @since 4.0.3
@@ -173,7 +249,7 @@ public class JschUtil {
/**
* 创建Sftp
*
*
* @param sshHost 远程主机
* @param sshPort 远程主机端口
* @param sshUser 远程主机用户名
@@ -187,7 +263,7 @@ public class JschUtil {
/**
* 创建Sftp
*
*
* @param session SSH会话
* @return {@link Sftp}
* @since 4.0.5
@@ -198,7 +274,7 @@ public class JschUtil {
/**
* 打开Shell连接
*
*
* @param session Session会话
* @return {@link ChannelShell}
* @since 4.0.3
@@ -209,8 +285,8 @@ public class JschUtil {
/**
* 打开Channel连接
*
* @param session Session会话
*
* @param session Session会话
* @param channelType 通道类型可以是shell或sftp等见{@link ChannelType}
* @return {@link Channel}
* @since 4.5.2
@@ -224,11 +300,11 @@ public class JschUtil {
}
return channel;
}
/**
* 创建Channel连接
*
* @param session Session会话
*
* @param session Session会话
* @param channelType 通道类型可以是shell或sftp等见{@link ChannelType}
* @return {@link Channel}
* @since 4.5.2
@@ -248,9 +324,9 @@ public class JschUtil {
/**
* 执行Shell命令
*
*
* @param session Session会话
* @param cmd 命令
* @param cmd 命令
* @param charset 发送和读取内容的编码
* @return {@link ChannelExec}
* @since 4.0.3
@@ -261,10 +337,10 @@ public class JschUtil {
/**
* 执行Shell命令
*
* @param session Session会话
* @param cmd 命令
* @param charset 发送和读取内容的编码
*
* @param session Session会话
* @param cmd 命令
* @param charset 发送和读取内容的编码
* @param errStream 错误信息输出到的位置
* @return {@link ChannelExec}
* @since 4.3.1
@@ -294,7 +370,7 @@ public class JschUtil {
/**
* 关闭SSH连接会话
*
*
* @param session SSH会话
*/
public static void close(Session session) {
@@ -306,7 +382,7 @@ public class JschUtil {
/**
* 关闭会话通道
*
*
* @param channel 会话通道
* @since 4.0.3
*/
@@ -318,7 +394,7 @@ public class JschUtil {
/**
* 关闭SSH连接会话
*
*
* @param key 主机格式为user@host:port
*/
public static void close(String key) {