Loading emailmicroservice/pom.xml +11 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,17 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <dependency> <groupId>cz.muni.fi.pa165</groupId> <artifactId>models</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> </dependencies> </project> No newline at end of file emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailController.java +2 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ public class EmailController { @Operation( summary = "Send email to given email address with given subject and body", description = "If email address is valid mail will be send to given address with given subject and body.") @PostMapping(value = "/sendemail", consumes = "application/json", produces = "application/json") @PostMapping(value = "/send", consumes = "application/json", produces = "application/json") @ResponseStatus(HttpStatus.OK) public EmailTemplate sendEmail(@RequestBody EmailTemplate emailTemplate) { Loading @@ -35,7 +35,7 @@ public class EmailController { HttpStatus.BAD_REQUEST, "Failed to send email. Error: " + emailAddress + " is not valid email address."); try { emailService.sendTextEmail(emailTemplate); emailService.send(emailTemplate); return emailTemplate; } catch (MailAuthenticationException e) { throw new ResponseStatusException( Loading emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailService.java +104 −3 Original line number Diff line number Diff line package cz.muni.fi.pa165.microservice3.email; import com.fasterxml.jackson.databind.ObjectMapper; import cz.muni.fi.pa165.model.dto.house.HouseDto; import cz.muni.fi.pa165.model.dto.user.UserDto; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Arrays; import java.util.List; @EnableScheduling @Service public class EmailService { Loading @@ -16,13 +38,92 @@ public class EmailService { } public void sendTextEmail(EmailTemplate emailTemplate) { public void send(EmailTemplate emailTemplate) { SimpleMailMessage msg = new SimpleMailMessage(); msg.setTo(emailTemplate.getSendTo()); msg.setSubject(emailTemplate.getSubject()); msg.setText(emailTemplate.getBody()); //TODO Setting username and password in application.yaml is needed //javaMailSender.send(msg); javaMailSender.send(msg); } @Scheduled(cron = "@Midnight") @ConditionalOnProperty(name = "emailScheduler.enabled", matchIfMissing = true) public void sendDailyStatisticToCustomers() { for (UserDto user : getAllCustomers()) { String email = user.getEmail(); StringBuilder houseStatistics = new StringBuilder(); for (HouseDto house : getAllHousesOfUser(user.getId())) { String address = house.getAddress() + " " + house.getCity() + " " + house.getZipcode() + " " + house.getState(); String statistics = getDailyHouseStatistics(user.getId(), house.getId()); houseStatistics.append(String.format(EmailUtils.HOUSE_STATISTICS_TEMPLATE, address, statistics)); } String body = String.format(EmailUtils.EMAIL_TEMPLATE, houseStatistics); String subject = "Daily statistics"; send(EmailTemplate.builder().sendTo(email).subject(subject).body(body).build()); } } private List<UserDto> getAllCustomers() { HttpClient httpClient = HttpClientBuilder.create().build(); HttpGet request = new HttpGet("http://localhost:8080/api/user/customers"); request.setHeader("Content-Type", "application/json"); try { HttpResponse response = httpClient.execute(request); String responseBody = EntityUtils.toString(response.getEntity()); ObjectMapper objectMapper = new ObjectMapper(); return Arrays.asList(objectMapper.readValue(responseBody, UserDto[].class)); } catch (IOException e) { throw new RuntimeException(e); } } private List<HouseDto> getAllHousesOfUser(String userId) { HttpClient httpClient = HttpClientBuilder.create().build(); HttpGet request = new HttpGet("http://localhost:8080/api/user/houses/" + userId); request.setHeader("Content-Type", "application/json"); try { HttpResponse response = httpClient.execute(request); String responseBody = EntityUtils.toString(response.getEntity()); ObjectMapper objectMapper = new ObjectMapper(); return Arrays.asList(objectMapper.readValue(responseBody, HouseDto[].class)); } catch (IOException e) { throw new RuntimeException(e); } } private String getDailyHouseStatistics(String userId, String houseId) { Instant startDateTime = LocalDateTime.now().minusDays(1).withHour(0).withMinute(0).withSecond(0).toInstant(ZoneOffset.UTC); Instant lastDateTime = LocalDateTime.now().minusDays(1).withHour(23).withMinute(59).withSecond(59).toInstant(ZoneOffset.UTC); String payload = String.format(""" { "userId": "%s", "houseId": "%s", "startTime": "%s", "endTime": "%s" } """, userId, houseId, startDateTime, lastDateTime); StringEntity entity = new StringEntity(payload, ContentType.APPLICATION_JSON); HttpClient httpClient = HttpClientBuilder.create().build(); HttpPost request = new HttpPost("http://localhost:8080/api/user/statistics"); request.setEntity(entity); request.setHeader("Content-Type", "application/json"); try { HttpResponse response = httpClient.execute(request); String statistics = EntityUtils.toString(response.getEntity()); return statistics.isEmpty() ? "0" : statistics; } catch (IOException e) { throw new RuntimeException(e); } } } emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailTemplate.java +3 −2 Original line number Diff line number Diff line package cz.muni.fi.pa165.microservice3.email; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Max; import lombok.Builder; import lombok.Getter; import lombok.Setter; @Getter @Setter @Builder public class EmailTemplate { @Email private String sendTo; @Max(value = 100) private String subject; private String body; } emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailUtils.java +16 −0 Original line number Diff line number Diff line Loading @@ -11,4 +11,20 @@ public class EmailUtils { public static boolean isValidEmail(String email) { return EMAIL_PATTERN.matcher(email).matches(); } public static final String EMAIL_TEMPLATE = """ Hello, We are sending you the daily energy consumption statistics for your house(s). {houseStatistics} Best regards, Your Smart Energy Management System"""; public static final String HOUSE_STATISTICS_TEMPLATE = """ The daily energy consumption statistics for house {houseAddress}: {statistics} kWh """; } Loading
emailmicroservice/pom.xml +11 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,17 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <dependency> <groupId>cz.muni.fi.pa165</groupId> <artifactId>models</artifactId> <version>0.0.1-SNAPSHOT</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> </dependencies> </project> No newline at end of file
emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailController.java +2 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ public class EmailController { @Operation( summary = "Send email to given email address with given subject and body", description = "If email address is valid mail will be send to given address with given subject and body.") @PostMapping(value = "/sendemail", consumes = "application/json", produces = "application/json") @PostMapping(value = "/send", consumes = "application/json", produces = "application/json") @ResponseStatus(HttpStatus.OK) public EmailTemplate sendEmail(@RequestBody EmailTemplate emailTemplate) { Loading @@ -35,7 +35,7 @@ public class EmailController { HttpStatus.BAD_REQUEST, "Failed to send email. Error: " + emailAddress + " is not valid email address."); try { emailService.sendTextEmail(emailTemplate); emailService.send(emailTemplate); return emailTemplate; } catch (MailAuthenticationException e) { throw new ResponseStatusException( Loading
emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailService.java +104 −3 Original line number Diff line number Diff line package cz.muni.fi.pa165.microservice3.email; import com.fasterxml.jackson.databind.ObjectMapper; import cz.muni.fi.pa165.model.dto.house.HouseDto; import cz.muni.fi.pa165.model.dto.user.UserDto; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Arrays; import java.util.List; @EnableScheduling @Service public class EmailService { Loading @@ -16,13 +38,92 @@ public class EmailService { } public void sendTextEmail(EmailTemplate emailTemplate) { public void send(EmailTemplate emailTemplate) { SimpleMailMessage msg = new SimpleMailMessage(); msg.setTo(emailTemplate.getSendTo()); msg.setSubject(emailTemplate.getSubject()); msg.setText(emailTemplate.getBody()); //TODO Setting username and password in application.yaml is needed //javaMailSender.send(msg); javaMailSender.send(msg); } @Scheduled(cron = "@Midnight") @ConditionalOnProperty(name = "emailScheduler.enabled", matchIfMissing = true) public void sendDailyStatisticToCustomers() { for (UserDto user : getAllCustomers()) { String email = user.getEmail(); StringBuilder houseStatistics = new StringBuilder(); for (HouseDto house : getAllHousesOfUser(user.getId())) { String address = house.getAddress() + " " + house.getCity() + " " + house.getZipcode() + " " + house.getState(); String statistics = getDailyHouseStatistics(user.getId(), house.getId()); houseStatistics.append(String.format(EmailUtils.HOUSE_STATISTICS_TEMPLATE, address, statistics)); } String body = String.format(EmailUtils.EMAIL_TEMPLATE, houseStatistics); String subject = "Daily statistics"; send(EmailTemplate.builder().sendTo(email).subject(subject).body(body).build()); } } private List<UserDto> getAllCustomers() { HttpClient httpClient = HttpClientBuilder.create().build(); HttpGet request = new HttpGet("http://localhost:8080/api/user/customers"); request.setHeader("Content-Type", "application/json"); try { HttpResponse response = httpClient.execute(request); String responseBody = EntityUtils.toString(response.getEntity()); ObjectMapper objectMapper = new ObjectMapper(); return Arrays.asList(objectMapper.readValue(responseBody, UserDto[].class)); } catch (IOException e) { throw new RuntimeException(e); } } private List<HouseDto> getAllHousesOfUser(String userId) { HttpClient httpClient = HttpClientBuilder.create().build(); HttpGet request = new HttpGet("http://localhost:8080/api/user/houses/" + userId); request.setHeader("Content-Type", "application/json"); try { HttpResponse response = httpClient.execute(request); String responseBody = EntityUtils.toString(response.getEntity()); ObjectMapper objectMapper = new ObjectMapper(); return Arrays.asList(objectMapper.readValue(responseBody, HouseDto[].class)); } catch (IOException e) { throw new RuntimeException(e); } } private String getDailyHouseStatistics(String userId, String houseId) { Instant startDateTime = LocalDateTime.now().minusDays(1).withHour(0).withMinute(0).withSecond(0).toInstant(ZoneOffset.UTC); Instant lastDateTime = LocalDateTime.now().minusDays(1).withHour(23).withMinute(59).withSecond(59).toInstant(ZoneOffset.UTC); String payload = String.format(""" { "userId": "%s", "houseId": "%s", "startTime": "%s", "endTime": "%s" } """, userId, houseId, startDateTime, lastDateTime); StringEntity entity = new StringEntity(payload, ContentType.APPLICATION_JSON); HttpClient httpClient = HttpClientBuilder.create().build(); HttpPost request = new HttpPost("http://localhost:8080/api/user/statistics"); request.setEntity(entity); request.setHeader("Content-Type", "application/json"); try { HttpResponse response = httpClient.execute(request); String statistics = EntityUtils.toString(response.getEntity()); return statistics.isEmpty() ? "0" : statistics; } catch (IOException e) { throw new RuntimeException(e); } } }
emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailTemplate.java +3 −2 Original line number Diff line number Diff line package cz.muni.fi.pa165.microservice3.email; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Max; import lombok.Builder; import lombok.Getter; import lombok.Setter; @Getter @Setter @Builder public class EmailTemplate { @Email private String sendTo; @Max(value = 100) private String subject; private String body; }
emailmicroservice/src/main/java/cz/muni/fi/pa165/microservice3/email/EmailUtils.java +16 −0 Original line number Diff line number Diff line Loading @@ -11,4 +11,20 @@ public class EmailUtils { public static boolean isValidEmail(String email) { return EMAIL_PATTERN.matcher(email).matches(); } public static final String EMAIL_TEMPLATE = """ Hello, We are sending you the daily energy consumption statistics for your house(s). {houseStatistics} Best regards, Your Smart Energy Management System"""; public static final String HOUSE_STATISTICS_TEMPLATE = """ The daily energy consumption statistics for house {houseAddress}: {statistics} kWh """; }