Skip to content

Commit

Permalink
alerter HTML email (template) (#126)
Browse files Browse the repository at this point in the history
* added test code to debug sendmail

* alerter html email and template

* alerter html email and template
  • Loading branch information
ndc-dxc authored Jul 11, 2024
1 parent e15520a commit 6d5535b
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/api-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: curl https://italia.github.io/api-oas-checker/spectral-full.yml > .spectral.yml
- run: curl https://raw.githubusercontent.com/italia/api-oas-checker/ff44a035af8f9ebcdd605f3edb93c7b054c17a22/rulesets/spectral-full.yml > .spectral.yml

# Get additional module required by spectral-full
- run: mkdir functions
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ dependencies {
implementation 'org.springframework.data:spring-data-elasticsearch'
implementation 'org.apache.jena:apache-jena-libs:4.9.0'
implementation 'org.apache.jena:jena-querybuilder:4.9.0'
implementation 'org.apache.commons:commons-text:1.12.0'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.eclipse.jgit:org.eclipse.jgit:6.8.0.202311291450-r'
implementation 'org.kohsuke:github-api:1.321'
Expand Down Expand Up @@ -210,6 +211,7 @@ jacocoTestCoverageVerification {
'it.gov.innovazione.ndc.harvester.service.OnceLogger',
'it.gov.innovazione.ndc.harvester.service.ConfigReaderService',
'it.gov.innovazione.ndc.service.EventCleaner',
'it.gov.innovazione.ndc.service.TemplateService',
'it.gov.innovazione.ndc.alerter.*'
]
}
Expand Down
64 changes: 43 additions & 21 deletions src/main/java/it/gov/innovazione/ndc/service/AlerterMailSender.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static it.gov.innovazione.ndc.harvester.service.ActualConfigService.ConfigKey.ALERTER_ENABLED;
import static org.apache.commons.collections4.ListUtils.emptyIfNull;
import static org.apache.commons.text.StringSubstitutor.replace;

@Component
@RequiredArgsConstructor
Expand All @@ -32,6 +36,7 @@ public class AlerterMailSender {
private final EventService eventService;
private final UserService userService;
private final ConfigService configService;
private final TemplateService templateService;

private static boolean isAlertable(Instant lastAlertedAt, Integer aggregationTime, Instant now) {
return lastAlertedAt.plusSeconds(aggregationTime).isBefore(now);
Expand Down Expand Up @@ -114,9 +119,9 @@ private void sendMessages(EventCategory category, List<EventDto> eventDtos, Prof
recipient.getEmail(),
eventDtos.size(),
category);
emailService.sendEmail(recipient.getEmail(),
emailService.sendHtmlEmail(recipient.getEmail(),
"[SCHEMAGOV] [" + category + "] Alerter: Report degli eventi",
getMessageBody(eventDtos, recipient));
getHtmlMessageBodyFromTemplates(eventDtos, recipient));
}
return;
}
Expand All @@ -131,30 +136,47 @@ private void sendMessages(EventCategory category, List<EventDto> eventDtos, Prof
.collect(Collectors.joining(", ")));
}

private String getMessageBody(List<EventDto> eventDtos, UserDto recipient) {
StringBuilder message = new StringBuilder("Ciao " + recipient.getName() + " " + recipient.getSurname() + ",\n\n"
+ "Di seguito i dettagli degli eventi riscontrati:\n");
int i = 1;
for (EventDto eventDto : eventDtos) {
message.append(getDetailsForEvent(i, eventDto));
i++;
}
message.append("Origine: Generata automaticamente dall'harvester.\n\n");
message.append("Cordiali saluti,\n\nIl team di supporto di Schemagov");
return message.toString();
private String getHtmlMessageBodyFromTemplates(List<EventDto> eventDtos, UserDto recipient) {
return replace(
templateService.getAlerterMailTemplate(),
Map.of(
"recipient.name", recipient.getName(),
"recipient.surname", recipient.getSurname(),
"eventList", replace(
templateService.getEventListTemplate(),
Map.of(
"events", getEvents(eventDtos)))));
}

private String getEvents(List<EventDto> eventDtos) {
return eventDtos.stream()
.map(eventDto -> replace(
templateService.getEventTemplate(),
Map.of(
"event.name", eventDto.getName(),
"event.description", eventDto.getDescription(),
"event.severity", eventDto.getSeverity(),
"event.context", toSubList(eventDto.getContext()),
"event.createdBy", eventDto.getCreatedBy(),
"event.createdAt", toLocalDate(eventDto.getCreatedAt()))))
.collect(Collectors.joining());
}

private String getDetailsForEvent(int i, EventDto eventDto) {
return i + ". Titolo: " + eventDto.getName() + "\n"
+ "Descrizione: " + eventDto.getDescription() + "\n"
+ "Severity: " + eventDto.getSeverity() + "\n"
+ "Contesto: " + eventDto.getContext() + "\n"
+ "Creato da: " + eventDto.getCreatedBy() + "\n"
+ "Creato il: " + eventDto.getCreatedAt() + "\n\n";
private String toLocalDate(Instant createdAt) {
return DateTimeFormatter.ofPattern("dd MMMM yyyy HH:mm:ss")
.withZone(ZoneId.systemDefault())
.format(createdAt);
}

private String toSubList(Map<String, Object> context) {
return "<ul>"
+ context.entrySet().stream()
.map(entry -> "<li><b>" + entry.getKey() + ":</b>" + entry.getValue() + "</li>")
.collect(Collectors.joining())
+ "</ul>";
}

private boolean isSeverityGteThanMin(EventDto eventDto, ProfileDto profileDto) {
return eventDto.getSeverity().ordinal() >= profileDto.getMinSeverity().ordinal();
}

}
25 changes: 13 additions & 12 deletions src/main/java/it/gov/innovazione/ndc/service/EmailService.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package it.gov.innovazione.ndc.service;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.internet.MimeMessage;

@Component
@RequiredArgsConstructor
@Slf4j
Expand All @@ -17,8 +19,6 @@ class EmailService {
private final JavaMailSender javaMailSender;
@Value("${alerter.mail.sender}")
private final String from;
@Value("${spring.mail.properties.mail.debug:false}")
private boolean mailDebug;

void sendEmail(String to, String subject, String text) {
SimpleMailMessage message = new SimpleMailMessage();
Expand All @@ -29,13 +29,14 @@ void sendEmail(String to, String subject, String text) {
javaMailSender.send(message);
}

@EventListener(ApplicationStartedEvent.class)
void debugSendMail() {
if (mailDebug) {
log.info("Sending test email");
sendEmail("[email protected]", "Test", "Test");
log.info("Test email sent");
}
@SneakyThrows
void sendHtmlEmail(String to, String subject, String htmlMessage) {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, "utf-8");
helper.setText(htmlMessage, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setFrom(from);
javaMailSender.send(mimeMessage);
}

}
42 changes: 42 additions & 0 deletions src/main/java/it/gov/innovazione/ndc/service/TemplateService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package it.gov.innovazione.ndc.service;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.nio.charset.StandardCharsets;

@RequiredArgsConstructor
@Component
@Getter
public class TemplateService {

@Value("classpath:templates/alerter_mail_template.html")
private final Resource alerterMailTemplateResource;
@Value("classpath:templates/event_list_template.html")
private final Resource eventListTemplateResource;
@Value("classpath:templates/event_template.html")
private final Resource eventTemplateResource;

private String alerterMailTemplate;
private String eventListTemplate;
private String eventTemplate;

@PostConstruct
public void init() {
alerterMailTemplate = readTemplate(alerterMailTemplateResource);
eventListTemplate = readTemplate(eventListTemplateResource);
eventTemplate = readTemplate(eventTemplateResource);
}

@SneakyThrows
private String readTemplate(Resource eventTemplateResource) {
return IOUtils.toString(eventTemplateResource.getInputStream(), StandardCharsets.UTF_8);
}

}
5 changes: 5 additions & 0 deletions src/main/resources/templates/alerter_mail_template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<p>Ciao <b>${recipient.name} ${recipient.surname}</b></p>
<p>Di seguito i dettagli degli eventi riscontrati:</p>
${eventList}
<p>Origine: Generata automaticamente dall'harvester.</p>
<p>Cordiali saluti,<br/>Il team di supporto di Schemagov</p>
3 changes: 3 additions & 0 deletions src/main/resources/templates/event_list_template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<ol>
${events}
</ol>
9 changes: 9 additions & 0 deletions src/main/resources/templates/event_template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<li style='margin-bottom:2em'><b>${event.name}</b>
<ul>
<li><b>Descrizione:</b> ${event.description}</li>
<li><b>Severity:</b> ${event.severity}</li>
<li><b>Contesto:</b><br/> ${event.context}</li>
<li><b>Creato da:</b> ${event.createdBy}</b></li>
<li><b>Creato il:</b> ${event.createdAt}</b></li>
</ul>
</li>

0 comments on commit 6d5535b

Please sign in to comment.