Files
VisualSapfor/src/_VisualDVM/TestingSystem/DVM/UserConnection.java
02090095 b37e20e4a4 ++
решение проблемы совместимости с java 1.8._4xx
2025-04-21 15:27:20 +03:00

570 lines
23 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package _VisualDVM.TestingSystem.DVM;
import Common.CommonConstants;
import Common.Passes.PassException;
import Common.Utils.Pair;
import Common.Utils.Utils_;
import _VisualDVM.Constants;
import _VisualDVM.GlobalData.Machine.Machine;
import _VisualDVM.GlobalData.RemoteFile.RemoteFile;
import _VisualDVM.GlobalData.User.User;
import _VisualDVM.ProjectData.Project.db_project_info;
import _VisualDVM.Utils;
import com.jcraft.jsch.*;
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; //для тестирования
//--
public ChannelSftp sftpChannel = null;
public ChannelShell shellChannel = null;
public ChannelExec execChannel = null;
//--
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;
//--
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) {
Utils_.MainLog.PrintException(exception);
}
}
if (out != null) {
try {
out.close();
} catch (Exception exception) {
Utils_.MainLog.PrintException(exception);
}
}
if (pin != null) {
try {
pin.close();
} catch (Exception exception) {
Utils_.MainLog.PrintException(exception);
}
}
if (pout != null) {
try {
pout.close();
} catch (Exception exception) {
Utils_.MainLog.PrintException(exception);
}
}
if (fromServer != null) {
try {
fromServer.close();
} catch (Exception exception) {
Utils_.MainLog.PrintException(exception);
}
}
if (sftpChannel != null) sftpChannel.disconnect();
if (shellChannel != null) shellChannel.disconnect();
if (execChannel != null) execChannel.disconnect();
if (session != null) {
session.disconnect();
}
//----------------------
sftpChannel = null;
shellChannel = null;
execChannel = null;
session = null;
//---
in = null;
out = null;
//---
pin = null;
pout = null;
fromServer = null;
jsch = null;
System.gc();
}
public void getSingleFile(String src, String dst) throws Exception {
sftpChannel.get(src, dst);
}
public long getFileKBSize(String path) throws Exception {
long size = sftpChannel.lstat(path).getSize();
return size / 1024;
}
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 {
Utils.WriteToFile(dst, "Размер файла превышает " + maxSize + " KB.\n" + "Файл не загружен. Его можно просмотреть на машине по адресу\n" + Utils_.Brackets(src.full_name));
}
}
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);
}
//-
public void RMDIR(String dir) throws Exception {
if (!dir.isEmpty() && !dir.equals("/") && !dir.equals("\\") && !dir.equals("*")) {
Command("rm -rf " + Utils_.DQuotes(dir));
} else throw new PassException("Недопустимый путь для удаления папки " + Utils_.DQuotes(dir));
}
//-
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)) {
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);
}
//--
writeToFile("cd " + Utils_.DQuotes(directory.full_name) + "\n" + String.join("\n", commands), script_file);
//--
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 {
boolean planner = module_name.equals("planner");
String flags = planner ? getAvailibleCPPStandard(modulesDirectory) : "";
String command = "g++ -O3 " + flags + " " + Utils_.DQuotes(module_name + ".cpp") + " -o " + Utils_.DQuotes(module_name);
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)
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 {
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) {
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) {
Utils_.MainLog.PrintException(exception);
}
}
if (out != null) {
try {
out.close();
} catch (Exception exception) {
Utils_.MainLog.PrintException(exception);
}
}
if (pin != null) {
try {
pin.close();
} catch (Exception exception) {
Utils_.MainLog.PrintException(exception);
}
}
if (pout != null) {
try {
pout.close();
} catch (Exception exception) {
Utils_.MainLog.PrintException(exception);
}
}
if (fromServer != null) {
try {
fromServer.close();
} catch (Exception exception) {
Utils_.MainLog.PrintException(exception);
}
}
if (shellChannel != null) shellChannel.disconnect();
//--
in = null;
out = null;
pin = null;
pout = null;
fromServer = null;
shellChannel = null;
System.gc();
}
*/
public void waitForFileCreation(RemoteFile file) throws Exception {
while (!Exists(file)) {
System.out.println(file.full_name + " NOT FOUND");
Utils_.sleep(1000);
}
}
public void waitForFileFree(RemoteFile file) throws Exception {
while (!Busy(file)) {
System.out.println(file.full_name + " PERMISSION DENIED");
Utils_.sleep(1000);
}
}
public void startShellProcess(RemoteFile directory, String outFileName, String... commands) throws Exception {
Vector<String> commands_ = new Vector<>();
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);
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");
}
//-- проверка существования рабочего пространства.
public void CheckUserInitialization(String email) throws Exception {
RemoteFile userWorkspace = new RemoteFile(user.workspace, true);
if (!Exists(userWorkspace)) {
sftpChannel.mkdir(userWorkspace.full_name);
//--
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);
//--
RemoteFile info = new RemoteFile(userWorkspace, email);
user.connection.writeToFile("", info);
}
}
//--
public String CheckModulesVersion() throws Exception {
RemoteFile modulesDirectory = new RemoteFile(user.workspace, "modules");
RemoteFile version = new RemoteFile(modulesDirectory, "version.h");
int current_version = CommonConstants.Nan;
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 "";
}
}