Commit 3feb32c0f6fae02c3a51ba99457a7da1fb8e2fb0
Committed by
Andrew Shvayka
1 parent
ee3abe59
Improvements to the templates
Showing
5 changed files
with
182 additions
and
114 deletions
application/src/main/java/org/thingsboard/server/service/apiusage/DefaultTbApiUsageStateService.java
... | ... | @@ -305,7 +305,7 @@ public class DefaultTbApiUsageStateService implements TbApiUsageStateService { |
305 | 305 | } |
306 | 306 | mailExecutor.submit(() -> { |
307 | 307 | try { |
308 | - mailService.sendApiFeatureStateEmail(apiFeature, stateValue, email, msgs); | |
308 | + mailService.sendApiFeatureStateEmail(apiFeature, stateValue, email, msgs[0]); | |
309 | 309 | } catch (ThingsboardException e) { |
310 | 310 | log.warn("[{}] Can't send update of the API state to tenant with provided email [{}]", state.getTenantId(), email, e); |
311 | 311 | } | ... | ... |
... | ... | @@ -250,13 +250,11 @@ public class DefaultMailService implements MailService { |
250 | 250 | } |
251 | 251 | |
252 | 252 | @Override |
253 | - public void sendApiFeatureStateEmail(ApiFeature apiFeature, ApiUsageStateValue stateValue, String email, ApiUsageStateMailMessage[] stateMailMessages) throws ThingsboardException { | |
253 | + public void sendApiFeatureStateEmail(ApiFeature apiFeature, ApiUsageStateValue stateValue, String email, ApiUsageStateMailMessage msg) throws ThingsboardException { | |
254 | 254 | String subject = messages.getMessage("api.usage.state", null, Locale.US); |
255 | 255 | |
256 | 256 | Map<String, Object> model = new HashMap<>(); |
257 | - model.put("apiFeature", apiFeature.getApiStateKey()); | |
258 | - model.put("apiUsageStateMailMessages", stateMailMessages); | |
259 | - | |
257 | + model.put("apiFeature", apiFeature.getLabel()); | |
260 | 258 | model.put(TARGET_EMAIL, email); |
261 | 259 | |
262 | 260 | String message = null; |
... | ... | @@ -269,12 +267,43 @@ public class DefaultMailService implements MailService { |
269 | 267 | message = mergeTemplateIntoString("state.warning.ftl", model); |
270 | 268 | break; |
271 | 269 | case DISABLED: |
270 | + model.put("apiLimitValueLabel", toDisabledValueLabel(apiFeature) + " " + toDisabledValueLabel(msg)); | |
272 | 271 | message = mergeTemplateIntoString("state.disabled.ftl", model); |
273 | 272 | break; |
274 | 273 | } |
275 | 274 | sendMail(mailSender, mailFrom, email, subject, message); |
276 | 275 | } |
277 | 276 | |
277 | + private String toDisabledValueLabel(ApiFeature apiFeature) { | |
278 | + switch (apiFeature) { | |
279 | + case DB: | |
280 | + return "saved"; | |
281 | + case TRANSPORT: | |
282 | + return "received"; | |
283 | + case JS: | |
284 | + case RE: | |
285 | + return "invoked"; | |
286 | + default: | |
287 | + throw new RuntimeException("Not implemented!"); | |
288 | + } | |
289 | + } | |
290 | + | |
291 | + private String toDisabledValueLabel(ApiUsageStateMailMessage msg) { | |
292 | + switch (msg.getKey()) { | |
293 | + case STORAGE_DP_COUNT: | |
294 | + case TRANSPORT_DP_COUNT: | |
295 | + return (msg.getThreshold() / 1000000) + "M data points"; | |
296 | + case TRANSPORT_MSG_COUNT: | |
297 | + return (msg.getThreshold() / 1000000) + "M messages"; | |
298 | + case JS_EXEC_COUNT: | |
299 | + return (msg.getThreshold() / 1000000) + "M JavaScript functions"; | |
300 | + case RE_EXEC_COUNT: | |
301 | + return (msg.getThreshold() / 1000000) + "M Rule Engine nodes"; | |
302 | + default: | |
303 | + throw new RuntimeException("Not implemented!"); | |
304 | + } | |
305 | + } | |
306 | + | |
278 | 307 | private void sendMail(JavaMailSenderImpl mailSender, |
279 | 308 | String mailFrom, String email, |
280 | 309 | String subject, String message) throws ThingsboardException { | ... | ... |
... | ... | @@ -15,112 +15,148 @@ |
15 | 15 | limitations under the License. |
16 | 16 | |
17 | 17 | --> |
18 | -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
19 | -<html xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
18 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |
19 | + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
20 | +<html xmlns="http://www.w3.org/1999/xhtml" | |
21 | + style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
20 | 22 | <head> |
21 | -<meta name="viewport" content="width=device-width" /> | |
22 | -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | |
23 | -<title>Thingsboard - Api Usage State</title> | |
24 | - | |
25 | - | |
26 | -<style type="text/css"> | |
27 | -img { | |
28 | -max-width: 100%; | |
29 | -} | |
30 | -body { | |
31 | --webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; | |
32 | -} | |
33 | -body { | |
34 | -background-color: #f6f6f6; | |
35 | -} | |
36 | -@media only screen and (max-width: 640px) { | |
37 | - body { | |
38 | - padding: 0 !important; | |
39 | - } | |
40 | - h1 { | |
41 | - font-weight: 800 !important; margin: 20px 0 5px !important; | |
42 | - } | |
43 | - h2 { | |
44 | - font-weight: 800 !important; margin: 20px 0 5px !important; | |
45 | - } | |
46 | - h3 { | |
47 | - font-weight: 800 !important; margin: 20px 0 5px !important; | |
48 | - } | |
49 | - h4 { | |
50 | - font-weight: 800 !important; margin: 20px 0 5px !important; | |
51 | - } | |
52 | - h1 { | |
53 | - font-size: 22px !important; | |
54 | - } | |
55 | - h2 { | |
56 | - font-size: 18px !important; | |
57 | - } | |
58 | - h3 { | |
59 | - font-size: 16px !important; | |
60 | - } | |
61 | - .container { | |
62 | - padding: 0 !important; width: 100% !important; | |
63 | - } | |
64 | - .content { | |
65 | - padding: 0 !important; | |
66 | - } | |
67 | - .content-wrap { | |
68 | - padding: 10px !important; | |
69 | - } | |
70 | - .invoice { | |
71 | - width: 100% !important; | |
72 | - } | |
73 | -} | |
74 | -</style> | |
23 | + <meta name="viewport" content="width=device-width"/> | |
24 | + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |
25 | + <title>Thingsboard - Api Usage State</title> | |
26 | + | |
27 | + | |
28 | + <style type="text/css"> | |
29 | + img { | |
30 | + max-width: 100%; | |
31 | + } | |
32 | + | |
33 | + body { | |
34 | + -webkit-font-smoothing: antialiased; | |
35 | + -webkit-text-size-adjust: none; | |
36 | + width: 100% !important; | |
37 | + height: 100%; | |
38 | + line-height: 1.6em; | |
39 | + } | |
40 | + | |
41 | + body { | |
42 | + background-color: #f6f6f6; | |
43 | + } | |
44 | + | |
45 | + @media only screen and (max-width: 640px) { | |
46 | + body { | |
47 | + padding: 0 !important; | |
48 | + } | |
49 | + | |
50 | + h1 { | |
51 | + font-weight: 800 !important; | |
52 | + margin: 20px 0 5px !important; | |
53 | + } | |
54 | + | |
55 | + h2 { | |
56 | + font-weight: 800 !important; | |
57 | + margin: 20px 0 5px !important; | |
58 | + } | |
59 | + | |
60 | + h3 { | |
61 | + font-weight: 800 !important; | |
62 | + margin: 20px 0 5px !important; | |
63 | + } | |
64 | + | |
65 | + h4 { | |
66 | + font-weight: 800 !important; | |
67 | + margin: 20px 0 5px !important; | |
68 | + } | |
69 | + | |
70 | + h1 { | |
71 | + font-size: 22px !important; | |
72 | + } | |
73 | + | |
74 | + h2 { | |
75 | + font-size: 18px !important; | |
76 | + } | |
77 | + | |
78 | + h3 { | |
79 | + font-size: 16px !important; | |
80 | + } | |
81 | + | |
82 | + .container { | |
83 | + padding: 0 !important; | |
84 | + width: 100% !important; | |
85 | + } | |
86 | + | |
87 | + .content { | |
88 | + padding: 0 !important; | |
89 | + } | |
90 | + | |
91 | + .content-wrap { | |
92 | + padding: 10px !important; | |
93 | + } | |
94 | + | |
95 | + .invoice { | |
96 | + width: 100% !important; | |
97 | + } | |
98 | + } | |
99 | + </style> | |
75 | 100 | </head> |
76 | 101 | |
77 | -<body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6"> | |
78 | - | |
79 | -<table class="body-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6"><tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"><td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td> | |
80 | - <td class="container" width="600" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;" valign="top"> | |
81 | - <div class="content" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;"> | |
82 | - <table class="main" width="100%" cellpadding="0" cellspacing="0" itemprop="action" itemscope itemtype="http://schema.org/ConfirmAction" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff"><tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"><td class="content-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top"> | |
83 | - <meta itemprop="name" content="Confirm Email" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;" /><table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
84 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
85 | - <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; color: #348eda; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top"> | |
86 | - <h2>Thingsboard Api Usage State for tenant has been updated</h2> | |
87 | - </td> | |
88 | - </tr> | |
89 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
90 | - <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top"> | |
91 | - Thingsboard Usage state ${apiFeature} was updated to status DISABLED. | |
92 | - </td> | |
93 | - </tr> | |
94 | - <#list apiUsageStateMailMessages as msg> | |
95 | - <tr> | |
96 | - <td> | |
97 | - ${msg.key.apiLimitKey} = ${msg.threshold} | |
98 | - </td> | |
99 | - </tr> | |
100 | - <tr> | |
101 | - <td> | |
102 | - ${msg.key.apiCountKey} = ${msg.value} | |
103 | - </td> | |
104 | - </tr> | |
105 | - </#list> | |
106 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
107 | - <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top"> | |
108 | - — The Thingsboard | |
109 | - </td> | |
110 | - </tr></table></td> | |
111 | - </tr> | |
112 | - </table> | |
113 | - <div class="footer" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;"> | |
114 | - <table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
115 | - <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
116 | - <td class="aligncenter content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;" align="center" valign="top">This email was sent to <a href="mailto:${targetEmail}" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;">${targetEmail}</a> by Thingsboard.</td> | |
117 | - </tr> | |
118 | - </table> | |
119 | - </div> | |
120 | - </div> | |
121 | - </td> | |
122 | - <td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td> | |
123 | - </tr> | |
102 | +<body itemscope itemtype="http://schema.org/EmailMessage" | |
103 | + style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" | |
104 | + bgcolor="#f6f6f6"> | |
105 | + | |
106 | +<table class="main" | |
107 | + style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; box-sizing: border-box; border-radius: 3px; width: 100%; background-color: #f6f6f6; margin: 0px auto;" | |
108 | + cellspacing="0" cellpadding="0" bgcolor="#f6f6f6"> | |
109 | + <tbody> | |
110 | + <tr style="box-sizing: border-box; margin: 0px;"> | |
111 | + <td class="content-wrap" style="box-sizing: border-box; vertical-align: top; margin: 0px; padding: 20px;" | |
112 | + align="center" valign="top"> | |
113 | + <table style="box-sizing: border-box; border: 1px solid #e9e9e9; border-radius: 3px; margin: 0px; height: 223px; padding: 20px; background-color: #ffffff; width: 600px; max-width: 600px !important;" | |
114 | + width="600" cellspacing="0" cellpadding="0"> | |
115 | + <tbody> | |
116 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
117 | + <td class="content-block" | |
118 | + style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; color: #348eda; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 84px;" | |
119 | + valign="top"> | |
120 | + <h2>Your ThingsBoard account feature was disabled</h2> | |
121 | + </td> | |
122 | + </tr> | |
123 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
124 | + <td class="content-block" | |
125 | + style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 40px;" | |
126 | + valign="top">We have disabled the ${apiFeature} for your account because ThingsBoard has already ${apiLimitValueLabel} | |
127 | + . | |
128 | + </td> | |
129 | + </tr> | |
130 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
131 | + <td class="content-block" | |
132 | + style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 59px;" | |
133 | + valign="top">Please contact your system administrator to resolve the issue. | |
134 | + </td> | |
135 | + </tr> | |
136 | + <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"> | |
137 | + <td class="content-block" | |
138 | + style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0px; padding: 0px 0px 20px; height: 40px;" | |
139 | + valign="top">— The ThingsBoard | |
140 | + </td> | |
141 | + </tr> | |
142 | + </tbody> | |
143 | + </table> | |
144 | + </td> | |
145 | + </tr> | |
146 | + </tbody> | |
147 | +</table> | |
148 | +<table style="color: #999999; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; box-sizing: border-box; margin: 0px auto; height: 64px; background-color: #f6f6f6; width: 100%;" | |
149 | + cellpadding="0px 0px 20px"> | |
150 | + <tbody> | |
151 | + <tr style="box-sizing: border-box; margin: 0px;"> | |
152 | + <td class="aligncenter content-block" | |
153 | + style="box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px 0px 20px; width: 600px; text-align: center; vertical-align: middle;" | |
154 | + align="center" valign="top">This email was sent to <a | |
155 | + style="box-sizing: border-box; color: #999999; margin: 0px;" | |
156 | + href="mailto:${targetEmail}">${targetEmail}</a> by ThingsBoard. | |
157 | + </td> | |
158 | + </tr> | |
159 | + </tbody> | |
124 | 160 | </table> |
125 | 161 | </body> |
126 | 162 | </html> | ... | ... |
... | ... | @@ -18,16 +18,19 @@ package org.thingsboard.server.common.data; |
18 | 18 | import lombok.Getter; |
19 | 19 | |
20 | 20 | public enum ApiFeature { |
21 | - TRANSPORT("transportApiState"), | |
22 | - DB("dbApiState"), | |
23 | - RE("ruleEngineApiState"), | |
24 | - JS("jsExecutionApiState"); | |
21 | + TRANSPORT("transportApiState", "Device API"), | |
22 | + DB("dbApiState", "Telemetry persistence"), | |
23 | + RE("ruleEngineApiState", "Rule engine execution"), | |
24 | + JS("jsExecutionApiState", "JavaScript functions execution"); | |
25 | 25 | |
26 | 26 | @Getter |
27 | 27 | private final String apiStateKey; |
28 | + @Getter | |
29 | + private final String label; | |
28 | 30 | |
29 | - ApiFeature(String apiStateKey) { | |
31 | + ApiFeature(String apiStateKey, String label) { | |
30 | 32 | this.apiStateKey = apiStateKey; |
33 | + this.label = label; | |
31 | 34 | } |
32 | 35 | |
33 | 36 | } | ... | ... |
... | ... | @@ -43,5 +43,5 @@ public interface MailService { |
43 | 43 | |
44 | 44 | void sendAccountLockoutEmail( String lockoutEmail, String email, Integer maxFailedLoginAttempts) throws ThingsboardException; |
45 | 45 | |
46 | - void sendApiFeatureStateEmail(ApiFeature apiFeature, ApiUsageStateValue stateValue, String email, ApiUsageStateMailMessage[] stateMailMessages) throws ThingsboardException; | |
46 | + void sendApiFeatureStateEmail(ApiFeature apiFeature, ApiUsageStateValue stateValue, String email, ApiUsageStateMailMessage msg) throws ThingsboardException; | |
47 | 47 | } | ... | ... |