Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/main/java/backupmanager/BackupOperations.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
import backupmanager.Entities.ConfigurationBackup;
import backupmanager.Entities.TimeInterval;
import backupmanager.Entities.ZippingContext;
import backupmanager.Enums.BackupStatusEnum;
import backupmanager.Enums.BackupTriggeredEnum;
import backupmanager.Enums.ErrorTypes;
import backupmanager.Enums.BackupStatus;
import backupmanager.Enums.BackupTriggerType;
import backupmanager.Enums.ErrorType;
import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory;
import backupmanager.Enums.TranslationLoaderEnum.TranslationKey;
import backupmanager.GUI.BackupManagerGUI;
Expand All @@ -39,7 +39,7 @@

public class BackupOperations {
private static final Logger logger = LoggerFactory.getLogger(BackupOperations.class);
public static void singleBackup(ZippingContext context, BackupTriggeredEnum triggeredBy) {
public static void singleBackup(ZippingContext context, BackupTriggerType triggeredBy) {
if (context.backup() == null) throw new IllegalArgumentException("Backup cannot be null!");

logger.info("Event --> manual backup started");
Expand Down Expand Up @@ -70,7 +70,7 @@ public static void singleBackup(ZippingContext context, BackupTriggeredEnum trig
}
}

public static void executeBackup(ZippingContext context, BackupTriggeredEnum triggeredBy, String path1, String path2) {
public static void executeBackup(ZippingContext context, BackupTriggerType triggeredBy, String path1, String path2) {
File sourceFile = new File(path1.trim());
File outputFile = new File((path2+".zip").trim());

Expand All @@ -81,7 +81,7 @@ public static void executeBackup(ZippingContext context, BackupTriggeredEnum tri
ZippingThread.zipDirectory(sourceFile, outputFile, context, totalFilesCount);
}

private static void createBackupRequest(ZippingContext context, BackupTriggeredEnum triggeredBy, File sourceFile, File outputFile, int totalFilesCount) {
private static void createBackupRequest(ZippingContext context, BackupTriggerType triggeredBy, File sourceFile, File outputFile, int totalFilesCount) {
long targetSize = FolderUtils.calculateFileOrFolderSize(sourceFile.getAbsolutePath());
BackupRequestRepository.insertBackupRequest(BackupRequest.createNewBackupRequest(context.backup().getId(), triggeredBy, outputFile.getAbsolutePath(), targetSize, totalFilesCount));
}
Expand Down Expand Up @@ -162,17 +162,17 @@ else if (selectedFile.isFile())
public static boolean checkInputCorrect(String backupName, String path1, String path2, TrayIcon trayIcon) {
//check if inputs are null
if(path1.length() == 0 || path2.length() == 0) {
setError(ErrorTypes.InputMissing, trayIcon, backupName);
setError(ErrorType.InputMissing, trayIcon, backupName);
return false;
}

if (!Files.exists(Path.of(path1)) || !Files.exists(Path.of(path2))) {
setError(ErrorTypes.InputError, trayIcon, backupName);
setError(ErrorType.InputError, trayIcon, backupName);
return false;
}

if (path1.equals(path2)) {
setError(ErrorTypes.SamePaths, trayIcon, backupName);
setError(ErrorType.SamePaths, trayIcon, backupName);
return false;
}

Expand Down Expand Up @@ -283,7 +283,7 @@ public static void deletePotentiallyIncompletedBackupsFromLastExecution() {
for (BackupRequest request : requests) {
boolean deleted = deletePartialBackup(request.outputPath());
if (deleted) {
BackupRequestRepository.updateRequestStatusByRequestId(request.backupRequestId(), BackupStatusEnum.TERMINATED);
BackupRequestRepository.updateRequestStatusByRequestId(request.backupRequestId(), BackupStatus.TERMINATED);
}
}
}
Expand Down Expand Up @@ -326,7 +326,7 @@ private static boolean deletePartialBackup(String filePath) {
return false;
}

public static void setError(ErrorTypes error, TrayIcon trayIcon, String backupName) {
public static void setError(ErrorType error, TrayIcon trayIcon, String backupName) {
switch (error) {
case InputMissing -> {
logger.warn("Input Missing!");
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/backupmanager/Dialogs/BackupEntryDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import backupmanager.Entities.ConfigurationBackup;
import backupmanager.Entities.TimeInterval;
import backupmanager.Entities.ZippingContext;
import backupmanager.Enums.BackupTriggeredEnum;
import backupmanager.Enums.BackupTriggerType;
import backupmanager.Enums.ConfigKey;
import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory;
import backupmanager.Enums.TranslationLoaderEnum.TranslationKey;
Expand Down Expand Up @@ -199,7 +199,7 @@ public void singleBackup(String path1, String path2, BackupTable backupTable) {

ZippingContext context = ZippingContext.create(currentBackup, null, backupTable, BackupManagerGUI.progressBar, null, null);

BackupOperations.executeBackup(context, BackupTriggeredEnum.USER, path1, path2);
BackupOperations.executeBackup(context, BackupTriggerType.USER, path1, path2);

//if current_file_opened is null it means they are not in a backup but it is a backup with no associated json file
if (currentBackup.getName() != null && !currentBackup.getName().isEmpty()) {
Expand Down
72 changes: 61 additions & 11 deletions src/main/java/backupmanager/Email/EmailSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import backupmanager.Entities.Email;
import backupmanager.Entities.User;
import backupmanager.Enums.ConfigKey;
import backupmanager.Enums.EmailType;
import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory;
import backupmanager.Enums.TranslationLoaderEnum.TranslationKey;
import backupmanager.Json.JSONConfigReader;
import backupmanager.database.Repositories.EmailRepository;
import backupmanager.database.Repositories.UserRepository;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.net.SMTPAppender;
Expand All @@ -24,6 +29,8 @@
*/
public class EmailSender {

private static final JSONConfigReader configReader = new JSONConfigReader(ConfigKey.CONFIG_FILE_STRING.getValue(), ConfigKey.CONFIG_DIRECTORY_STRING.getValue());

private static final Logger logger = LoggerFactory.getLogger(EmailSender.class);

// Logger for sending critical error emails
Expand All @@ -40,12 +47,16 @@ public class EmailSender {
* @param subject The email subject.
* @param body The email body.
*/
public static void sendErrorEmail(String subject, String body) {
public static void sendErrorEmail(String subject, String body, String errorMessage) {
User user = getCurrentUser();

if (user == null) {
logger.warn("User is null, using a default user for the email");
user = User.getDefaultUser();
logger.warn("User is null. Cannot send critical error email");
return;
}

if (!canSend(errorMessage)) {
return;
}

int rows = 300;
Expand Down Expand Up @@ -76,6 +87,8 @@ public static void sendErrorEmail(String subject, String body) {
emailErrorLogger.error(emailMessage); // Log the message as ERROR, triggering the SMTPAppender

logger.info("Error email sent with subject: " + subject);

insertEmailInternally(EmailType.CRITICAL_ERROR, errorMessage);
}

/**
Expand All @@ -90,6 +103,8 @@ public static void sendUserCreationEmail(User user) {
emailInfoLogger.error(emailMessage); // Log the message as INFO, triggering the SMTPAppender

logger.info("User creation info email sent with user: " + user.toString());

insertEmailInternally(EmailType.WELCOME, null);
}

/**
Expand All @@ -101,7 +116,6 @@ public static void sendConfirmEmailToUser(User user) {
String subject = TranslationCategory.USER_DIALOG.getTranslation(TranslationKey.EMAIL_CONFIRMATION_SUBJECT);
String body = TranslationCategory.USER_DIALOG.getTranslation(TranslationKey.EMAIL_CONFIRMATION_BODY);

// Assicurati di assegnare il risultato della sostituzione
body = body.replace("[UserName]", user.getUserCompleteName());
body = body.replace("[SupportEmail]", ConfigKey.EMAIL.getValue());

Expand All @@ -115,17 +129,44 @@ public static void sendConfirmEmailToUser(User user) {
logger.info("Confirmation registration email sent to the user: " + user.toString());
}

private static User getCurrentUser() {
User user = UserRepository.getLastUser();
private static void insertEmailInternally(EmailType type, String payload) {
Email email = Email.createNewEmail(type, ConfigKey.VERSION.getValue(), payload);
EmailRepository.insertEmail(email);
}

if (user == null) {
logger.error("Unable to retrieve user details for the email because there is no user registered");
private static boolean canSend(String payload) {
int minWaitDays = configReader.getConfigValue("CriticalEmailMinWaitDays", 7);
LocalDateTime now = LocalDateTime.now();

if (isDuplicateError(payload)) {
logger.info("A critical error occurred, but the email was not sent because this error has already been reported for the current version.");
return false;
}

return user;
if (!hasWaitedSufficientTime(minWaitDays, now)) {
logger.info("A critical error occurred, but the email was not sent because the minimum wait time since the last critical error email has not elapsed.");
return false;
}

return true;
}

private static boolean isDuplicateError(String payload) {
if (payload == null) return false;

Email lastError = EmailRepository.getLastErrorEmailByPayloadAndVersion(payload, ConfigKey.VERSION.getValue());
return lastError != null;
}

private static boolean hasWaitedSufficientTime(int minWaitDays, LocalDateTime now) {
Email lastEmail = EmailRepository.getLastEmailByType(EmailType.CRITICAL_ERROR);
if (lastEmail == null) return true;

LocalDateTime lastSent = lastEmail.insertDate();
return lastSent.plusDays(minWaitDays).isBefore(now);
}

public static String getTextFromLogFile(int rows) {
private static String getTextFromLogFile(int rows) {
File file = new File(ConfigKey.LOG_DIRECTORY_STRING.getValue() + ConfigKey.LOG_FILE_STRING.getValue());

if (!file.exists() || !file.isFile() || file.length() == 0) {
Expand All @@ -151,10 +192,19 @@ public static String getTextFromLogFile(int rows) {
return String.join("\n", lastLines);
}

private static User getCurrentUser() {
User user = UserRepository.getLastUser();

if (user == null) {
logger.error("Unable to retrieve user details for the email because there is no user registered");
}

return user;
}

private static void updateEmailRecipient(String newRecipient) {
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();

//get the'appender SMTP
SMTPAppender smtpAppender = (SMTPAppender) context.getLogger("EMAIL_CONFIRMATION_LOGGER").getAppender("EMAIL_CONFIRMATION_LOGGER");

// if exists -> update
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/backupmanager/Entities/BackupRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import java.time.LocalDateTime;

import backupmanager.Enums.BackupStatusEnum;
import backupmanager.Enums.BackupTriggeredEnum;
import backupmanager.Enums.BackupStatus;
import backupmanager.Enums.BackupTriggerType;

public record BackupRequest (
int backupRequestId,
int backupConfigurationId,
LocalDateTime startedDate,
LocalDateTime completionDate,
BackupStatusEnum status,
BackupStatus status,
int progress,
BackupTriggeredEnum triggeredBy,
BackupTriggerType triggeredBy,
Long durationMs,
String outputPath,
long unzippedTargetSize,
Expand All @@ -21,7 +21,7 @@ public record BackupRequest (
String errorMessage
)
{
public static BackupRequest createNewBackupRequest(int backupConfigurationId, BackupTriggeredEnum type, String outputPath, long targetSize, int filesCount) {
return new BackupRequest(0, backupConfigurationId, LocalDateTime.now(), null, BackupStatusEnum.IN_PROGRESS, 0, type, null, outputPath, targetSize, null, filesCount, null);
public static BackupRequest createNewBackupRequest(int backupConfigurationId, BackupTriggerType type, String outputPath, long targetSize, int filesCount) {
return new BackupRequest(0, backupConfigurationId, LocalDateTime.now(), null, BackupStatus.IN_PROGRESS, 0, type, null, outputPath, targetSize, null, filesCount, null);
}
}
7 changes: 6 additions & 1 deletion src/main/java/backupmanager/Entities/Email.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ public record Email (
LocalDateTime insertDate,
String appVersion,
String payload
){ }
)
{
public static Email createNewEmail(EmailType type, String appVersion, String payload) {
return new Email(0, type, LocalDateTime.now(), appVersion, payload);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
import backupmanager.Enums.utils.CodeEnum;
import backupmanager.Enums.utils.EnumUtil;

public enum BackupStatusEnum implements CodeEnum {
public enum BackupStatus implements CodeEnum {
IN_PROGRESS(1),
QUEUE(2),
FINISHED(3),
TERMINATED(4);

private final int code;

BackupStatusEnum(int code) {
BackupStatus(int code) {
this.code = code;
}

Expand All @@ -20,7 +20,7 @@ public int getCode() {
return code;
}

public static BackupStatusEnum fromCode(int code) {
return EnumUtil.fromCode(BackupStatusEnum.class, code);
public static BackupStatus fromCode(int code) {
return EnumUtil.fromCode(BackupStatus.class, code);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import backupmanager.Enums.utils.CodeEnum;
import backupmanager.Enums.utils.EnumUtil;

public enum BackupTriggeredEnum implements CodeEnum {
public enum BackupTriggerType implements CodeEnum {
USER(1),
SCHEDULER(2);

private final int code;

BackupTriggeredEnum(int code) {
BackupTriggerType(int code) {
this.code = code;
}

Expand All @@ -18,7 +18,7 @@ public int getCode() {
return code;
}

public static BackupTriggeredEnum fromCode(int code) {
return EnumUtil.fromCode(BackupTriggeredEnum.class, code);
public static BackupTriggerType fromCode(int code) {
return EnumUtil.fromCode(BackupTriggerType.class, code);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package backupmanager.Enums;

public enum ErrorTypes {
public enum ErrorType {
InputMissing,
InputError,
SamePaths,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import backupmanager.BackupOperations;
import backupmanager.Entities.ConfigurationBackup;
import backupmanager.Entities.ZippingContext;
import backupmanager.Enums.BackupTriggeredEnum;
import backupmanager.Enums.BackupTriggerType;
import backupmanager.Enums.TranslationLoaderEnum.TranslationCategory;
import backupmanager.Enums.TranslationLoaderEnum.TranslationKey;
import backupmanager.GUI.BackupManagerGUI;
Expand Down Expand Up @@ -110,7 +110,7 @@ public static void popupItemRunBackup(int selectedRow, BackupTable backupTable,
BackupManagerGUI.progressBar = new BackupProgressGUI(backup.getTargetPath(), backup.getDestinationPath());

ZippingContext context = ZippingContext.create(backup, null, backupTable, BackupManagerGUI.progressBar, interruptBackupPopupItem, RunBackupPopupItem);
BackupOperations.singleBackup(context, BackupTriggeredEnum.USER);
BackupOperations.singleBackup(context, BackupTriggerType.USER);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/backupmanager/Managers/ExceptionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static void openExceptionMessage(String errorMessage, String stackTrace)

stackTrace = !errorMessage.isEmpty() ? errorMessage + "\n" + stackTrace : errorMessage + stackTrace;

EmailSender.sendErrorEmail("Critical Error Report", stackTrace);
EmailSender.sendErrorEmail("Critical Error Report", stackTrace, errorMessage);

String stackTraceMessage = TranslationCategory.DIALOGS.getTranslation(TranslationKey.EXCEPTION_MESSAGE_REPORT_MESSAGE) + "\n" + stackTrace;

Expand Down
Loading