Commit a676fa9ca68f646a711dd44e3c27239039d38b49

Authored by VoBa
Committed by GitHub
2 parents 30d686f7 8d60c67f

Merge pull request #37 from BohdanSmetanyuk/feature/read_templates_from_files

load mail templates from files
@@ -18,7 +18,6 @@ package org.thingsboard.server.service.edge.rpc.constructor; @@ -18,7 +18,6 @@ package org.thingsboard.server.service.edge.rpc.constructor;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.springframework.stereotype.Component; 19 import org.springframework.stereotype.Component;
20 import org.thingsboard.server.common.data.AdminSettings; 20 import org.thingsboard.server.common.data.AdminSettings;
21 -import org.thingsboard.server.common.data.id.AdminSettingsId;  
22 import org.thingsboard.server.dao.util.mapping.JacksonUtil; 21 import org.thingsboard.server.dao.util.mapping.JacksonUtil;
23 import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg; 22 import org.thingsboard.server.gen.edge.AdminSettingsUpdateMsg;
24 23
@@ -30,10 +29,8 @@ public class AdminSettingsUpdateMsgConstructor { @@ -30,10 +29,8 @@ public class AdminSettingsUpdateMsgConstructor {
30 AdminSettingsUpdateMsg.Builder builder = AdminSettingsUpdateMsg.newBuilder() 29 AdminSettingsUpdateMsg.Builder builder = AdminSettingsUpdateMsg.newBuilder()
31 .setKey(adminSettings.getKey()) 30 .setKey(adminSettings.getKey())
32 .setJsonValue(JacksonUtil.toString(adminSettings.getJsonValue())); 31 .setJsonValue(JacksonUtil.toString(adminSettings.getJsonValue()));
33 - AdminSettingsId adminSettingsId = adminSettings.getId();  
34 - if (adminSettingsId != null) {  
35 - builder.setIdMSB(adminSettingsId.getId().getMostSignificantBits());  
36 - builder.setIdLSB(adminSettingsId.getId().getLeastSignificantBits()); 32 + if (adminSettings.getId() != null) {
  33 + builder.setIsSystem(true);
37 } 34 }
38 return builder.build(); 35 return builder.build();
39 } 36 }
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.service.edge.rpc.init; 16 package org.thingsboard.server.service.edge.rpc.init;
17 17
  18 +import com.datastax.driver.core.utils.UUIDs;
18 import com.fasterxml.jackson.databind.JsonNode; 19 import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.ObjectMapper; 20 import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 21 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -22,8 +23,12 @@ import com.google.common.util.concurrent.FutureCallback; @@ -22,8 +23,12 @@ import com.google.common.util.concurrent.FutureCallback;
22 import com.google.common.util.concurrent.Futures; 23 import com.google.common.util.concurrent.Futures;
23 import com.google.common.util.concurrent.ListenableFuture; 24 import com.google.common.util.concurrent.ListenableFuture;
24 import lombok.extern.slf4j.Slf4j; 25 import lombok.extern.slf4j.Slf4j;
  26 +import org.apache.commons.io.FileUtils;
  27 +import org.apache.commons.lang3.StringUtils;
  28 +import org.apache.commons.lang3.text.WordUtils;
25 import org.checkerframework.checker.nullness.qual.Nullable; 29 import org.checkerframework.checker.nullness.qual.Nullable;
26 import org.springframework.beans.factory.annotation.Autowired; 30 import org.springframework.beans.factory.annotation.Autowired;
  31 +import org.springframework.core.io.DefaultResourceLoader;
27 import org.springframework.stereotype.Service; 32 import org.springframework.stereotype.Service;
28 import org.thingsboard.server.common.data.AdminSettings; 33 import org.thingsboard.server.common.data.AdminSettings;
29 import org.thingsboard.server.common.data.DashboardInfo; 34 import org.thingsboard.server.common.data.DashboardInfo;
@@ -37,6 +42,7 @@ import org.thingsboard.server.common.data.audit.ActionType; @@ -37,6 +42,7 @@ import org.thingsboard.server.common.data.audit.ActionType;
37 import org.thingsboard.server.common.data.edge.Edge; 42 import org.thingsboard.server.common.data.edge.Edge;
38 import org.thingsboard.server.common.data.edge.EdgeEvent; 43 import org.thingsboard.server.common.data.edge.EdgeEvent;
39 import org.thingsboard.server.common.data.edge.EdgeEventType; 44 import org.thingsboard.server.common.data.edge.EdgeEventType;
  45 +import org.thingsboard.server.common.data.id.AdminSettingsId;
40 import org.thingsboard.server.common.data.id.DeviceId; 46 import org.thingsboard.server.common.data.id.DeviceId;
41 import org.thingsboard.server.common.data.id.EdgeId; 47 import org.thingsboard.server.common.data.id.EdgeId;
42 import org.thingsboard.server.common.data.id.EntityId; 48 import org.thingsboard.server.common.data.id.EntityId;
@@ -76,11 +82,15 @@ import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg; @@ -76,11 +82,15 @@ import org.thingsboard.server.gen.edge.RuleChainMetadataRequestMsg;
76 import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg; 82 import org.thingsboard.server.gen.edge.UserCredentialsRequestMsg;
77 import org.thingsboard.server.service.executors.DbCallbackExecutorService; 83 import org.thingsboard.server.service.executors.DbCallbackExecutorService;
78 84
  85 +import java.io.File;
  86 +import java.nio.charset.StandardCharsets;
79 import java.util.ArrayList; 87 import java.util.ArrayList;
80 import java.util.HashMap; 88 import java.util.HashMap;
81 import java.util.List; 89 import java.util.List;
82 import java.util.Map; 90 import java.util.Map;
83 import java.util.UUID; 91 import java.util.UUID;
  92 +import java.util.regex.Matcher;
  93 +import java.util.regex.Pattern;
84 94
85 @Service 95 @Service
86 @Slf4j 96 @Slf4j
@@ -299,13 +309,71 @@ public class DefaultSyncEdgeService implements SyncEdgeService { @@ -299,13 +309,71 @@ public class DefaultSyncEdgeService implements SyncEdgeService {
299 309
300 private void syncAdminSettings(Edge edge) { 310 private void syncAdminSettings(Edge edge) {
301 try { 311 try {
302 - AdminSettings mailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail");  
303 - saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(mailSettings)); 312 + AdminSettings systemMailSettings = adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, "mail");
  313 + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(systemMailSettings));
  314 + AdminSettings tenantMailSettings = convertToTenantAdminSettings(systemMailSettings.getKey(), (ObjectNode) systemMailSettings.getJsonValue());
  315 + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(tenantMailSettings));
  316 + AdminSettings systemMailTemplates = loadMailTemplates();
  317 + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(systemMailTemplates));
  318 + AdminSettings tenantMailTemplates = convertToTenantAdminSettings(systemMailTemplates.getKey(), (ObjectNode) systemMailTemplates.getJsonValue());
  319 + saveEdgeEvent(edge.getTenantId(), edge.getId(), EdgeEventType.ADMIN_SETTINGS, ActionType.UPDATED, null, mapper.valueToTree(tenantMailTemplates));
304 } catch (Exception e) { 320 } catch (Exception e) {
305 log.error("Can't load admin settings", e); 321 log.error("Can't load admin settings", e);
306 } 322 }
307 } 323 }
308 324
  325 + private AdminSettings loadMailTemplates() throws Exception {
  326 + Map<String, Object> mailTemplates = new HashMap<>();
  327 + Pattern startPattern = Pattern.compile("<div class=\"content\".*?>");
  328 + Pattern endPattern = Pattern.compile("<div class=\"footer\".*?>");
  329 + File[] files = new DefaultResourceLoader().getResource("classpath:/templates/").getFile().listFiles();
  330 + for (File file: files) {
  331 + Map<String, String> mailTemplate = new HashMap<>();
  332 + String name = validateName(file.getName());
  333 + String stringTemplate = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
  334 + Matcher start = startPattern.matcher(stringTemplate);
  335 + Matcher end = endPattern.matcher(stringTemplate);
  336 + if (start.find() && end.find()) {
  337 + String body = StringUtils.substringBetween(stringTemplate, start.group(), end.group()).replaceAll("\t", "");
  338 + String subject = StringUtils.substringBetween(body, "<h2>", "</h2>");
  339 + mailTemplate.put("subject", subject);
  340 + mailTemplate.put("body", body);
  341 + mailTemplates.put(name, mailTemplate);
  342 + } else {
  343 + log.error("Can't load mail template from file {}", file.getName());
  344 + }
  345 + }
  346 + AdminSettings adminSettings = new AdminSettings();
  347 + adminSettings.setId(new AdminSettingsId(UUIDs.timeBased()));
  348 + adminSettings.setKey("mailTemplates");
  349 + adminSettings.setJsonValue(mapper.convertValue(mailTemplates, JsonNode.class));
  350 + return adminSettings;
  351 + }
  352 +
  353 + private String validateName(String name) throws Exception {
  354 + StringBuilder nameBuilder = new StringBuilder();
  355 + name = name.replace(".vm", "");
  356 + String[] nameParts = name.split("\\.");
  357 + if (nameParts.length >= 1) {
  358 + nameBuilder.append(nameParts[0]);
  359 + for (int i = 1; i < nameParts.length; i++) {
  360 + String word = WordUtils.capitalize(nameParts[i]);
  361 + nameBuilder.append(word);
  362 + }
  363 + return nameBuilder.toString();
  364 + } else {
  365 + throw new Exception("Error during filename validation");
  366 + }
  367 + }
  368 +
  369 + private AdminSettings convertToTenantAdminSettings(String key, ObjectNode jsonValue) {
  370 + AdminSettings tenantMailSettings = new AdminSettings();
  371 + jsonValue.put("useSystemMailSettings", true);
  372 + tenantMailSettings.setJsonValue(jsonValue);
  373 + tenantMailSettings.setKey(key);
  374 + return tenantMailSettings;
  375 + }
  376 +
309 private void pushUsersToEdge(TextPageData<User> pageData, Edge edge) { 377 private void pushUsersToEdge(TextPageData<User> pageData, Edge edge) {
310 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) { 378 if (pageData != null && pageData.getData() != null && !pageData.getData().isEmpty()) {
311 log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); 379 log.trace("[{}] [{}] user(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
@@ -275,10 +275,9 @@ message WidgetTypeUpdateMsg { @@ -275,10 +275,9 @@ message WidgetTypeUpdateMsg {
275 } 275 }
276 276
277 message AdminSettingsUpdateMsg { 277 message AdminSettingsUpdateMsg {
278 - int64 idMSB = 1;  
279 - int64 idLSB = 2;  
280 - string key = 3;  
281 - string jsonValue = 4; 278 + bool isSystem = 1;
  279 + string key = 2;
  280 + string jsonValue = 3;
282 } 281 }
283 282
284 message UserCredentialsUpdateMsg { 283 message UserCredentialsUpdateMsg {