|
|
@@ -8,6 +8,7 @@ import cz.senslog.watchdog.messagebroker.MessageStatus;
|
|
|
import cz.senslog.watchdog.messagebroker.MultiMessageBroker;
|
|
|
import cz.senslog.watchdog.messagebroker.writer.HtmlTableWriter;
|
|
|
import cz.senslog.watchdog.messagebroker.writer.TableWriter;
|
|
|
+import cz.senslog.watchdog.util.Tuple;
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
|
|
@@ -16,6 +17,8 @@ import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
|
|
|
import static cz.senslog.watchdog.config.MessageBrokerType.EMAIL;
|
|
|
+import static cz.senslog.watchdog.domain.StatusReport.FAIL;
|
|
|
+import static cz.senslog.watchdog.domain.StatusReport.OK;
|
|
|
import static java.time.format.DateTimeFormatter.ofPattern;
|
|
|
|
|
|
public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
@@ -23,6 +26,8 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
private static final String BREAK_LINE = "<br />";
|
|
|
private static final String HORIZONTAL_SEPARATOR = "<hr>";
|
|
|
|
|
|
+ private static final String SUBSTITUTABLE_VARIABLE_PREFIX = "$";
|
|
|
+
|
|
|
private static final Logger logger = LogManager.getLogger(EmailMessageBroker.class);
|
|
|
|
|
|
private final EmailServerConnection serverConnection;
|
|
|
@@ -33,26 +38,36 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
this.messageConfig = messageConfig;
|
|
|
}
|
|
|
|
|
|
- private String createMessage(Report report) {
|
|
|
+ private Tuple<String, Map<String, String>> createMessage(Report report) {
|
|
|
StringBuilder content = new StringBuilder();
|
|
|
final String rowStyle = "border: 1px solid #dddddd; text-align: left; padding: 8px;";
|
|
|
|
|
|
boolean isMessages = !report.getMessages().isEmpty();
|
|
|
boolean isRecords = !report.getReports().isEmpty();
|
|
|
|
|
|
- if (!report.getOperationProperties().isEmpty()) {
|
|
|
+ Map<String, String> operationProperties = report.getOperationProperties();
|
|
|
+ Map<String, String> substitutableVariables = new HashMap<>(operationProperties.size());
|
|
|
+ if (!operationProperties.isEmpty()) {
|
|
|
+ for (Map.Entry<String, String> property : operationProperties.entrySet()) {
|
|
|
+ if (property.getKey().startsWith(SUBSTITUTABLE_VARIABLE_PREFIX)) {
|
|
|
+ substitutableVariables.put(property.getKey(), property.getValue());
|
|
|
+ operationProperties.remove(property.getKey());
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- TableWriter tableSourceWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
|
- .cell("Operation Type").cell("Operation Value").end();
|
|
|
+ if (!operationProperties.isEmpty()) {
|
|
|
+ TableWriter tableSourceWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
|
+ .cell("Operation Type").cell("Operation Value").end();
|
|
|
|
|
|
- for (Map.Entry<String, String> operationEntry : report.getOperationProperties().entrySet()) {
|
|
|
- tableSourceWriter.row(rowStyle)
|
|
|
+ for (Map.Entry<String, String> operationEntry : operationProperties.entrySet()) {
|
|
|
+ tableSourceWriter.row(rowStyle)
|
|
|
.cell(operationEntry.getKey(), rowStyle)
|
|
|
.cell(operationEntry.getValue(), rowStyle)
|
|
|
- .end();
|
|
|
- }
|
|
|
+ .end();
|
|
|
+ }
|
|
|
|
|
|
- content.append(tableSourceWriter.table()).append(BREAK_LINE);
|
|
|
+ content.append(tableSourceWriter.table()).append(BREAK_LINE);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (isMessages || !isRecords) {
|
|
|
@@ -71,16 +86,80 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
}
|
|
|
|
|
|
if (isRecords) {
|
|
|
- TableWriter tableReportWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
|
- .cell("unitName (unitId)").cell("sensorName (sensorId)")
|
|
|
- .cell("timestamp")/*.cell("reported")*/.cell("status").end();
|
|
|
|
|
|
- // String reportedTime = report.getCreated().format(ofPattern("yyyy-MM-dd HH:mm:ss"));
|
|
|
+ boolean renderReportTable = false;
|
|
|
+ Map<Unit, List<ObservationInfo>> unitsToReport = new HashMap<>();
|
|
|
+ Map<Unit, Tuple<Unit, StatusReport>> unitToStatus = new HashMap<>();
|
|
|
+ for (SimpleReport simpleReport : report.getReports()) {
|
|
|
+ StatusReport status = simpleReport.getStatus();
|
|
|
+ boolean isOk = status.equals(OK);
|
|
|
+ if (simpleReport.getRecord() instanceof ObservationInfo) {
|
|
|
+ ObservationInfo observation = (ObservationInfo) simpleReport.getRecord();
|
|
|
+ Unit unit = observation.getSource().getUnit();
|
|
|
+
|
|
|
+ StatusReport updatedStatus;
|
|
|
+ List<ObservationInfo> observations;
|
|
|
+ if (unitToStatus.containsKey(unit)) {
|
|
|
+ observations = unitsToReport.get(unit);
|
|
|
+ updatedStatus = isOk ? unitToStatus.get(unit).getItem2() : FAIL;
|
|
|
+ } else {
|
|
|
+ updatedStatus = status;
|
|
|
+ observations = new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!isOk) {
|
|
|
+ observations.add(observation);
|
|
|
+ renderReportTable = true;
|
|
|
+ }
|
|
|
+ unitToStatus.put(unit, Tuple.of(unit, updatedStatus));
|
|
|
+ unitsToReport.put(unit, observations);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ TableWriter tableUnitStatusWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
|
+ .cell("unitName").cell("unitId").end();
|
|
|
+
|
|
|
+ List<Tuple<Unit, StatusReport>> statuses = new ArrayList<>(unitToStatus.values());
|
|
|
+ statuses.sort(Comparator.comparing(Tuple::getItem2, Comparator.reverseOrder()));
|
|
|
+ for (Tuple<Unit, StatusReport> unitEntry : statuses) {
|
|
|
+ Unit unit = unitEntry.getItem1();
|
|
|
+ boolean isOk = unitEntry.getItem2().equals(OK);
|
|
|
+ tableUnitStatusWriter.row(rowStyle + "background-color: " + (isOk ? "#CCFFCC" : "#FFCCCC"))
|
|
|
+ .cell(unit.getName(), rowStyle)
|
|
|
+ .cell(String.valueOf(unit.getId()), rowStyle)
|
|
|
+ .end();
|
|
|
+ }
|
|
|
+
|
|
|
+ content.append(tableUnitStatusWriter.table());
|
|
|
+
|
|
|
+ if (renderReportTable) {
|
|
|
+
|
|
|
+ content.append(HORIZONTAL_SEPARATOR).append(HORIZONTAL_SEPARATOR).append(BREAK_LINE);
|
|
|
+
|
|
|
+ TableWriter tableReportWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
|
+ .cell("unitName (unitId)").cell("sensorName (sensorId)").cell("timestamp").end();
|
|
|
+
|
|
|
+ for (Map.Entry<Unit, List<ObservationInfo>> unitEntry : unitsToReport.entrySet()) {
|
|
|
+ for (ObservationInfo observation : unitEntry.getValue()) {
|
|
|
+ Source source = observation.getSource();
|
|
|
+
|
|
|
+ String unitCell = String.format("%s (%s)", source.getUnit().getName(), source.getUnit().getId());
|
|
|
+ String sensorCell = String.format("%s (%s)", source.getSensor().getName(), source.getSensor().getId());
|
|
|
+
|
|
|
+ tableReportWriter.row(rowStyle + "background-color: #FFCCCC")
|
|
|
+ .cell(unitCell, rowStyle)
|
|
|
+ .cell(sensorCell, rowStyle)
|
|
|
+ .cell(observation.getTimestamp().toString(), rowStyle)
|
|
|
+ .end();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
report.getReports().sort(Comparator.comparing(SimpleReport::getStatus).reversed());
|
|
|
for (SimpleReport simpleReport : report.getReports()) {
|
|
|
- boolean isOk = simpleReport.getStatus().equals(StatusReport.OK);
|
|
|
- if (simpleReport.getRecord() instanceof ObservationInfo) {
|
|
|
+ boolean isOk = simpleReport.getStatus().equals(OK);
|
|
|
+ // ALLOW ONLY NOT OK REPORTS -> // TODO create a template system
|
|
|
+ if (!isOk && simpleReport.getRecord() instanceof ObservationInfo) {
|
|
|
ObservationInfo observation = (ObservationInfo) simpleReport.getRecord();
|
|
|
Source source = observation.getSource();
|
|
|
|
|
|
@@ -92,14 +171,17 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
.cell(sensorCell, rowStyle)
|
|
|
.cell(observation.getTimestamp().toString(), rowStyle)
|
|
|
// .cell(reportedTime, rowStyle)
|
|
|
- .cell(simpleReport.getStatus().name(), rowStyle)
|
|
|
+ // .cell(simpleReport.getStatus().name(), rowStyle)
|
|
|
.end();
|
|
|
}
|
|
|
}
|
|
|
- content.append(tableReportWriter.table()).append(BREAK_LINE);
|
|
|
+ */
|
|
|
+
|
|
|
+ content.append(tableReportWriter.table()).append(BREAK_LINE);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return content.toString();
|
|
|
+ return Tuple.of(content.toString(), substitutableVariables);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -112,13 +194,24 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
|
|
|
try {
|
|
|
StringBuilder reportMessage = new StringBuilder();
|
|
|
+ Map<String, String> substitutableVariables = new HashMap<>();
|
|
|
for (Report report : reports) {
|
|
|
- reportMessage.append(createMessage(report))
|
|
|
+ Tuple<String, Map<String, String>> message = createMessage(report);
|
|
|
+ for (Map.Entry<String, String> varEntry : message.getItem2().entrySet()) {
|
|
|
+ if (substitutableVariables.containsKey(varEntry.getKey())) {
|
|
|
+ String oldValue = substitutableVariables.get(varEntry.getKey());
|
|
|
+ substitutableVariables.put(varEntry.getKey(), oldValue + " & " + varEntry.getValue());
|
|
|
+ } else {
|
|
|
+ substitutableVariables.put(varEntry.getKey(), varEntry.getValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ reportMessage.append(message.getItem1())
|
|
|
.append(HORIZONTAL_SEPARATOR).append(HORIZONTAL_SEPARATOR)
|
|
|
.append(BREAK_LINE);
|
|
|
}
|
|
|
logger.info("Sending a message via email.");
|
|
|
- serverConnection.send(reportMessage.toString(), messageConfig);
|
|
|
+ serverConnection.send(reportMessage.toString(), substitutableVariables, messageConfig);
|
|
|
logger.info("The message was send successfully.");
|
|
|
status.handle(MessageStatus.success(LocalDateTime.now(), EMAIL.name()));
|
|
|
} catch (MessagingException e) {
|