package Repository; import Common.Utils.CommonUtils; import _VisualDVM.Constants; import Common.Database.Objects.DBObject; import Common.Database.Database; import _VisualDVM.Global; import Common.Utils.InterruptThread; import _VisualDVM.Utils; import Repository.Server.DiagnosticSignalHandler; import Repository.Server.ServerCode; import Repository.Server.ServerExchangeUnit_2021; import javafx.util.Pair; import sun.misc.SignalHandler; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; import java.util.LinkedHashMap; import java.util.Properties; import java.util.Vector; public abstract class RepositoryServer { Class d_class; protected Socket clientSocket; //сокет для общения protected ServerSocket server; // серверсокет protected ObjectInputStream in; // поток чтения из сокета protected ObjectOutputStream out; // поток записи в сокет //- public D db; protected static FileWriter Log; protected ServerExchangeUnit_2021 request; protected ServerExchangeUnit_2021 response; //- protected ServerCode code; protected long count = 0; //для отладки. protected static boolean printOn = false; //----------- SignalHandler signalHandler = signal -> { }; //------------ public abstract int getPort(); protected abstract void Session() throws Exception; protected void startAdditionalThreads() { } public final static String separator = "----------------------------------"; public RepositoryServer(Class d_class_in) { d_class = d_class_in; } public void ActivateDB() { try { db = d_class.newInstance(); db.Connect(); db.CreateAllTables(); db.prepareTablesStatements(); db.Synchronize(); } catch (Exception ex) { ex.printStackTrace(); } } protected Thread interruptThread = new InterruptThread(10000, () -> { System.exit(0); return null; }); protected static void Print(String message) { if (printOn) { try { Log = new FileWriter("Log.txt", true); String dmessage = CommonUtils.Brackets("SESSION -> ") + new Date() + " " + message; Log.write(dmessage + "\n"); Log.close(); } catch (Exception ex) { ex.printStackTrace(); } } } protected void checkTargets(EmailMessage message_in) { } public void Email(EmailMessage message_in, File... directAttachements) throws Exception { checkTargets(message_in); Thread thread = new Thread(() -> { try { Properties props = new Properties(); props.put("mail.smtp.host", Global.properties.SMTPHost); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", String.valueOf(Global.properties.SMTPPort)); props.put("mail.smtp.socketFactory.port", String.valueOf(Global.properties.MailSocketPort)); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.connectiontimeout", String.valueOf(Global.properties.SocketTimeout)); props.put("mail.smtp.timeout", String.valueOf(Global.properties.SocketTimeout)); props.put("mail.smtp.writetimeout", String.valueOf(Global.properties.SocketTimeout)); //------------------------------ LinkedHashMap innerFiles = new LinkedHashMap<>(); for (String aName : message_in.files.keySet()) { File f = Utils.getTempFileName(aName); CommonUtils.bytesToFile(message_in.files.get(aName), f); innerFiles.put(aName, f); } Vector targets_ = new Vector<>(message_in.targets); Utils.addDefaultMails(targets_); //------------------------------ Session session = Session.getDefaultInstance(props, new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication( Constants.MailAddress, Constants.MailPassword); } }); for (String target : targets_) { boolean done = false; int attempts = 5; while (!done && (attempts > 0)) { try { MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(Constants.MailAddress)); message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(target)); message.setSubject(message_in.subject); Multipart multipart = new MimeMultipart(); MimeBodyPart textBodyPart = new MimeBodyPart(); textBodyPart.setText(message_in.text); multipart.addBodyPart(textBodyPart); for (String aName : innerFiles.keySet()) { MimeBodyPart attachmentBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(innerFiles.get(aName)); attachmentBodyPart.setDataHandler(new DataHandler(source)); attachmentBodyPart.setFileName(aName); multipart.addBodyPart(attachmentBodyPart); } for (File f : directAttachements) { if (f.exists()) { MimeBodyPart attachmentBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(f); attachmentBodyPart.setDataHandler(new DataHandler(source)); attachmentBodyPart.setFileName(f.getName()); multipart.addBodyPart(attachmentBodyPart); } } message.setContent(multipart); Transport.send(message); done = true; } catch (Exception ex) { System.out.println("Исключение во время отправки сообщения абоненту " + CommonUtils.Brackets(target)); ex.printStackTrace(); CommonUtils.sleep(1000); } finally { attempts--; } } } } catch (Exception ex) { System.out.println("Исключение во время выполнения рассылки."); ex.printStackTrace(); } }); thread.start(); } public boolean canDelete(DBObject object) throws Exception { return true; } public void StartAction() throws Exception { } public void Start() throws Exception { /* File started = new File(Constants.STARTED); if (started.exists()) FileUtils.forceDelete(started); Utils.createEmptyFile(Constants.STARTED); */ DiagnosticSignalHandler.install("TERM", signalHandler); DiagnosticSignalHandler.install("INT", signalHandler); DiagnosticSignalHandler.install("ABRT", signalHandler); interruptThread.start(); startAdditionalThreads(); server = new ServerSocket(getPort()); Print("Сервер запущен!"); StartAction(); while (true) { try { clientSocket = server.accept(); Print((count++) + " клиент присоединился, IP=" + clientSocket.getInetAddress()); code = ServerCode.Undefined; out = new ObjectOutputStream(clientSocket.getOutputStream()); in = new ObjectInputStream(clientSocket.getInputStream()); //-> while (true) { DBObject dbObject = null; Pair p = null; Print("Ожидание команды от клиента..."); Object transport = in.readObject(); Print("Команда прочитана."); if (transport instanceof ServerExchangeUnit_2021) { request = (ServerExchangeUnit_2021) transport; response = null; Print("клиент_2021: <- " + (request.codeName)); try { code = request.getCode(); //базовый функционал. switch (code) { // case ReadFile: Print("Отправить клиенту текст файла по пути " + CommonUtils.Brackets(request.arg)); response = new ServerExchangeUnit_2021(ServerCode.OK, "", Utils.ReadAllText(new File(request.arg))); break; case SendFile: //нам пришел файл. Print("Получить от клиента файл, и распаковать его по пути " + CommonUtils.Brackets(request.arg)); request.Unpack(); //распаковка идет по его аргу-пути назначения response = new ServerExchangeUnit_2021(ServerCode.OK); break; case ReceiveFile: Print("Отправить клиенту файл по пути " + CommonUtils.Brackets(request.arg)); response = new ServerExchangeUnit_2021(ServerCode.OK); File file = new File(request.arg); response.object = file.exists() ? CommonUtils.fileToBytes(file) : null; break; case Email: Print("Отправка сообщения электронной почты"); Email((EmailMessage) request.object); response = new ServerExchangeUnit_2021(ServerCode.OK); break; // // case CheckObjectExistense: p = (Pair) request.object; Print("Проверить существование объекта класса " + p.getKey().toString() + " с ключом " + p.getValue()); response = new ServerExchangeUnit_2021(ServerCode.OK); response.object = db.checkObjectExistense(p.getKey(), p.getValue()); break; case EditObject: DBObject new_object = (DBObject) request.object; Print("Редактировать объект " + new_object.getPK()); db.UpdateWithCheck(new_object); afterEditAction(new_object); response = new ServerExchangeUnit_2021(ServerCode.OK); break; case DeleteObject: //устарело. потом убрать. сейчас на это баг репорты повязаны. dbObject = (DBObject) request.object; Print("Удалить объект " + dbObject.getPK()); db.DeleteWithCheck(dbObject); afterDeleteAction(dbObject); response = new ServerExchangeUnit_2021(ServerCode.OK); break; case GetObjectCopyByPK: p = (Pair) request.object; Print("Получить копию объекта класса " + p.getKey().toString() + " по ключу " + p.getValue()); dbObject = db.getObjectCopyByPK(p.getKey(), p.getValue()); response = new ServerExchangeUnit_2021(ServerCode.OK); response.object = dbObject; break; case GetObjectsCopiesByPK: Print("Получить список копий объектов по ключам"); p = (Pair) request.object; response = new ServerExchangeUnit_2021(ServerCode.OK); response.object = db.getObjectsCopies(p.getKey(), (Vector) p.getValue()); break; case PublishObject: PublishObject(); break; case PublishObjects: PublishObjects(); break; case DeleteObjectByPK: DeleteObjectByPK(); break; case DeleteObjectsByPK: DeleteObjectsByPK(); break; // case EXIT: Print("ЗАВЕРШИТЬ РАБОТУ СЕРВЕРА"); System.exit(0); break; case Ping: Print("Проверка активности сервера"); Ping(); break; default: Session(); break; } } catch (Exception ex) { response = new ServerExchangeUnit_2021(ServerCode.FAIL, "Исключение сервера", ex); } finally { Print("сервер: -> " + response.codeName); out.writeObject(response); Print("Ответ отправлен."); } } } //-> } catch (Exception ex) { Print("Соединение с клиентом завершено."); } finally { //-> try { if (clientSocket != null) clientSocket.close(); } catch (Exception ex) { ex.printStackTrace(); } // потоки тоже хорошо бы закрыть try { if (in != null) in.close(); } catch (Exception ex) { ex.printStackTrace(); } try { if (out != null) out.close(); } catch (Exception ex) { ex.printStackTrace(); } Print("Сервер ждет следующего клиента."); } } } //-- protected Database getDefaultDatabase() { return db; } //-- private void PublishObject() throws Exception { response = new ServerExchangeUnit_2021(ServerCode.OK); DBObject dbObject = (DBObject) request.object; beforePublishAction(dbObject); response.object = (Serializable) getDefaultDatabase().InsertS(dbObject).getPK(); afterPublishAction(dbObject); } private void PublishObjects() throws Exception { response = new ServerExchangeUnit_2021(ServerCode.OK); Vector objects = (Vector) request.object; Database database = getDefaultDatabase(); for (DBObject dbObject : objects) { beforePublishAction(dbObject); response.object = (Serializable) database.InsertS(dbObject).getPK(); afterPublishAction(dbObject); } } protected void beforePublishAction(DBObject object) throws Exception { } protected void afterPublishAction(DBObject object) throws Exception { } protected void afterEditAction(DBObject object) throws Exception { } //------------------------------ private void DeleteObjectByPK() throws Exception { Print("Удалить объект по ключу"); Pair to_delete = (Pair) request.object; afterDeleteAction(getDefaultDatabase().DeleteByPK(to_delete.getKey(), to_delete.getValue())); response = new ServerExchangeUnit_2021(ServerCode.OK); } private void DeleteObjectsByPK() throws Exception { Print("Удалить объекты по ключам"); Pair> to_delete = (Pair>) request.object; Database database = getDefaultDatabase(); for (Object object : to_delete.getValue()) { afterDeleteAction(database.DeleteByPK(to_delete.getKey(), object)); } response = new ServerExchangeUnit_2021(ServerCode.OK); } public void afterDeleteAction(DBObject object) throws Exception { } public void Ping() { response = new ServerExchangeUnit_2021(ServerCode.OK); } }