Files
VisualSapfor/src/_VisualDVM/TestingSystem/DVM/UserConnection.java

570 lines
23 KiB
Java
Raw Normal View History

2024-10-09 22:21:57 +03:00
package _VisualDVM.TestingSystem.DVM;
2024-10-07 14:22:52 +03:00
import Common.CommonConstants;
2024-10-14 15:19:13 +03:00
import Common.Passes.PassException;
2024-10-11 00:00:30 +03:00
import Common.Utils.Utils_;
2024-10-09 22:01:19 +03:00
import _VisualDVM.Constants;
2024-10-09 22:21:57 +03:00
import _VisualDVM.GlobalData.Machine.Machine;
import _VisualDVM.GlobalData.RemoteFile.RemoteFile;
import _VisualDVM.GlobalData.User.User;
import _VisualDVM.ProjectData.Project.db_project_info;
2024-10-14 15:19:13 +03:00
import _VisualDVM.Utils;
import com.jcraft.jsch.*;
import javafx.util.Pair;
2023-09-17 22:13:42 +03:00
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Vector;
public class UserConnection {
//http://www.jcraft.com/jsch/
public int iterations = 0; //для тестирования
//--
2023-09-17 22:13:42 +03:00
public ChannelSftp sftpChannel = null;
public ChannelShell shellChannel = null;
public ChannelExec execChannel = null;
2023-09-17 22:13:42 +03:00
//--
JSch jsch = null;
Session session = null;
//---
PipedInputStream in = null;
PipedOutputStream out = null;
//---
PipedOutputStream pin = null;
PipedInputStream pout = null;
InputStreamReader fromServer = null;
//---
Machine machine = null;
User user = null;
//---
public UserConnection(Machine machine_in, User user_in) throws Exception {
machine = machine_in;
user = user_in;
//--
2023-09-17 22:13:42 +03:00
session = (jsch = new JSch()).getSession(user.login, machine.address, machine.port);
session.setPassword(user.password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect(0);
//-->
//создать канал для файлов
sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
//-->
//создать канал для команд
}
public void Disconnect() {
if (in != null) {
try {
in.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
2023-09-17 22:13:42 +03:00
}
}
if (out != null) {
try {
out.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
2023-09-17 22:13:42 +03:00
}
}
if (pin != null) {
try {
pin.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
2023-09-17 22:13:42 +03:00
}
}
if (pout != null) {
try {
pout.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
2023-09-17 22:13:42 +03:00
}
}
if (fromServer != null) {
try {
fromServer.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
2023-09-17 22:13:42 +03:00
}
}
if (sftpChannel != null) sftpChannel.disconnect();
if (shellChannel != null) shellChannel.disconnect();
if (execChannel != null) execChannel.disconnect();
if (session != null) {
session.disconnect();
}
2023-09-17 22:13:42 +03:00
//----------------------
sftpChannel = null;
shellChannel = null;
execChannel = null;
2023-09-17 22:13:42 +03:00
session = null;
//---
in = null;
out = null;
//---
pin = null;
pout = null;
fromServer = null;
jsch = null;
2023-09-17 22:13:42 +03:00
System.gc();
}
public void getSingleFile(String src, String dst) throws Exception {
sftpChannel.get(src, dst);
}
public long getFileKBSize(String path) throws Exception {
2023-09-17 22:13:42 +03:00
long size = sftpChannel.lstat(path).getSize();
return size / 1024;
2023-09-17 22:13:42 +03:00
}
public void getSingleFileWithMaxSize(RemoteFile src, File dst, int maxSize) throws Exception {
if ((maxSize == 0) || getFileKBSize(src.full_name) <= maxSize) {
getSingleFile(src.full_name, dst.getAbsolutePath());
} else {
2024-10-11 00:00:30 +03:00
Utils.WriteToFile(dst, "Размер файла превышает " + maxSize + " KB.\n" + "Файл не загружен. Его можно просмотреть на машине по адресу\n" + Utils_.Brackets(src.full_name));
2023-09-17 22:13:42 +03:00
}
}
public void putSingleFile(File src, RemoteFile dst) throws Exception {
sftpChannel.put(src.getAbsolutePath(), dst.full_name);
}
//-
public void MKDIR(RemoteFile dir) throws Exception {
if (!Exists(dir)) sftpChannel.mkdir(dir.full_name);
2023-09-17 22:13:42 +03:00
}
//-
public void RMDIR(String dir) throws Exception {
if (!dir.isEmpty() && !dir.equals("/") && !dir.equals("\\") && !dir.equals("*")) {
2024-10-11 00:00:30 +03:00
Command("rm -rf " + Utils_.DQuotes(dir));
} else throw new PassException("Недопустимый путь для удаления папки " + Utils_.DQuotes(dir));
2023-09-17 22:13:42 +03:00
}
//-
public void SynchronizeSubDirsR(File local_dir, RemoteFile remote_dir) throws Exception {
File[] local_subdirs = local_dir.listFiles(File::isDirectory);
File[] local_files = local_dir.listFiles(File::isFile);
//------------------------------------------------------------------------
LinkedHashMap<String, RemoteFile> remote_subdirs = new LinkedHashMap<>();
LinkedHashMap<String, RemoteFile> remote_files = new LinkedHashMap<>();
Vector<ChannelSftp.LsEntry> files = sftpChannel.ls(remote_dir.full_name);
for (ChannelSftp.LsEntry file : files) {
if (file.getAttrs().isDir()) {
if (!file.getFilename().equals(".") && !file.getFilename().equals(".."))
remote_subdirs.put(file.getFilename(), new RemoteFile(remote_dir.full_name, file.getFilename(), true));
} else {
RemoteFile rf = new RemoteFile(remote_dir.full_name, file.getFilename());
rf.updateTime = RemoteFile.convertUpdateTime(file.getAttrs().getMTime());
remote_files.put(file.getFilename(), rf);
}
}
if (local_subdirs != null) {
for (File lsd : local_subdirs) {
if (!lsd.getName().equals(Constants.data)) {
2023-09-17 22:13:42 +03:00
RemoteFile rsd = null;
if (!remote_subdirs.containsKey(lsd.getName()))
sftpChannel.mkdir((rsd = new RemoteFile(remote_dir.full_name, lsd.getName(), true)).full_name);
else rsd = remote_subdirs.get(lsd.getName());
SynchronizeSubDirsR(lsd, rsd);
}
}
}
if (local_files != null) {
for (File lf : local_files) {
RemoteFile rf = null;
if (!remote_files.containsKey(lf.getName())) {
rf = new RemoteFile(remote_dir.full_name, lf.getName());
putSingleFile(lf, rf);
} else {
rf = remote_files.get(lf.getName());
if (lf.lastModified() > rf.updateTime) {
putSingleFile(lf, rf);
}
}
}
}
}
public void writeToFile(String text, RemoteFile dst) throws Exception {
sftpChannel.put(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), dst.full_name);
sftpChannel.chmod(0777, dst.full_name);
}
public String readFromFile(RemoteFile src) throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
sftpChannel.get(src.full_name, outputStream);
return outputStream.toString(StandardCharsets.UTF_8.name());
}
//--
public boolean Exists(String file_full_name) throws Exception {
try {
sftpChannel.lstat(file_full_name);
return true;
} catch (SftpException e) {
if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
// file doesn't exist
return false;
} else {
// something else went wrong
throw e;
}
}
}
public boolean Busy(String file_full_name) throws Exception {
try {
sftpChannel.lstat(file_full_name);
return true;
} catch (SftpException e) {
if (e.id == ChannelSftp.SSH_FX_PERMISSION_DENIED) {
// file busy
return false;
} else {
// something else went wrong
throw e;
}
}
}
public boolean Busy(RemoteFile file) throws Exception {
return Busy(file.full_name);
}
public boolean Exists(RemoteFile file) throws Exception {
return Exists(file.full_name);
}
//--
public Pair<RemoteFile, RemoteFile> performScript(RemoteFile directory, String... commands) throws Exception {
RemoteFile script_file = new RemoteFile(directory, Constants.script);
RemoteFile out = new RemoteFile(directory, Constants.out_file);
RemoteFile err = new RemoteFile(directory, Constants.err_file);
//
Vector<RemoteFile> files = new Vector<>();
files.add(script_file);
files.add(out);
files.add(err);
for (RemoteFile file : files) {
if (Exists(file))
sftpChannel.rm(file.full_name);
}
//--
2024-10-11 00:00:30 +03:00
writeToFile("cd " + Utils_.DQuotes(directory.full_name) + "\n" + String.join("\n", commands), script_file);
//--
2024-10-11 00:00:30 +03:00
Command(Utils_.DQuotes(script_file.full_name) + " 1>" + Utils_.DQuotes(out.full_name) + " 2>" + Utils_.DQuotes(err.full_name));
return new Pair<>(out, err);
}
public void putResource(RemoteFile dstDirectory, String resource_name) throws Exception {
File src = Utils.CreateTempResourceFile(resource_name);
RemoteFile dst = new RemoteFile(dstDirectory, resource_name);
putSingleFile(src, dst);
}
boolean compileModule(RemoteFile modulesDirectory, String module_name) throws Exception {
2025-02-06 19:20:15 +03:00
boolean planner = module_name.equals("planner");
String flags = planner ? getAvailibleCPPStandard(modulesDirectory) : "";
2024-10-11 00:00:30 +03:00
String command = "g++ -O3 " + flags + " " + Utils_.DQuotes(module_name + ".cpp") + " -o " + Utils_.DQuotes(module_name);
2025-03-13 00:32:20 +03:00
if (planner && flags.contains("c++17")) command += " -lstdc++fs";
RemoteFile binary = new RemoteFile(modulesDirectory, module_name);
//--
if (Exists(binary))
sftpChannel.rm(binary.full_name);
//--
performScript(modulesDirectory, command);
//--
if (Exists(binary)) {
sftpChannel.chmod(0777, binary.full_name);
return true;
}
return false;
}
String getAvailibleCPPStandard(RemoteFile scriptDirectory) throws Exception {
String res = "";
String command = "g++ -v --help 2> /dev/null | sed -n '/^ *-std=\\([^<][^ ]\\+\\).*/ {s//\\1/p}' | grep c++";
Pair<RemoteFile, RemoteFile> oe = performScript(scriptDirectory, command);
RemoteFile outFile = oe.getKey();
String out = readFromFile(outFile);
//--
RemoteFile cppVersionsInfo = new RemoteFile(scriptDirectory, "cpp_versions.txt");
sftpChannel.rename(outFile.full_name, cppVersionsInfo.full_name);
//--
String[] data = out.split("\n");
boolean cpp_17 = false;
boolean cpp_11 = false;
//определить какие есть версии.
for (String version : data) {
switch (version) {
case "c++17":
cpp_17 = true;
break;
case "c++11":
cpp_11 = true;
break;
}
}
if (cpp_17)
2025-02-06 19:20:15 +03:00
res = "-std=c++17";
else if (cpp_11)
res = "-std=c++11";
RemoteFile cppFlag = new RemoteFile(scriptDirectory, "current_ccp_version");
writeToFile(res, cppFlag);
return res;
}
public String compileModules(RemoteFile modulesDirectory) throws Exception {
if (!compileModule(modulesDirectory, "launcher")) {
return "Не удалось собрать модуль [launcher]";
}
if (!compileModule(modulesDirectory, "starter")) {
return "Не удалось собрать модуль [starter]";
}
if (!compileModule(modulesDirectory, "planner")) {
return "Не удалось собрать модуль [planner]";
}
return "";
}
//--
public void tryRM(RemoteFile file) throws Exception {
if (Exists(file))
sftpChannel.rm(file.full_name);
}
//с проверкой.
public boolean tryGetSingleFileWithMaxSize(RemoteFile src, File dst, int maxSize) throws Exception {
if (Exists(src)) {
if ((maxSize == 0) || (getFileKBSize(src.full_name) <= maxSize)) {
getSingleFile(src.full_name, dst.getAbsolutePath());
return true;
} else {
2024-10-11 00:00:30 +03:00
Utils.WriteToFile(dst, "Размер файла превышает " + maxSize + " KB.\n" + "Файл не загружен. Его можно просмотреть на машине по адресу\n" + Utils_.Brackets(src.full_name));
}
}
return false;
}
//--
public void SynchronizeProjectSubDirsR(db_project_info project, File local_dir, RemoteFile remote_dir, boolean data) throws Exception {
// ShowMessage2("синхронизация: " + local_dir.getName());
Vector<File> local_subdirs = project.getSubdirectoriesSimple(local_dir);
Vector<File> local_files = project.getActiveFilesForSynchronization(local_dir, data);
//------------------------------------------------------------------------
LinkedHashMap<String, RemoteFile> remote_subdirs = new LinkedHashMap<>();
LinkedHashMap<String, RemoteFile> remote_files = new LinkedHashMap<>();
Vector<ChannelSftp.LsEntry> files = sftpChannel.ls(remote_dir.full_name);
for (ChannelSftp.LsEntry file : files) {
if (file.getAttrs().isDir()) {
if (!file.getFilename().equals(".") && !file.getFilename().equals(".."))
remote_subdirs.put(file.getFilename(), new RemoteFile(remote_dir.full_name, file.getFilename(), true));
} else {
RemoteFile rf = new RemoteFile(remote_dir.full_name, file.getFilename());
rf.updateTime = RemoteFile.convertUpdateTime(file.getAttrs().getMTime());
remote_files.put(file.getFilename(), rf);
}
}
for (File lsd : local_subdirs) {
RemoteFile rsd = null;
if (!remote_subdirs.containsKey(lsd.getName()))
sftpChannel.mkdir((rsd = new RemoteFile(remote_dir.full_name, lsd.getName(), true)).full_name);
else rsd = remote_subdirs.get(lsd.getName());
SynchronizeProjectSubDirsR(project, lsd, rsd, data);
}
for (File lf : local_files) {
RemoteFile rf = null;
if (!remote_files.containsKey(lf.getName())) {
rf = new RemoteFile(remote_dir.full_name, lf.getName());
// ShowMessage2(lf.getName());
putSingleFile(lf, rf);
} else {
rf = remote_files.get(lf.getName());
if (lf.lastModified() > rf.updateTime) {
// ShowMessage2(lf.getName());
putSingleFile(lf, rf);
}
}
}
}
//--
public Vector<RemoteFile> getFilesByExtensions(RemoteFile dir, String... extensions) throws Exception {
Vector<RemoteFile> res = new Vector<>();
Vector<ChannelSftp.LsEntry> files = sftpChannel.ls(dir.full_name);
for (ChannelSftp.LsEntry file : files) {
String[] data = file.getFilename().split("\\.");
if (data.length > 1) {
String file_extension = data[data.length - 1];
for (String extension : extensions) {
if (file_extension.equalsIgnoreCase(extension))
res.add(new RemoteFile(dir.full_name, file.getFilename()));
}
}
}
return res;
}
public void deleteFilesByExtensions(RemoteFile dir, String... extensions) throws Exception {
Vector<RemoteFile> to_delete = getFilesByExtensions(dir, extensions);
for (RemoteFile file : to_delete)
sftpChannel.rm(file.full_name);
}
public void Command(String... commands) throws Exception {
if (commands.length > 0) {
String command = String.join("\n", commands);
execChannel = (ChannelExec) session.openChannel("exec");
execChannel.setErrStream(System.err);
execChannel.setCommand(command);
execChannel.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(execChannel.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
2024-10-11 00:00:30 +03:00
System.out.println(Utils_.Brackets(line));
}
}
execChannel.disconnect();
}
public void CommandNoWait(String... commands) throws Exception {
if (commands.length > 0) {
String command = String.join("\n", commands);
execChannel = (ChannelExec) session.openChannel("exec");
execChannel.setErrStream(System.err);
execChannel.setCommand(command);
execChannel.connect();
execChannel.disconnect();
}
}
//-----
/*
public void ShellConnect() throws Exception {
shellChannel = (ChannelShell) session.openChannel("shell");
in = new PipedInputStream();
out = new PipedOutputStream();
//--
shellChannel.setInputStream(in);
shellChannel.setOutputStream(out);
pin = new PipedOutputStream(in);
pout = new PipedInputStream(out);
shellChannel.connect();
//-
fromServer = new InputStreamReader(pout);
}
public void ShellDisconnect() throws Exception {
if (in != null) {
try {
in.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
}
}
if (out != null) {
try {
out.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
}
}
if (pin != null) {
try {
pin.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
}
}
if (pout != null) {
try {
pout.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
}
}
if (fromServer != null) {
try {
fromServer.close();
} catch (Exception exception) {
2024-10-11 00:00:30 +03:00
Utils_.MainLog.PrintException(exception);
}
}
if (shellChannel != null) shellChannel.disconnect();
//--
in = null;
out = null;
pin = null;
pout = null;
fromServer = null;
shellChannel = null;
System.gc();
}
*/
2024-04-26 22:21:56 +03:00
public void waitForFileCreation(RemoteFile file) throws Exception {
while (!Exists(file)) {
System.out.println(file.full_name + " NOT FOUND");
2024-10-11 00:00:30 +03:00
Utils_.sleep(1000);
2024-04-26 22:21:56 +03:00
}
}
public void waitForFileFree(RemoteFile file) throws Exception {
while (!Busy(file)) {
System.out.println(file.full_name + " PERMISSION DENIED");
2024-10-11 00:00:30 +03:00
Utils_.sleep(1000);
}
}
2024-11-29 16:33:46 +03:00
public void startShellProcess(RemoteFile directory, String outFileName, String... commands) throws Exception {
Vector<String> commands_ = new Vector<>();
2024-10-11 00:00:30 +03:00
commands_.add("cd " + Utils_.DQuotes(directory.full_name));
for (int i = 0; i < commands.length; ++i) {
if (i == commands.length - 1) {
commands_.add(commands[i] + " 1>" + Utils_.DQuotes(outFileName) + " 2>err.txt");
} else {
commands_.add(commands[i]);
}
}
RemoteFile script_file = new RemoteFile(directory, Constants.script);
if (Exists(script_file))
sftpChannel.rm(script_file.full_name);
writeToFile(String.join("\n", commands_), script_file);
2024-10-11 00:00:30 +03:00
String start_command = Utils_.DQuotes(script_file.full_name);
//--
RemoteFile outFile = new RemoteFile(directory, outFileName);
if (Exists(outFile))
sftpChannel.rm(outFile.full_name);
//--
System.out.println("nohup " + start_command + " &\r\n");
execChannel = (ChannelExec) session.openChannel("exec");
execChannel.setErrStream(System.err);
execChannel.setCommand("nohup " + start_command + " &\r\n");
execChannel.connect();
execChannel.disconnect();
System.out.println("done");
}
2024-05-22 00:09:01 +03:00
//-- проверка существования рабочего пространства.
2024-05-21 23:20:50 +03:00
public void CheckUserInitialization(String email) throws Exception {
RemoteFile userWorkspace = new RemoteFile(user.workspace, true);
2024-05-22 00:09:01 +03:00
if (!Exists(userWorkspace)) {
sftpChannel.mkdir(userWorkspace.full_name);
//--
2024-05-22 00:09:01 +03:00
RemoteFile modulesDirectory = new RemoteFile(userWorkspace, "modules");
RemoteFile projectsDirectory = new RemoteFile(userWorkspace, "projects");
RemoteFile testsDirectory = new RemoteFile(userWorkspace, "tests");
//--
Vector<RemoteFile> subdirectories = new Vector<>();
subdirectories.add(modulesDirectory);
subdirectories.add(projectsDirectory);
subdirectories.add(testsDirectory);
for (RemoteFile remoteFile : subdirectories)
sftpChannel.mkdir(remoteFile.full_name);
//--
for (String resource_name : Constants.resourses_names) {
putResource(modulesDirectory, resource_name);
}
//-
String modules_log = compileModules(modulesDirectory);
if (!modules_log.isEmpty())
throw new PassException(modules_log);
2024-05-21 23:48:01 +03:00
//--
2024-05-21 23:20:50 +03:00
RemoteFile info = new RemoteFile(userWorkspace, email);
user.connection.writeToFile("", info);
}
}
2024-05-22 00:09:01 +03:00
//--
public String CheckModulesVersion() throws Exception {
RemoteFile modulesDirectory = new RemoteFile(user.workspace, "modules");
RemoteFile version = new RemoteFile(modulesDirectory, "version.h");
2024-10-07 14:22:52 +03:00
int current_version = CommonConstants.Nan;
2024-05-22 00:09:01 +03:00
int actual_version = Constants.planner_version;
if (Exists(version)) {
try {
current_version = Integer.parseInt(readFromFile(version));
} catch (Exception ex) {
ex.printStackTrace();
}
}
if (current_version < actual_version) {
for (String resource_name : Constants.resourses_names) {
putResource(modulesDirectory, resource_name);
}
//--
return compileModules(modulesDirectory);
}
return "";
}
}