From 8a50747ffd868509a04f21a8b4dbafea48f73915 Mon Sep 17 00:00:00 2001 From: chandrasegar Date: Mon, 26 Feb 2024 09:36:20 +0530 Subject: [PATCH] custom exceptions added --- .../mailsender/Controller/MailController.java | 13 +- .../mailsender/DAO/Impl/MailDAOImpl.java | 181 +++++++++--------- .../java/entgra/mailsender/DAO/MailDAO.java | 3 +- .../Service/Impl/MailServiceImpl.java | 37 ++-- .../mailsender/Service/MailService.java | 3 +- .../exception/DatabaseAccessException.java | 11 ++ .../exception/FileConversionException.java | 11 ++ .../exception/MailProcessingException.java | 11 ++ .../mailsender/exception/QueueException.java | 11 ++ 9 files changed, 164 insertions(+), 117 deletions(-) create mode 100644 src/main/java/entgra/mailsender/exception/DatabaseAccessException.java create mode 100644 src/main/java/entgra/mailsender/exception/FileConversionException.java create mode 100644 src/main/java/entgra/mailsender/exception/MailProcessingException.java create mode 100644 src/main/java/entgra/mailsender/exception/QueueException.java diff --git a/src/main/java/entgra/mailsender/Controller/MailController.java b/src/main/java/entgra/mailsender/Controller/MailController.java index 65b3d49..b7d9169 100644 --- a/src/main/java/entgra/mailsender/Controller/MailController.java +++ b/src/main/java/entgra/mailsender/Controller/MailController.java @@ -4,6 +4,8 @@ package entgra.mailsender.Controller; import entgra.mailsender.DTO.MailModel; import entgra.mailsender.Service.MailService; import entgra.mailsender.exception.MailException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -14,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController; import javax.mail.MessagingException; import java.io.IOException; +import java.sql.SQLException; @RestController @RequestMapping("/api/message-distribution/email") @@ -21,6 +24,9 @@ public class MailController { @Autowired public MailService mailService; + private static final Logger logger = LoggerFactory.getLogger(MailController.class); + + @PostMapping public ResponseEntity sendEmail(@ModelAttribute MailModel emailModel) { String msg; @@ -30,11 +36,12 @@ public class MailController { return ResponseEntity.ok(msg); } catch (MailException e) { msg = "Invalid email address"; + logger.error(msg, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(msg); - } catch (MessagingException | IOException exception) { + } catch (MessagingException | SQLException | IOException exception) { msg = "Failed to send email"; + logger.error(msg, exception); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(msg + exception); } } - } - +} \ No newline at end of file diff --git a/src/main/java/entgra/mailsender/DAO/Impl/MailDAOImpl.java b/src/main/java/entgra/mailsender/DAO/Impl/MailDAOImpl.java index 10993e6..45c886a 100644 --- a/src/main/java/entgra/mailsender/DAO/Impl/MailDAOImpl.java +++ b/src/main/java/entgra/mailsender/DAO/Impl/MailDAOImpl.java @@ -4,12 +4,12 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import entgra.mailsender.DAO.MailDAO; import entgra.mailsender.DTO.MailModel; +import entgra.mailsender.exception.DatabaseAccessException; +import entgra.mailsender.exception.FileConversionException; +import entgra.mailsender.exception.MailProcessingException; import org.springframework.stereotype.Component; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -26,82 +26,83 @@ import java.util.logging.Logger; @Component public class MailDAOImpl implements MailDAO { -Logger logger = Logger.getLogger(String.valueOf(MailDAOImpl.class)); - -private Connection getConnection() throws SQLException { - return DriverManager.getConnection("jdbc:mysql://localhost:3306/email_sending", "root", "StrongPassword123!"); -} - -@Override -public int addMail(MailModel mailModel){ - PreparedStatement stmt; - int generatedId = -1; - - try { - Connection conn = this.getConnection(); - stmt = conn.prepareStatement("INSERT INTO email (EMAIL_ADDRESS, MSG_TEMPLATE, PRIORITY, ATTACHMENT, PARAMETERS, TIME, FILENAME, EXPIRY_AT) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", PreparedStatement.RETURN_GENERATED_KEYS); - Timestamp current_time = new Timestamp(System.currentTimeMillis()); - String parametersJson = new ObjectMapper().writeValueAsString(mailModel.getParameters()); - stmt.setString(1,mailModel.getEmailAddress()); - stmt.setString(2,mailModel.getMsgTemplate()); - stmt.setInt(3,mailModel.getPriority()); - stmt.setBytes(4,mailModel.getAttachment().getBytes()); + Logger logger = Logger.getLogger(String.valueOf(MailDAOImpl.class)); + + private Connection getConnection() throws SQLException { + return DriverManager.getConnection("jdbc:mysql://localhost:3306/email_sending", "root", "StrongPassword123!"); + } + + @Override + public int addMail(MailModel mailModel) throws SQLException { + try { + PreparedStatement stmt; + int generatedId; + Connection conn = this.getConnection(); + stmt = conn.prepareStatement("INSERT INTO email (EMAIL_ADDRESS, MSG_TEMPLATE, PRIORITY, ATTACHMENT, PARAMETERS, TIME, FILENAME, EXPIRY_AT) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", PreparedStatement.RETURN_GENERATED_KEYS); + Timestamp current_time = new Timestamp(System.currentTimeMillis()); + String parametersJson = new ObjectMapper().writeValueAsString(mailModel.getParameters()); + stmt.setString(1, mailModel.getEmailAddress()); + stmt.setString(2, mailModel.getMsgTemplate()); + stmt.setInt(3, mailModel.getPriority()); + stmt.setBytes(4, mailModel.getAttachment().getBytes()); stmt.setString(5, parametersJson); - stmt.setTimestamp(6,current_time); + stmt.setTimestamp(6, current_time); String filename = mailModel.getAttachment().getOriginalFilename(); - stmt.setString(7,filename); - stmt.setDate(8,mailModel.getExpiry_at()); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - if (rs.next()) { - generatedId = rs.getInt(1); + stmt.setString(7, filename); + stmt.setDate(8, mailModel.getExpiry_at()); + stmt.executeUpdate(); + ResultSet rs = stmt.getGeneratedKeys(); + if (rs.next()) { + generatedId = rs.getInt(1); + return generatedId; + } + } catch (SQLException e) { + logger.info(e.getMessage()); + throw new SQLException("error processing sql !!", e); + } catch (IOException e) { + logger.info(e.getMessage()); + throw new MailProcessingException("Error processing mailModel", e); } - logger.info("Stored successfully"); - } catch (SQLException e) { - logger.info(e.getMessage()); - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - return generatedId; -} + return 0; + } -@Override -public List getUnsentMessages(){ - String sql = "SELECT * FROM email WHERE email_id NOT IN (SELECT email_id FROM sentEmail)"; + @Override + public List getUnsentMessages() { + String sql = "SELECT * FROM email WHERE email_id NOT IN (SELECT email_id FROM sentEmail)"; - List unsentMails = new ArrayList<>(); + List unsentMails = new ArrayList<>(); - try(Connection connection = this.getConnection(); - PreparedStatement statement = connection.prepareStatement(sql); - ResultSet rs = statement.executeQuery()) { - while (rs.next()){ - MailModel mailModel = new MailModel(); - mailModel.setEmailId(rs.getInt("email_id")); - mailModel.setPriority(rs.getInt("priority")); - mailModel.setExpiry_at(rs.getDate("expiry_at")); - unsentMails.add(mailModel); + try (Connection connection = this.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql); + ResultSet rs = statement.executeQuery()) { + while (rs.next()) { + MailModel mailModel = new MailModel(); + mailModel.setEmailId(rs.getInt("email_id")); + mailModel.setPriority(rs.getInt("priority")); + mailModel.setExpiry_at(rs.getDate("expiry_at")); + unsentMails.add(mailModel); + } + } catch (SQLException e) { + logger.info(e.getMessage()); + throw new DatabaseAccessException("Error accessing database", e); } - } catch (SQLException e) { - throw new RuntimeException(e); - } - return unsentMails; + return unsentMails; -} + } -@Override -public MailModel getMailDetails(Integer mail_id){ + @Override + public MailModel getMailDetails(Integer mail_id) { String sql = "SELECT * FROM email WHERE email_id = ?"; MailModel mailModel = new MailModel(); try { Connection conn = this.getConnection(); - try(PreparedStatement stmt = conn.prepareStatement(sql)) { - stmt.setInt(1,mail_id); - try(ResultSet rs = stmt.executeQuery()) { - while (rs.next()){ + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setInt(1, mail_id); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { mailModel.setEmailId(rs.getInt("email_id")); mailModel.setEmailAddress(rs.getString("email_address")); mailModel.setMsgTemplate(rs.getString("msg_template")); @@ -111,38 +112,38 @@ public MailModel getMailDetails(Integer mail_id){ List parameters = parseJsonParameters(jsonData); mailModel.setParameters(parameters); - String filename = rs.getString("filename"); + String filename = rs.getString("filename"); mailModel.setFilename(filename); Blob blob = rs.getBlob("attachment"); - File file = convertBlobToFile(blob,filename); + File file = convertBlobToFile(blob, filename); mailModel.setFile(file); - - - } return mailModel; } catch (IOException e) { - throw new RuntimeException(e); + logger.info(e.getMessage()); + throw new MailProcessingException("Error processing mail", e); } } } catch (SQLException e) { - throw new RuntimeException(e); + logger.info(e.getMessage()); + throw new DatabaseAccessException("Error accessing database", e); } } -private List parseJsonParameters(String parametersJson) { + private List parseJsonParameters(String parametersJson) { try { ObjectMapper objectMapper = new ObjectMapper(); return objectMapper.readValue(parametersJson, new TypeReference<>() { }); } catch (IOException e) { + logger.info(e.getMessage()); throw new IllegalArgumentException("Error parsing parameters JSON", e); } } -public static File convertBlobToFile(Blob blob, String fileName) throws IOException, SQLException { + public static File convertBlobToFile(Blob blob, String fileName) throws IOException, SQLException { File file = new File(fileName); try (FileOutputStream outputStream = new FileOutputStream(file)) { InputStream inputStream = blob.getBinaryStream(); @@ -150,31 +151,25 @@ public static File convertBlobToFile(Blob blob, String fileName) throws IOExcept while (inputStream.read(buffer) > 0) { outputStream.write(buffer); } + } catch (IOException e) { + throw new FileConversionException("Error converting Blob to File", e); } return file; } -public void addToSentMail(Integer mail_id){ - PreparedStatement stmt; - - try { - Connection connection = this.getConnection(); - stmt = connection.prepareStatement("INSERT INTO sentEmail (email_id,sent_time) VALUE (?,?)"); - stmt.setInt(1,mail_id); + public void addToSentMail(Integer mail_id) { + try { + PreparedStatement stmt; + Connection connection = this.getConnection(); + stmt = connection.prepareStatement("INSERT INTO sentEmail (email_id,sent_time) VALUE (?,?)"); + stmt.setInt(1, mail_id); stmt.setDate(2, Date.valueOf(LocalDate.now())); - stmt.execute(); - logger.info("added to sent_email successfully"); - - } catch (SQLException e) { - throw new RuntimeException(e); + stmt.execute(); + } catch (SQLException e) { + logger.info(e.getMessage()); + throw new DatabaseAccessException("Error accessing database", e); + } } -} - - - -} - - - +} \ No newline at end of file diff --git a/src/main/java/entgra/mailsender/DAO/MailDAO.java b/src/main/java/entgra/mailsender/DAO/MailDAO.java index 7c5fea2..adb3fda 100644 --- a/src/main/java/entgra/mailsender/DAO/MailDAO.java +++ b/src/main/java/entgra/mailsender/DAO/MailDAO.java @@ -2,11 +2,12 @@ package entgra.mailsender.DAO; import entgra.mailsender.DTO.MailModel; +import java.sql.SQLException; import java.util.List; public interface MailDAO { - int addMail(MailModel mailModel); + int addMail(MailModel mailModel) throws SQLException; MailModel getMailDetails(Integer mail_id); diff --git a/src/main/java/entgra/mailsender/Service/Impl/MailServiceImpl.java b/src/main/java/entgra/mailsender/Service/Impl/MailServiceImpl.java index 5ffb9be..e7d34f5 100644 --- a/src/main/java/entgra/mailsender/Service/Impl/MailServiceImpl.java +++ b/src/main/java/entgra/mailsender/Service/Impl/MailServiceImpl.java @@ -6,6 +6,7 @@ import entgra.mailsender.Service.MailQueueService; import entgra.mailsender.Service.MailService; import entgra.mailsender.exception.BadRequestException; import entgra.mailsender.exception.MailException; +import entgra.mailsender.exception.QueueException; import entgra.mailsender.util.PriorityQueueHolder; import jakarta.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Autowired; @@ -13,6 +14,7 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; @@ -26,7 +28,6 @@ public class MailServiceImpl implements MailService { @Autowired private MailQueueService mailQueueService; - @PreDestroy public void shutdown() { shutdownRequested = true; @@ -39,16 +40,14 @@ public class MailServiceImpl implements MailService { @Autowired private MailDAO mailDAO; - - - public void sendEmail(MailModel emailModel) throws MailException { + public void sendEmail(MailModel emailModel) throws MailException, SQLException { if (shutdownRequested) { String msg = "Server is shutting down. SMS requests will not be accepted."; logger.warning(msg); throw new BadRequestException(msg); } - if (isValidEmailAddress(emailModel.getEmailAddress())){ + if (isValidEmailAddress(emailModel.getEmailAddress())) { String msg = "Invalid Email address"; logger.warning(msg); throw new BadRequestException(msg); @@ -64,13 +63,14 @@ public class MailServiceImpl implements MailService { try { mailQueueService.enqueMails(mailModels); - } catch (Exception e){ - throw new RuntimeException(e); + } catch (Exception e) { + logger.info(e.getMessage()); + throw new QueueException("Error processing Queue", e); } //send the high priority mail - while (PriorityQueueHolder.getInstance().getPriorityQueue().peek() != null){ - MailModel prioritizedMail =mailQueueService.getHighPriorityMail(); + while (PriorityQueueHolder.getInstance().getPriorityQueue().peek() != null) { + MailModel prioritizedMail = mailQueueService.getHighPriorityMail(); javaMailSender.send(mimeMessage -> { @@ -101,25 +101,25 @@ public class MailServiceImpl implements MailService { } - } - public boolean isValidEmailAddress(String email){ + public boolean isValidEmailAddress(String email) { String regex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"; return !email.matches(regex); } - public void syncMailWithDB(){ + public void syncMailWithDB() { try { List mailModels = mailDAO.getUnsentMessages(); - if (!mailModels.isEmpty()){ + if (!mailModels.isEmpty()) { mailQueueService.enqueMails(mailModels); } } catch (Exception e) { - throw new RuntimeException(e); + logger.info(e.getMessage()); + throw new QueueException("Error processing Queue", e); } - while(PriorityQueueHolder.getInstance().getPriorityQueue().peek() != null) { + while (PriorityQueueHolder.getInstance().getPriorityQueue().peek() != null) { MailModel prioritizedMail = mailDAO.getMailDetails(mailQueueService.getHighPriorityMail().getEmailId()); javaMailSender.send(mimeMessage -> { @@ -145,10 +145,10 @@ public class MailServiceImpl implements MailService { // Append text to email body mimeMessageHelper.setText(emailBody.toString(), false); - // Append attachments to email body + // Append attachments to email body mimeMessageHelper.addAttachment(prioritizedMail.getFilename(), prioritizedMail.getFile()); - //Store the sent mail to the table + //Store the sent mail to the table mailDAO.addToSentMail(prioritizedMail.getEmailId()); @@ -158,5 +158,4 @@ public class MailServiceImpl implements MailService { } - -} +} \ No newline at end of file diff --git a/src/main/java/entgra/mailsender/Service/MailService.java b/src/main/java/entgra/mailsender/Service/MailService.java index c945cbd..1fdf793 100644 --- a/src/main/java/entgra/mailsender/Service/MailService.java +++ b/src/main/java/entgra/mailsender/Service/MailService.java @@ -6,10 +6,11 @@ import entgra.mailsender.exception.MailException; import javax.mail.MessagingException; import java.io.IOException; +import java.sql.SQLException; public interface MailService { - void sendEmail(MailModel emailModel) throws MessagingException, IOException, BadRequestException, MailException; + void sendEmail(MailModel emailModel) throws MessagingException, IOException, BadRequestException, MailException, SQLException; boolean isValidEmailAddress(String email); diff --git a/src/main/java/entgra/mailsender/exception/DatabaseAccessException.java b/src/main/java/entgra/mailsender/exception/DatabaseAccessException.java new file mode 100644 index 0000000..a7cb4ba --- /dev/null +++ b/src/main/java/entgra/mailsender/exception/DatabaseAccessException.java @@ -0,0 +1,11 @@ +package entgra.mailsender.exception; + +public class DatabaseAccessException extends RuntimeException{ + public DatabaseAccessException(String message) { + super(message); + } + + public DatabaseAccessException(String message, Throwable cause) { + super(message, cause); + } +} \ No newline at end of file diff --git a/src/main/java/entgra/mailsender/exception/FileConversionException.java b/src/main/java/entgra/mailsender/exception/FileConversionException.java new file mode 100644 index 0000000..da5eb2d --- /dev/null +++ b/src/main/java/entgra/mailsender/exception/FileConversionException.java @@ -0,0 +1,11 @@ +package entgra.mailsender.exception; + +public class FileConversionException extends RuntimeException{ + public FileConversionException(String message) { + super(message); + } + + public FileConversionException(String message, Throwable cause) { + super(message, cause); + } +} \ No newline at end of file diff --git a/src/main/java/entgra/mailsender/exception/MailProcessingException.java b/src/main/java/entgra/mailsender/exception/MailProcessingException.java new file mode 100644 index 0000000..c06564d --- /dev/null +++ b/src/main/java/entgra/mailsender/exception/MailProcessingException.java @@ -0,0 +1,11 @@ +package entgra.mailsender.exception; + +public class MailProcessingException extends RuntimeException{ + public MailProcessingException(String msg){ + super(msg); + } + + public MailProcessingException(String msg, Throwable cause){ + super(msg,cause); + } +} \ No newline at end of file diff --git a/src/main/java/entgra/mailsender/exception/QueueException.java b/src/main/java/entgra/mailsender/exception/QueueException.java new file mode 100644 index 0000000..1ef819c --- /dev/null +++ b/src/main/java/entgra/mailsender/exception/QueueException.java @@ -0,0 +1,11 @@ +package entgra.mailsender.exception; + +public class QueueException extends RuntimeException{ + public QueueException(String message){ + super(message); + } + + public QueueException(String message, Throwable cause) { + super(message, cause); + } +} \ No newline at end of file