Commit a676fa9ca68f646a711dd44e3c27239039d38b49
Committed by
GitHub
Merge pull request #37 from BohdanSmetanyuk/feature/read_templates_from_files
load mail templates from files
Showing
3 changed files
with
75 additions
and
11 deletions
@@ -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 { |