VIVIMAN
3 years ago
17 changed files with 486 additions and 83 deletions
@ -0,0 +1,25 @@ |
|||
package com.insigma.command; |
|||
|
|||
import com.insigma.entry.ExecuteResult; |
|||
|
|||
/** |
|||
* LocalCommandExecutor.java |
|||
* @author Vivim |
|||
*/ |
|||
public interface LocalCommandExecutor { |
|||
/** |
|||
* 执行命令行对象 |
|||
* @param command 执行命令行 |
|||
* @param timeout 超时控制 |
|||
* @return |
|||
*/ |
|||
ExecuteResult executeCommand(String command, long timeout); |
|||
/** |
|||
* 执行命令行对象 |
|||
* @param command 执行命令行 |
|||
* @param keyword 检测关键字 |
|||
* @param timeout 超时控制 |
|||
* @return |
|||
*/ |
|||
String getPort(String command, String keyword, long timeout); |
|||
} |
@ -0,0 +1,145 @@ |
|||
package com.insigma.command.impl; |
|||
|
|||
import com.insigma.entry.ExecuteResult; |
|||
import com.insigma.command.LocalCommandExecutor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thymeleaf.util.StringUtils; |
|||
|
|||
import java.io.Closeable; |
|||
import java.io.IOException; |
|||
import java.io.InputStream; |
|||
import java.util.Arrays; |
|||
import java.util.Objects; |
|||
import java.util.Optional; |
|||
import java.util.concurrent.Callable; |
|||
import java.util.concurrent.ExecutionException; |
|||
import java.util.concurrent.ExecutorService; |
|||
import java.util.concurrent.Future; |
|||
import java.util.concurrent.SynchronousQueue; |
|||
import java.util.concurrent.ThreadPoolExecutor; |
|||
import java.util.concurrent.TimeUnit; |
|||
import java.util.concurrent.TimeoutException; |
|||
|
|||
|
|||
/** |
|||
* @author Vivim |
|||
*/ |
|||
@Slf4j |
|||
@Service |
|||
public class LocalCommandExecutorImpl implements LocalCommandExecutor { |
|||
|
|||
static ExecutorService pool = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 3L, TimeUnit.SECONDS, new SynchronousQueue()); |
|||
|
|||
@Override |
|||
public ExecuteResult executeCommand(String command, long timeout) { |
|||
Process process = null; |
|||
InputStream pIn = null; |
|||
InputStream pErr = null; |
|||
StreamGobbler outputGobbler = null; |
|||
StreamGobbler errorGobbler = null; |
|||
Future<Integer> executeFuture = null; |
|||
try { |
|||
log.debug("执行操作命令:{}", command); |
|||
process = Runtime.getRuntime().exec(command); |
|||
final Process p = process; |
|||
|
|||
// close process's output stream.
|
|||
p.getOutputStream().close(); |
|||
|
|||
pIn = process.getInputStream(); |
|||
outputGobbler = new StreamGobbler(pIn, "OUTPUT"); |
|||
outputGobbler.start(); |
|||
|
|||
pErr = process.getErrorStream(); |
|||
errorGobbler = new StreamGobbler(pErr, "ERROR"); |
|||
errorGobbler.start(); |
|||
|
|||
// create a Callable for the command's Process which can be called by an Executor
|
|||
Callable<Integer> call = () -> { |
|||
p.waitFor(); |
|||
return p.exitValue(); |
|||
}; |
|||
|
|||
// submit the command's call and get the result from a
|
|||
executeFuture = pool.submit(call); |
|||
int exitCode = executeFuture.get(timeout, TimeUnit.MILLISECONDS); |
|||
return new ExecuteResult(exitCode, outputGobbler.getContent()); |
|||
|
|||
} catch (IOException ex) { |
|||
String errorMessage = "The command [" + command + "] execute failed."; |
|||
log.error(errorMessage, ex); |
|||
return new ExecuteResult(-1, null); |
|||
} catch (TimeoutException ex) { |
|||
String errorMessage = "The command [" + command + "] timed out."; |
|||
log.error(errorMessage, ex); |
|||
return new ExecuteResult(-1, null); |
|||
} catch (ExecutionException ex) { |
|||
String errorMessage = "The command [" + command + "] did not complete due to an execution error."; |
|||
log.error(errorMessage, ex); |
|||
return new ExecuteResult(-1, null); |
|||
} catch (InterruptedException ex) { |
|||
String errorMessage = "The command [" + command + "] did not complete due to an interrupted error."; |
|||
log.error(errorMessage, ex); |
|||
return new ExecuteResult(-1, null); |
|||
} finally { |
|||
if (executeFuture != null) { |
|||
try { |
|||
executeFuture.cancel(true); |
|||
} catch (Exception ignore) { |
|||
ignore.printStackTrace(); |
|||
} |
|||
} |
|||
if (pIn != null) { |
|||
this.closeQuietly(pIn); |
|||
if (outputGobbler != null && !outputGobbler.isInterrupted()) { |
|||
outputGobbler.interrupt(); |
|||
} |
|||
} |
|||
if (pErr != null) { |
|||
this.closeQuietly(pErr); |
|||
if (errorGobbler != null && !errorGobbler.isInterrupted()) { |
|||
errorGobbler.interrupt(); |
|||
} |
|||
} |
|||
if (process != null) { |
|||
process.destroy(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void closeQuietly(Closeable c) { |
|||
try { |
|||
if (c != null) { |
|||
c.close(); |
|||
} |
|||
} catch (IOException e) { |
|||
log.error("exception", e); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public String getPort(String command, String keyword, long timeout){ |
|||
if(StringUtils.isEmpty(keyword)){ |
|||
return null; |
|||
} |
|||
ExecuteResult executeResult = executeCommand(command, timeout); |
|||
if(Objects.nonNull(executeResult) && executeResult.getExitCode() == 0){ |
|||
String executeOut = executeResult.getExecuteOut(); |
|||
if(!StringUtils.isEmpty(executeOut)){ |
|||
String[] split = executeOut.split("\n"); |
|||
Optional<String> first = Arrays.stream(split) |
|||
.filter(s -> s.contains(keyword)) |
|||
.findFirst(); |
|||
if(first.isPresent()){ |
|||
Optional<String[]> listening = first.map(s -> s.split("LISTENING")); |
|||
String[] strings = listening.get(); |
|||
if(strings.length == 2){ |
|||
return strings[1].trim(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
@ -0,0 +1,67 @@ |
|||
package com.insigma.command.impl; |
|||
|
|||
import java.io.BufferedReader; |
|||
import java.io.IOException; |
|||
import java.io.InputStream; |
|||
import java.io.InputStreamReader; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
/** |
|||
* @author Vivim |
|||
*/ |
|||
@Slf4j |
|||
public class StreamGobbler extends Thread { |
|||
private InputStream inputStream; |
|||
private String streamType; |
|||
private StringBuilder buf; |
|||
private volatile boolean isStopped = false; |
|||
|
|||
/** |
|||
* @param inputStream the InputStream to be consumed |
|||
* @param streamType the stream type (should be OUTPUT or ERROR) |
|||
*/ |
|||
public StreamGobbler(final InputStream inputStream, final String streamType) { |
|||
this.inputStream = inputStream; |
|||
this.streamType = streamType; |
|||
this.buf = new StringBuilder(); |
|||
this.isStopped = false; |
|||
} |
|||
|
|||
/** |
|||
* Consumes the output from the input stream and displays the lines consumed |
|||
* if configured to do so. |
|||
*/ |
|||
@Override |
|||
public void run() { |
|||
try { |
|||
// 默认编码为UTF-8,这里设置编码为GBK,因为WIN7的编码为GBK
|
|||
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "GBK"); |
|||
BufferedReader bufferedReader = new BufferedReader(inputStreamReader); |
|||
String line = null; |
|||
while ((line = bufferedReader.readLine()) != null) { |
|||
this.buf.append(line + "\n"); |
|||
} |
|||
} catch (IOException ex) { |
|||
log.error("Failed to successfully consume and display the input stream of type " + streamType + ".", ex); |
|||
} finally { |
|||
this.isStopped = true; |
|||
synchronized (this) { |
|||
notify(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public String getContent() { |
|||
if (!this.isStopped) { |
|||
synchronized (this) { |
|||
try { |
|||
wait(); |
|||
} catch (InterruptedException ignore) { |
|||
ignore.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
return this.buf.toString(); |
|||
} |
|||
} |
@ -1,17 +1,62 @@ |
|||
package com.insigma.controller; |
|||
|
|||
import com.alibaba.fastjson.JSONObject; |
|||
import com.insigma.entry.Vo; |
|||
import com.insigma.service.Computer; |
|||
import com.insigma.service.Database; |
|||
import com.insigma.service.Middleware; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Qualifier; |
|||
import org.springframework.web.bind.annotation.PostMapping; |
|||
import org.springframework.web.bind.annotation.RequestBody; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
/** |
|||
* @author Vivim |
|||
*/ |
|||
@Slf4j |
|||
@RestController |
|||
@RequestMapping("/swing") |
|||
public class TestController { |
|||
|
|||
@GetMapping("/hello") |
|||
public String hello(String helloWord){ |
|||
return helloWord; |
|||
@Qualifier("windowsTomcatMysql") |
|||
@Autowired |
|||
private Computer computer; |
|||
@Qualifier("windowsTomcatMysql") |
|||
@Autowired |
|||
private Database database; |
|||
@Qualifier("windowsTomcatMysql") |
|||
@Autowired |
|||
private Middleware middleware; |
|||
|
|||
@PostMapping("/runShell") |
|||
public JSONObject runShell(@RequestBody Vo vo){ |
|||
log.info("查询对象参数为:{}", vo); |
|||
boolean b = computer.runShell(vo.getShell(), false); |
|||
log.info("执行结果:{}", b); |
|||
return new JSONObject(); |
|||
} |
|||
|
|||
@PostMapping("/runBak") |
|||
public JSONObject runBak(@RequestBody Vo vo){ |
|||
log.info("查询对象参数为:{}", vo); |
|||
computer.runShell(vo.getShell(), false); |
|||
return new JSONObject(); |
|||
} |
|||
|
|||
@PostMapping("/runRestore") |
|||
public JSONObject runRestore(@RequestBody Vo vo){ |
|||
log.info("查询对象参数为:{}", vo); |
|||
computer.runShell(vo.getShell(), false); |
|||
return new JSONObject(); |
|||
} |
|||
|
|||
@PostMapping("/openServer") |
|||
public JSONObject openServer(@RequestBody Vo vo){ |
|||
log.info("查询对象参数为:{}", vo); |
|||
computer.openServer(); |
|||
return new JSONObject(); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,19 @@ |
|||
package com.insigma.entry; |
|||
|
|||
import lombok.Data; |
|||
import lombok.ToString; |
|||
|
|||
/** |
|||
* @author Vivim |
|||
*/ |
|||
@Data |
|||
@ToString |
|||
public class ExecuteResult { |
|||
private int exitCode; |
|||
private String executeOut; |
|||
|
|||
public ExecuteResult(int exitCode, String executeOut) { |
|||
this.exitCode = exitCode; |
|||
this.executeOut = executeOut; |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
package com.insigma.entry; |
|||
|
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Data; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* (Vo 类) |
|||
* |
|||
* @author zhangxianwei |
|||
* @since 16:40 2022/4/29 |
|||
*/ |
|||
@Data |
|||
@AllArgsConstructor |
|||
@NoArgsConstructor |
|||
public class Vo implements Serializable { |
|||
|
|||
/** |
|||
* 序列化编码ID |
|||
*/ |
|||
private static final long serialVersionUID = 1L; |
|||
|
|||
private String shell; |
|||
private String serverName; |
|||
private String path; |
|||
private String filePath; |
|||
} |
@ -1,16 +1,19 @@ |
|||
package com.insigma.utils; |
|||
|
|||
import cn.hutool.db.Session; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.junit.Test; |
|||
import static org.junit.jupiter.api.Assertions.*; |
|||
import java.sql.SQLException; |
|||
|
|||
@Slf4j |
|||
public class DbUtilTest { |
|||
|
|||
@Test |
|||
public void getSessionTest() throws SQLException { |
|||
Session session = DbUtil.getSession("jdbc:mysql://127.0.0.1:35017/hy_qggwy", "root", "admin", "com.mysql.jdbc.Driver"); |
|||
String queryString = session.queryString("select count(1) from a01 limit 1"); |
|||
String queryString = session.queryString("select count(1) from a01"); |
|||
log.info("对象:{} >> 查询带数据:{}", session, queryString); |
|||
assertNotEquals("0", queryString); |
|||
} |
|||
} |
Loading…
Reference in new issue