Merge pull request 'custom exceptions added' (#8) from exception into master

Reviewed-on: #8
pull/10/head
commit 23ff720b71

@ -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<String> 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);
}
}
}
}

@ -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));
Logger logger = Logger.getLogger(String.valueOf(MailDAOImpl.class));
private Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/email_sending", "root", "StrongPassword123!");
}
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());
@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<MailModel> getUnsentMessages(){
String sql = "SELECT * FROM email WHERE email_id NOT IN (SELECT email_id FROM sentEmail)";
@Override
public List<MailModel> getUnsentMessages() {
String sql = "SELECT * FROM email WHERE email_id NOT IN (SELECT email_id FROM sentEmail)";
List<MailModel> unsentMails = new ArrayList<>();
List<MailModel> 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<MailModel.Parameter> 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<MailModel.Parameter> parseJsonParameters(String parametersJson) {
private List<MailModel.Parameter> 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);
}
}
}
}

@ -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);

@ -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<MailModel> 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 {
}
}

@ -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);

@ -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);
}
}

@ -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);
}
}

@ -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);
}
}

@ -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);
}
}
Loading…
Cancel
Save