|
@@ -17,8 +17,7 @@ import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
|
|
|
|
import static cz.senslog.watchdog.config.MessageBrokerType.EMAIL;
|
|
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 cz.senslog.watchdog.domain.StatusReport.*;
|
|
|
import static java.time.format.DateTimeFormatter.ofPattern;
|
|
import static java.time.format.DateTimeFormatter.ofPattern;
|
|
|
|
|
|
|
|
public class EmailMessageBroker extends MultiMessageBroker {
|
|
public class EmailMessageBroker extends MultiMessageBroker {
|
|
@@ -38,6 +37,33 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
this.messageConfig = messageConfig;
|
|
this.messageConfig = messageConfig;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private static int[] createStatusProgressForUnit(int[] statuses) {
|
|
|
|
|
+ int[] statusToColor = new int[statuses.length];
|
|
|
|
|
+
|
|
|
|
|
+ int max = 0;
|
|
|
|
|
+ for (int status : statuses) {
|
|
|
|
|
+ max += status;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int maxPercent = 100;
|
|
|
|
|
+ for (int i = 0; i < statuses.length; i++) {
|
|
|
|
|
+ int percent = (int) ((double) statuses[i] / (double) max * 100.0);
|
|
|
|
|
+ statusToColor[i] = percent;
|
|
|
|
|
+ maxPercent -= percent;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (maxPercent != 0) {
|
|
|
|
|
+ for (int i = statusToColor.length - 1; i >= 0; i--) {
|
|
|
|
|
+ if (statusToColor[i] != 0) {
|
|
|
|
|
+ statusToColor[i] += maxPercent;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ return statusToColor;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private Tuple<String, Map<String, String>> createMessage(Report report) {
|
|
private Tuple<String, Map<String, String>> createMessage(Report report) {
|
|
|
StringBuilder content = new StringBuilder();
|
|
StringBuilder content = new StringBuilder();
|
|
|
final String rowStyle = "border: 1px solid #dddddd; text-align: left; padding: 8px;";
|
|
final String rowStyle = "border: 1px solid #dddddd; text-align: left; padding: 8px;";
|
|
@@ -89,7 +115,7 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
|
|
|
|
|
boolean renderReportTable = false;
|
|
boolean renderReportTable = false;
|
|
|
Map<Unit, List<ObservationInfo>> unitsToReport = new HashMap<>();
|
|
Map<Unit, List<ObservationInfo>> unitsToReport = new HashMap<>();
|
|
|
- Map<Unit, Tuple<Unit, StatusReport>> unitToStatus = new HashMap<>();
|
|
|
|
|
|
|
+ Map<Unit, Tuple<Unit, int[]>> unitToStatus = new HashMap<>();
|
|
|
for (SimpleReport simpleReport : report.getReports()) {
|
|
for (SimpleReport simpleReport : report.getReports()) {
|
|
|
StatusReport status = simpleReport.getStatus();
|
|
StatusReport status = simpleReport.getStatus();
|
|
|
boolean isOk = status.equals(OK);
|
|
boolean isOk = status.equals(OK);
|
|
@@ -97,34 +123,37 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
ObservationInfo observation = (ObservationInfo) simpleReport.getRecord();
|
|
ObservationInfo observation = (ObservationInfo) simpleReport.getRecord();
|
|
|
Unit unit = observation.getSource().getUnit();
|
|
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<>();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ int[] statusReportCounters = unitToStatus.computeIfAbsent(unit,
|
|
|
|
|
+ u -> Tuple.of(u, new int[StatusReport.values().length]))
|
|
|
|
|
+ .getItem2();
|
|
|
|
|
+
|
|
|
|
|
+ statusReportCounters[status.ordinal()] += 1;
|
|
|
|
|
+
|
|
|
|
|
+ List<ObservationInfo> observations = unitsToReport.computeIfAbsent(unit, u -> new ArrayList<>());
|
|
|
|
|
|
|
|
if (!isOk) {
|
|
if (!isOk) {
|
|
|
observations.add(observation);
|
|
observations.add(observation);
|
|
|
renderReportTable = true;
|
|
renderReportTable = true;
|
|
|
}
|
|
}
|
|
|
- unitToStatus.put(unit, Tuple.of(unit, updatedStatus));
|
|
|
|
|
- unitsToReport.put(unit, observations);
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
TableWriter tableUnitStatusWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
TableWriter tableUnitStatusWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
|
.cell("unitName").cell("unitId").end();
|
|
.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) {
|
|
|
|
|
|
|
+ List<Tuple<Unit, int[]>> statuses = new ArrayList<>(unitToStatus.values());
|
|
|
|
|
+ statuses.sort(Comparator.comparing(e -> e.getItem2()[OK.ordinal()] != 0));
|
|
|
|
|
+ for (Tuple<Unit, int[]> unitEntry : statuses) {
|
|
|
Unit unit = unitEntry.getItem1();
|
|
Unit unit = unitEntry.getItem1();
|
|
|
- boolean isOk = unitEntry.getItem2().equals(OK);
|
|
|
|
|
- tableUnitStatusWriter.row(rowStyle + "background-color: " + (isOk ? "#CCFFCC" : "#FFCCCC"))
|
|
|
|
|
|
|
+ // TODO change color according to the statu
|
|
|
|
|
+ int[] statusProgress = createStatusProgressForUnit(unitEntry.getItem2());
|
|
|
|
|
+ int percentOK = statusProgress[OK.ordinal()];
|
|
|
|
|
+ int percentFAIL = statusProgress[FAIL.ordinal()] + statusProgress[OK.ordinal()];
|
|
|
|
|
+ int percentNODATA = statusProgress[NO_DATA.ordinal()] + percentFAIL;
|
|
|
|
|
+ String color = String.format("linear-gradient(135deg, #CCFFCC %d%%, #FFCCCC 0 %d%%, white 0 %d%%)",
|
|
|
|
|
+ percentOK, percentFAIL, percentNODATA);
|
|
|
|
|
+
|
|
|
|
|
+ tableUnitStatusWriter.row(rowStyle + "background: " + color)
|
|
|
.cell(unit.getName(), rowStyle)
|
|
.cell(unit.getName(), rowStyle)
|
|
|
.cell(String.valueOf(unit.getId()), rowStyle)
|
|
.cell(String.valueOf(unit.getId()), rowStyle)
|
|
|
.end();
|
|
.end();
|
|
@@ -139,12 +168,15 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
TableWriter tableReportWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
TableWriter tableReportWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
|
|
|
.cell("unitName (unitId)").cell("sensorName (sensorId)").cell("timestamp").end();
|
|
.cell("unitName (unitId)").cell("sensorName (sensorId)").cell("timestamp").end();
|
|
|
|
|
|
|
|
|
|
+
|
|
|
for (Map.Entry<Unit, List<ObservationInfo>> unitEntry : unitsToReport.entrySet()) {
|
|
for (Map.Entry<Unit, List<ObservationInfo>> unitEntry : unitsToReport.entrySet()) {
|
|
|
for (ObservationInfo observation : unitEntry.getValue()) {
|
|
for (ObservationInfo observation : unitEntry.getValue()) {
|
|
|
Source source = observation.getSource();
|
|
Source source = observation.getSource();
|
|
|
|
|
+ Unit unit = source.getUnit();
|
|
|
|
|
+ Sensor sensor = source.getSensor();
|
|
|
|
|
|
|
|
- String unitCell = String.format("%s (%s)", source.getUnit().getName(), source.getUnit().getId());
|
|
|
|
|
- String sensorCell = String.format("%s (%s)", source.getSensor().getName(), source.getSensor().getId());
|
|
|
|
|
|
|
+ String unitCell = String.format("%s (%s)", unit.getName(), unit.getId());
|
|
|
|
|
+ String sensorCell = String.format("%s (%s)", sensor.getName(), sensor.getId());
|
|
|
|
|
|
|
|
tableReportWriter.row(rowStyle + "background-color: #FFCCCC")
|
|
tableReportWriter.row(rowStyle + "background-color: #FFCCCC")
|
|
|
.cell(unitCell, rowStyle)
|
|
.cell(unitCell, rowStyle)
|
|
@@ -152,6 +184,9 @@ public class EmailMessageBroker extends MultiMessageBroker {
|
|
|
.cell(observation.getTimestamp().toString(), rowStyle)
|
|
.cell(observation.getTimestamp().toString(), rowStyle)
|
|
|
.end();
|
|
.end();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ tableReportWriter.emptyRow().emptyRow().emptyRow();
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
/*
|