package _VisualDVM.Repository.Server; import Common.Database.Objects.DBObject; import Common.Database.RepositoryRefuseException; import Common.Utils.Utils_; import _VisualDVM.Constants; import _VisualDVM.Global; import _VisualDVM.GlobalData.Account.Account; import _VisualDVM.GlobalData.Machine.Machine; import _VisualDVM.GlobalData.Machine.MachineType; import _VisualDVM.GlobalData.RemoteFile.RemoteFile; import _VisualDVM.GlobalData.User.User; import _VisualDVM.Passes.All.ArchivesBackupPass; import _VisualDVM.Passes.All.UnzipFolderPass; import _VisualDVM.Passes.All.ZipFolderPass; import _VisualDVM.ProjectData.LanguageName; import _VisualDVM.Repository.BugReport.BugReport; import _VisualDVM.Repository.BugReport.Json.BugReportAdditionJson; import _VisualDVM.Repository.BugReportsDatabase; import _VisualDVM.Repository.Component.ComponentType; import _VisualDVM.Repository.Component.Json.ComponentPublicationInfoJson; import _VisualDVM.Repository.Component.Json.ComponentVersionsInfoJson; import _VisualDVM.Repository.EmailMessage; import _VisualDVM.Repository.RepositoryServer; import _VisualDVM.Repository.Subscribes.Subscriber; import _VisualDVM.Utils; import javafx.util.Pair; import org.apache.commons.io.FileUtils; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Vector; public class ComponentsServer extends RepositoryServer { public static final String server_dvm_drv = "/home/DVM/dvm_current/dvm_sys/bin/dvm_drv"; public static ZipFolderPass zip = new ZipFolderPass(); public static UnzipFolderPass unzip = new UnzipFolderPass(); public static ArchivesBackupPass backupSession = new ArchivesBackupPass(); //- public static Vector> storages = new Vector<>(Arrays.asList(new Pair<>(new Machine("titan", "dvmh.keldysh.ru", 22, MachineType.Server), new User("dvmuser1", "mprit_2011")) /* new Pair<>( new Machine("k100", "k100.kiam.ru", 22, MachineType.Server), new User("dvmuser1", "mprit_2011")) */)); //- protected Thread backUp = new Thread(() -> { while (true) { try { //------------------------------------- Calendar rightNow = Calendar.getInstance(); int year = rightNow.get(Calendar.YEAR); int month = rightNow.get(Calendar.MONTH); int day = rightNow.get(Calendar.DAY_OF_MONTH); int hour = rightNow.get(Calendar.HOUR_OF_DAY); int minute = rightNow.get(Calendar.MINUTE); if ((hour == Global.componentsServerProperties.BackupHour) && (minute == Global.componentsServerProperties.BackupMinute)) { //определить имя папки с багом. String backUpName = year + "_" + (month + 1) + "_" + (day); File todayBackUp = Paths.get(Global.DataBackUpsDirectory.getAbsolutePath(), backUpName).toFile(); File todayBackUpArchive = Paths.get(Global.DataBackUpsDirectory.getAbsolutePath(), backUpName + ".zip").toFile(); //- File bugsDBBackUp = Paths.get(todayBackUp.getAbsolutePath(), db.getFile().getName()).toFile(); File bugsArchives = Paths.get(todayBackUp.getAbsolutePath(), "Bugs.zip").toFile(); //- // Чистка старых бекапов на самом сервере. Utils.keepNewFiles(todayBackUp.getParentFile(), 2); if (!todayBackUpArchive.exists()) { FileUtils.forceMkdir(todayBackUp); Files.copy(db.getFile().toPath(), bugsDBBackUp.toPath()); //- zip.Do("Bugs", bugsArchives.getAbsolutePath()); zip.Do(todayBackUp.getAbsolutePath(), todayBackUpArchive.getAbsolutePath()); Utils_.forceDeleteWithCheck(todayBackUp); //- for (Pair cred : storages) { backupSession.Do(cred.getKey(), cred.getValue(), todayBackUpArchive); } //bonus backup //todo оформить как у планировщика, так как это нить, напрямую сервер трогать нельзя. if (rightNow.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) { EmailMessage message = new EmailMessage("db backup", "копия баз данных журнала ошибок"); message.addAttachement(db.getFile()); for (String address : Constants.admins_mails) { Email(message, address); } } } } //------------------------------------- Thread.sleep(60000); } catch (Exception ex) { Utils_.MainLog.PrintException(ex); } } }); public ComponentsServer() { super(BugReportsDatabase.class); } @Override public String getServerFileName() { return "VisualSapfor.jar"; } @Override public String getServerHomeName() { return "_sapfor_x64"; } @Override public int getPort() { return Constants.ComponentsServerPort; } @Override protected void beforePublishAction(DBObject object) throws Exception { if (object instanceof BugReport) { BugReport bugReport = (BugReport) object; if (bugReport.packed_archive != null) { File bugArchive = Utils_.getFile(Utils_.getHomePath(), "Bugs", bugReport.id); Utils_.bytesToFile(bugReport.packed_archive, bugArchive); } } } @Override protected void afterDeleteAction(DBObject object) throws Exception { if (object instanceof BugReport) { BugReport bugReport = (BugReport) object; if (!bugReport.project_version.isEmpty()) Utils_.forceDeleteWithCheck(bugReport.getArchiveFile()); } } @Override public void StartAction() throws Exception { if (Global.componentsServerProperties.EmailAdminsOnStart) { EmailMessage message = new EmailMessage("Сервер Sapfor запущен", new Date().toString()); for (String address : Constants.admins_mails) { Email(message, address); } } } private void DVMConvertProject() throws Exception { String[] args = request.arg.split("\n"); //- String projectName = args[0]; LanguageName projectLanguage = LanguageName.valueOf(args[1]); String options = args[2]; Vector filesNames = new Vector<>(Arrays.asList(args).subList(3, args.length)); //- File workspace = Utils.getTempFileName("convertation"); FileUtils.forceMkdir(workspace); File archive = new File(workspace, projectName + ".zip"); request.Unpack(archive); File project = new File(workspace, projectName); Vector badFiles = new Vector<>(); if (unzip.Do(archive.getAbsolutePath(), workspace.getAbsolutePath()) && project.exists()) { String output = ""; for (String fileName : filesNames) { File program = Paths.get(project.getAbsolutePath(), fileName).toFile(); //-- File convertedProgram = Paths.get(program.getParent(), Utils_.getFileNameWithoutExtension(program) + ".DVMH." + (projectLanguage.equals(LanguageName.fortran) ? "f" : "c")).toFile(); String command = Utils_.DQuotes(server_dvm_drv) + " " + projectLanguage.getDVMCompile() + "dv " + options + " " + Utils_.DQuotes(program.getName()); //-- File fileWorkspace = program.getParentFile(); Process process = Utils.startScript(workspace, fileWorkspace, Utils_.getDateName("convert_script"), command); process.waitFor(); String convertationOut = Utils.readAllOutput(process); convertationOut = convertationOut.replace(program.getName(), fileName); //для учета пути. if (!convertationOut.isEmpty()) output += convertationOut + "\n"; try { if (convertedProgram.exists()) { FileUtils.forceDelete(program); convertedProgram.renameTo(program); } else badFiles.add(program.getName()); } catch (Exception ex) { ex.printStackTrace(); } //-- } response.arg = String.join("\n", badFiles) + "|" + output; File resultArchive = new File(workspace, projectName + "_result.zip"); if (ComponentsServer.zip.Do(project.getAbsolutePath(), resultArchive.getAbsolutePath())) { response.object = Utils_.fileToBytes(resultArchive); } else throw new RepositoryRefuseException("Внутренняя ошибка. Не удалось запаковать версию"); //-- } else throw new RepositoryRefuseException("Внутренняя ошибка. Не удалось распаковать проект"); } private void GetComponentsVersionsInfo() throws Exception { Print("Получить информацию о версиях компонент"); Vector types = (Vector) request.object; Vector res = new Vector<>(); for (String sType : types) { ComponentType componentType = ComponentType.valueOf(sType); File actualVersionFile = Paths.get(Utils_.getHomePath(), "Components", sType, "version.txt").toFile(); File minimalVersionFile = Paths.get(Utils_.getHomePath(), "Components", sType, "minimal_version.txt").toFile(); ComponentVersionsInfoJson info = new ComponentVersionsInfoJson(componentType); info.actual_version = Utils_.removeCharacters(Utils.ReadAllText(actualVersionFile), "\n", "\r"); info.minimal_version = Utils_.removeCharacters(Utils.ReadAllText(minimalVersionFile), "\n", "\r"); res.add(info); } response = new ServerExchangeUnit_2021(ServerCode.OK); response.object = res; } private void AppendBugReportField() throws Exception { BugReportAdditionJson transport = (BugReportAdditionJson) request.object; Print("Дополнить поле " + request.arg + " баг репорта " + transport.id); if (db.bugReports.containsKey(transport.id)) { BugReport actual = db.bugReports.get(transport.id); Field field = BugReport.class.getField(transport.fieldName); field.set(actual, field.get(actual) + "\n" + transport.textAddition); actual.change_date = new Date().getTime(); db.Update(actual); response = new ServerExchangeUnit_2021(ServerCode.OK); response.object = actual; } else throw new RepositoryRefuseException("Баг репорт с ключом " + transport.id + " не существует."); } @Override protected void startAdditionalThreads() { backUp.start(); } //- private void UpdateComponent() throws Exception { ComponentPublicationInfoJson info = (ComponentPublicationInfoJson) request.object; Print("Опубликовать компонент " + info.componentType); File componentHome = Utils_.getFile(Utils_.getHomePath(), "Components", info.componentType.toString()); File componentFile = new File(componentHome, info.fileName); File versionFile = new File(componentHome, "version.txt"); File backupsFolder = new File(componentHome, "Backups"); //0 архивация старой версии, если она есть. if (componentFile.exists()) { String versionText = ""; if (versionFile.exists()) versionText = Utils.ReadAllText(versionFile); //---->> Utils_.CheckDirectory(backupsFolder); Utils.keepNewFiles(backupsFolder, Global.componentsServerProperties.ComponentsBackUpsCount); //-->> File backupFile = new File(backupsFolder, info.componentType + "_" + versionText); if (backupFile.exists()) Utils_.forceDeleteWithCheck(backupFile); FileUtils.moveFile(componentFile, backupFile); } //1 распаковка компонента Utils_.bytesToFile((byte[]) info.packedFile, componentFile); //2 запись версии компонента FileUtils.writeStringToFile(versionFile, info.versionText); //3 запись в журнал компонента File changesLog = new File(componentHome, "changes.txt"); FileWriter writer = new FileWriter(changesLog.getAbsolutePath(), true); BufferedWriter bufferWriter = new BufferedWriter(writer); bufferWriter.write(info.changeRecord); bufferWriter.close(); //- if (info.needsUpdateMinimalVersion) { Print("Поднять минимальную версию компонента " + info.componentType); File minimal_versionFile = new File(componentHome, "minimal_version.txt"); FileUtils.writeStringToFile(minimal_versionFile, info.versionText); //- //3 запись в журнал компонента FileWriter writer_ = new FileWriter(changesLog, true); BufferedWriter bufferWriter_ = new BufferedWriter(writer_); bufferWriter_.write("Минимальная версия поднята до " + info.versionText + "\n"); bufferWriter_.close(); } //- response = new ServerExchangeUnit_2021(ServerCode.OK); } private void CheckSubscriberRole() throws Exception { Account account = (Account) request.object; Subscriber subscriber = null; if (db.subscribers.containsKey(account.email)) { subscriber = db.subscribers.get(account.email); } else { subscriber = new Subscriber(); subscriber.name = account.name; subscriber.address = account.email; subscriber.mailOn = 1; db.Insert(subscriber); } response.object = subscriber; //возвращаем информацию о подписчике. } //-- @Override protected void Session() throws Exception { switch (code) { // case CheckSubscriberRole: Print("Проверить роль пользователя"); CheckSubscriberRole(); break; // // case ReceiveAllArchives: Print("Отправить клиенту архив всех архивов баг репортов"); ZipFolderPass zip = new ZipFolderPass(); File archives = new File(Utils_.getDateName("Bugs")); if (zip.Do("Bugs", archives.getAbsolutePath())) { response.object = Utils_.fileToBytes(archives); Print("Архив успешно запакован"); } else throw new RepositoryRefuseException("Не удалось запаковать архивы"); break; case UpdateBugReport: UpdateBugReport(); break; //-- case AppendBugReportTextField: AppendBugReportField(); break; //-- case ReceiveBugReportsDatabase: Print("Получить базу данных баг репортов"); response.object = Utils_.fileToBytes(db.getFile()); break; case ReceiveBugReport: Print("Скачать баг репорт по ключу " + request.arg); File bugArchive = Utils_.getFile(Utils_.getHomePath(), "Bugs", request.arg); response.object = Utils_.fileToBytes(bugArchive); break; case SendBugReport: //todo устарело Print("Отправить баг репорт " + request.arg); File bugArchive1 = Utils_.getFile(Utils_.getHomePath(), "Bugs", request.arg); Utils_.bytesToFile((byte[]) request.object, bugArchive1); break; // case GetComponentsBackups: Print("Получить список сохраненных версий компонента " + request.arg); File backupsDirectory = Paths.get(Utils_.getHomePath(), "Components", request.arg, "Backups").toFile(); //-- if (backupsDirectory.exists()) { File[] files = backupsDirectory.listFiles(File::isFile); if (files != null) { Vector res = new Vector<>(); for (File file : files) res.add(new RemoteFile(file.getAbsolutePath(), false)); //тут всегда линух. response.object = res; } else throw new RepositoryRefuseException("Не удалось получить список предыдущих версий"); } else { //баги еще не создавались. штатная ситуация. response.object = new Vector<>(); } break; case UpdateComponent: UpdateComponent(); break; case ReceiveComponent: String[] packed1 = request.arg.split("\n"); //тип/имя файла File componentFile1 = Paths.get(Utils_.getHomePath(), "Components", packed1[0], packed1[1]).toFile(); Print("Получить компонент " + packed1[0]); response.object = Utils_.fileToBytes(componentFile1); break; default: throw new RepositoryRefuseException("Неподдерживаемый код: " + code); case GetComponentsVersionsInfo: GetComponentsVersionsInfo(); break; case GetComponentChangesLog: Print("Получить журнал изменений компонента " + request.arg); response.object = Utils_.fileToBytes(Paths.get(Utils_.getHomePath(), "Components", request.arg, "changes.txt").toFile()); break; case CheckURLRegistered: Print("Проверить учетную запись на машине"); String[] data = request.arg.split("\n"); String email = data[0]; String machineURL = data[1]; String login = data[2]; response.object = db.workspaces.findWorkspace(email, machineURL, login); break; case DVMConvertProject: Print("Сконвертировать проект в DVM код"); DVMConvertProject(); break; } } void UpdateBugReport() throws Exception { BugReport oldBugReport = (BugReport) request.object; Print("Обновить баг репорт " + oldBugReport.id); if (db.bugReports.containsKey(oldBugReport.id)) { BugReport bugReport = db.bugReports.get(oldBugReport.id); bugReport.SynchronizeFields(oldBugReport); bugReport.change_date = new Date().getTime(); db.Update(bugReport); } else throw new RepositoryRefuseException("Баг репорт с ключом " + oldBugReport.id + " не существует."); } }