Showing
17 changed files
with
126 additions
and
43 deletions
@@ -34,6 +34,7 @@ import org.thingsboard.rule.engine.api.TbRelationTypes; | @@ -34,6 +34,7 @@ import org.thingsboard.rule.engine.api.TbRelationTypes; | ||
34 | import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; | 34 | import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; |
35 | import org.thingsboard.server.actors.ActorSystemContext; | 35 | import org.thingsboard.server.actors.ActorSystemContext; |
36 | import org.thingsboard.server.actors.TbActorRef; | 36 | import org.thingsboard.server.actors.TbActorRef; |
37 | +import org.thingsboard.server.common.data.ApiUsageRecordKey; | ||
37 | import org.thingsboard.server.common.data.Customer; | 38 | import org.thingsboard.server.common.data.Customer; |
38 | import org.thingsboard.server.common.data.DataConstants; | 39 | import org.thingsboard.server.common.data.DataConstants; |
39 | import org.thingsboard.server.common.data.Device; | 40 | import org.thingsboard.server.common.data.Device; |
@@ -21,7 +21,6 @@ import freemarker.template.Template; | @@ -21,7 +21,6 @@ import freemarker.template.Template; | ||
21 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
22 | import org.apache.commons.lang3.StringUtils; | 22 | import org.apache.commons.lang3.StringUtils; |
23 | import org.jetbrains.annotations.NotNull; | 23 | import org.jetbrains.annotations.NotNull; |
24 | -import org.springframework.beans.factory.annotation.Autowired; | ||
25 | import org.springframework.context.MessageSource; | 24 | import org.springframework.context.MessageSource; |
26 | import org.springframework.core.NestedRuntimeException; | 25 | import org.springframework.core.NestedRuntimeException; |
27 | import org.springframework.mail.javamail.JavaMailSenderImpl; | 26 | import org.springframework.mail.javamail.JavaMailSenderImpl; |
@@ -40,6 +39,8 @@ import org.thingsboard.server.common.data.id.EntityId; | @@ -40,6 +39,8 @@ import org.thingsboard.server.common.data.id.EntityId; | ||
40 | import org.thingsboard.server.common.data.id.TenantId; | 39 | import org.thingsboard.server.common.data.id.TenantId; |
41 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 40 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
42 | import org.thingsboard.server.dao.settings.AdminSettingsService; | 41 | import org.thingsboard.server.dao.settings.AdminSettingsService; |
42 | +import org.thingsboard.server.queue.usagestats.TbApiUsageClient; | ||
43 | +import org.thingsboard.server.service.apiusage.TbApiUsageStateService; | ||
43 | 44 | ||
44 | import javax.annotation.PostConstruct; | 45 | import javax.annotation.PostConstruct; |
45 | import javax.mail.MessagingException; | 46 | import javax.mail.MessagingException; |
@@ -58,18 +59,24 @@ public class DefaultMailService implements MailService { | @@ -58,18 +59,24 @@ public class DefaultMailService implements MailService { | ||
58 | public static final String UTF_8 = "UTF-8"; | 59 | public static final String UTF_8 = "UTF-8"; |
59 | public static final int _10K = 10000; | 60 | public static final int _10K = 10000; |
60 | public static final int _1M = 1000000; | 61 | public static final int _1M = 1000000; |
61 | - @Autowired | ||
62 | - private MessageSource messages; | ||
63 | 62 | ||
64 | - @Autowired | ||
65 | - private Configuration freemarkerConfig; | 63 | + private final MessageSource messages; |
64 | + private final Configuration freemarkerConfig; | ||
65 | + private final AdminSettingsService adminSettingsService; | ||
66 | + private final TbApiUsageStateService apiUsageStateService; | ||
67 | + private final TbApiUsageClient apiUsageClient; | ||
66 | 68 | ||
67 | private JavaMailSenderImpl mailSender; | 69 | private JavaMailSenderImpl mailSender; |
68 | 70 | ||
69 | private String mailFrom; | 71 | private String mailFrom; |
70 | 72 | ||
71 | - @Autowired | ||
72 | - private AdminSettingsService adminSettingsService; | 73 | + public DefaultMailService(MessageSource messages, Configuration freemarkerConfig, AdminSettingsService adminSettingsService, TbApiUsageStateService apiUsageStateService, TbApiUsageClient apiUsageClient) { |
74 | + this.messages = messages; | ||
75 | + this.freemarkerConfig = freemarkerConfig; | ||
76 | + this.adminSettingsService = adminSettingsService; | ||
77 | + this.apiUsageStateService = apiUsageStateService; | ||
78 | + this.apiUsageClient = apiUsageClient; | ||
79 | + } | ||
73 | 80 | ||
74 | @PostConstruct | 81 | @PostConstruct |
75 | private void init() { | 82 | private void init() { |
@@ -148,8 +155,11 @@ public class DefaultMailService implements MailService { | @@ -148,8 +155,11 @@ public class DefaultMailService implements MailService { | ||
148 | } | 155 | } |
149 | 156 | ||
150 | @Override | 157 | @Override |
151 | - public void sendEmail(String email, String subject, String message) throws ThingsboardException { | ||
152 | - sendMail(mailSender, mailFrom, email, subject, message); | 158 | + public void sendEmail(TenantId tenantId, String email, String subject, String message) throws ThingsboardException { |
159 | + if (apiUsageStateService.getApiUsageState(tenantId).isEmailSendEnabled()) { | ||
160 | + sendMail(mailSender, mailFrom, email, subject, message); | ||
161 | + apiUsageClient.report(tenantId, ApiUsageRecordKey.EMAIL_EXEC_COUNT, 1); | ||
162 | + } | ||
153 | } | 163 | } |
154 | 164 | ||
155 | @Override | 165 | @Override |
@@ -223,20 +233,23 @@ public class DefaultMailService implements MailService { | @@ -223,20 +233,23 @@ public class DefaultMailService implements MailService { | ||
223 | } | 233 | } |
224 | 234 | ||
225 | @Override | 235 | @Override |
226 | - public void send(String from, String to, String cc, String bcc, String subject, String body) throws MessagingException { | ||
227 | - MimeMessage mailMsg = mailSender.createMimeMessage(); | ||
228 | - MimeMessageHelper helper = new MimeMessageHelper(mailMsg, "UTF-8"); | ||
229 | - helper.setFrom(StringUtils.isBlank(from) ? mailFrom : from); | ||
230 | - helper.setTo(to.split("\\s*,\\s*")); | ||
231 | - if (!StringUtils.isBlank(cc)) { | ||
232 | - helper.setCc(cc.split("\\s*,\\s*")); | ||
233 | - } | ||
234 | - if (!StringUtils.isBlank(bcc)) { | ||
235 | - helper.setBcc(bcc.split("\\s*,\\s*")); | 236 | + public void send(TenantId tenantId, String from, String to, String cc, String bcc, String subject, String body) throws MessagingException { |
237 | + if (apiUsageStateService.getApiUsageState(tenantId).isEmailSendEnabled()) { | ||
238 | + MimeMessage mailMsg = mailSender.createMimeMessage(); | ||
239 | + MimeMessageHelper helper = new MimeMessageHelper(mailMsg, "UTF-8"); | ||
240 | + helper.setFrom(StringUtils.isBlank(from) ? mailFrom : from); | ||
241 | + helper.setTo(to.split("\\s*,\\s*")); | ||
242 | + if (!StringUtils.isBlank(cc)) { | ||
243 | + helper.setCc(cc.split("\\s*,\\s*")); | ||
244 | + } | ||
245 | + if (!StringUtils.isBlank(bcc)) { | ||
246 | + helper.setBcc(bcc.split("\\s*,\\s*")); | ||
247 | + } | ||
248 | + helper.setSubject(subject); | ||
249 | + helper.setText(body); | ||
250 | + mailSender.send(helper.getMimeMessage()); | ||
251 | + apiUsageClient.report(tenantId, ApiUsageRecordKey.EMAIL_EXEC_COUNT, 1); | ||
236 | } | 252 | } |
237 | - helper.setSubject(subject); | ||
238 | - helper.setText(body); | ||
239 | - mailSender.send(helper.getMimeMessage()); | ||
240 | } | 253 | } |
241 | 254 | ||
242 | @Override | 255 | @Override |
@@ -17,7 +17,6 @@ package org.thingsboard.server.service.sms; | @@ -17,7 +17,6 @@ package org.thingsboard.server.service.sms; | ||
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
20 | -import org.springframework.beans.factory.annotation.Autowired; | ||
21 | import org.springframework.core.NestedRuntimeException; | 20 | import org.springframework.core.NestedRuntimeException; |
22 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
23 | import org.thingsboard.rule.engine.api.SmsService; | 22 | import org.thingsboard.rule.engine.api.SmsService; |
@@ -26,12 +25,15 @@ import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; | @@ -26,12 +25,15 @@ import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; | ||
26 | import org.thingsboard.rule.engine.api.sms.config.SmsProviderConfiguration; | 25 | import org.thingsboard.rule.engine.api.sms.config.SmsProviderConfiguration; |
27 | import org.thingsboard.rule.engine.api.sms.config.TestSmsRequest; | 26 | import org.thingsboard.rule.engine.api.sms.config.TestSmsRequest; |
28 | import org.thingsboard.server.common.data.AdminSettings; | 27 | import org.thingsboard.server.common.data.AdminSettings; |
28 | +import org.thingsboard.server.common.data.ApiUsageRecordKey; | ||
29 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; | 29 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
30 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 30 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
31 | import org.thingsboard.server.common.data.id.EntityId; | 31 | import org.thingsboard.server.common.data.id.EntityId; |
32 | import org.thingsboard.server.common.data.id.TenantId; | 32 | import org.thingsboard.server.common.data.id.TenantId; |
33 | import org.thingsboard.server.dao.settings.AdminSettingsService; | 33 | import org.thingsboard.server.dao.settings.AdminSettingsService; |
34 | import org.thingsboard.server.dao.util.mapping.JacksonUtil; | 34 | import org.thingsboard.server.dao.util.mapping.JacksonUtil; |
35 | +import org.thingsboard.server.queue.usagestats.TbApiUsageClient; | ||
36 | +import org.thingsboard.server.service.apiusage.TbApiUsageStateService; | ||
35 | 37 | ||
36 | import javax.annotation.PostConstruct; | 38 | import javax.annotation.PostConstruct; |
37 | import javax.annotation.PreDestroy; | 39 | import javax.annotation.PreDestroy; |
@@ -40,14 +42,20 @@ import javax.annotation.PreDestroy; | @@ -40,14 +42,20 @@ import javax.annotation.PreDestroy; | ||
40 | @Slf4j | 42 | @Slf4j |
41 | public class DefaultSmsService implements SmsService { | 43 | public class DefaultSmsService implements SmsService { |
42 | 44 | ||
43 | - @Autowired | ||
44 | - private SmsSenderFactory smsSenderFactory; | ||
45 | - | ||
46 | - @Autowired | ||
47 | - private AdminSettingsService adminSettingsService; | 45 | + private final SmsSenderFactory smsSenderFactory; |
46 | + private final AdminSettingsService adminSettingsService; | ||
47 | + private final TbApiUsageStateService apiUsageStateService; | ||
48 | + private final TbApiUsageClient apiUsageClient; | ||
48 | 49 | ||
49 | private SmsSender smsSender; | 50 | private SmsSender smsSender; |
50 | 51 | ||
52 | + public DefaultSmsService(SmsSenderFactory smsSenderFactory, AdminSettingsService adminSettingsService, TbApiUsageStateService apiUsageStateService, TbApiUsageClient apiUsageClient) { | ||
53 | + this.smsSenderFactory = smsSenderFactory; | ||
54 | + this.adminSettingsService = adminSettingsService; | ||
55 | + this.apiUsageStateService = apiUsageStateService; | ||
56 | + this.apiUsageClient = apiUsageClient; | ||
57 | + } | ||
58 | + | ||
51 | @PostConstruct | 59 | @PostConstruct |
52 | private void init() { | 60 | private void init() { |
53 | updateSmsConfiguration(); | 61 | updateSmsConfiguration(); |
@@ -78,18 +86,26 @@ public class DefaultSmsService implements SmsService { | @@ -78,18 +86,26 @@ public class DefaultSmsService implements SmsService { | ||
78 | } | 86 | } |
79 | } | 87 | } |
80 | 88 | ||
81 | - @Override | ||
82 | - public void sendSms(String numberTo, String message) throws ThingsboardException { | 89 | + private int sendSms(String numberTo, String message) throws ThingsboardException { |
83 | if (this.smsSender == null) { | 90 | if (this.smsSender == null) { |
84 | throw new ThingsboardException("Unable to send SMS: no SMS provider configured!", ThingsboardErrorCode.GENERAL); | 91 | throw new ThingsboardException("Unable to send SMS: no SMS provider configured!", ThingsboardErrorCode.GENERAL); |
85 | } | 92 | } |
86 | - this.sendSms(this.smsSender, numberTo, message); | 93 | + return this.sendSms(this.smsSender, numberTo, message); |
87 | } | 94 | } |
88 | 95 | ||
89 | @Override | 96 | @Override |
90 | - public void sendSms(String[] numbersTo, String message) throws ThingsboardException { | ||
91 | - for (String numberTo : numbersTo) { | ||
92 | - this.sendSms(numberTo, message); | 97 | + public void sendSms(TenantId tenantId, String[] numbersTo, String message) throws ThingsboardException { |
98 | + if (apiUsageStateService.getApiUsageState(tenantId).isSmsSendEnabled()) { | ||
99 | + int smsCount = 0; | ||
100 | + try { | ||
101 | + for (String numberTo : numbersTo) { | ||
102 | + smsCount += this.sendSms(numberTo, message); | ||
103 | + } | ||
104 | + } finally { | ||
105 | + if (smsCount > 0) { | ||
106 | + apiUsageClient.report(tenantId, ApiUsageRecordKey.SMS_EXEC_COUNT, smsCount); | ||
107 | + } | ||
108 | + } | ||
93 | } | 109 | } |
94 | } | 110 | } |
95 | 111 |
@@ -21,7 +21,9 @@ public enum ApiFeature { | @@ -21,7 +21,9 @@ public enum ApiFeature { | ||
21 | TRANSPORT("transportApiState", "Device API"), | 21 | TRANSPORT("transportApiState", "Device API"), |
22 | DB("dbApiState", "Telemetry persistence"), | 22 | DB("dbApiState", "Telemetry persistence"), |
23 | RE("ruleEngineApiState", "Rule Engine execution"), | 23 | RE("ruleEngineApiState", "Rule Engine execution"), |
24 | - JS("jsExecutionApiState", "JavaScript functions execution"); | 24 | + JS("jsExecutionApiState", "JavaScript functions execution"), |
25 | + EMAIL("emailApiState", "Email messages"), | ||
26 | + SMS("smsApiState", "SMS messages"); | ||
25 | 27 | ||
26 | @Getter | 28 | @Getter |
27 | private final String apiStateKey; | 29 | private final String apiStateKey; |
@@ -23,11 +23,15 @@ public enum ApiUsageRecordKey { | @@ -23,11 +23,15 @@ public enum ApiUsageRecordKey { | ||
23 | TRANSPORT_DP_COUNT(ApiFeature.TRANSPORT, "transportDataPointsCount", "transportDataPointsLimit"), | 23 | TRANSPORT_DP_COUNT(ApiFeature.TRANSPORT, "transportDataPointsCount", "transportDataPointsLimit"), |
24 | STORAGE_DP_COUNT(ApiFeature.DB, "storageDataPointsCount", "storageDataPointsLimit"), | 24 | STORAGE_DP_COUNT(ApiFeature.DB, "storageDataPointsCount", "storageDataPointsLimit"), |
25 | RE_EXEC_COUNT(ApiFeature.RE, "ruleEngineExecutionCount", "ruleEngineExecutionLimit"), | 25 | RE_EXEC_COUNT(ApiFeature.RE, "ruleEngineExecutionCount", "ruleEngineExecutionLimit"), |
26 | - JS_EXEC_COUNT(ApiFeature.JS, "jsExecutionCount", "jsExecutionLimit"); | 26 | + JS_EXEC_COUNT(ApiFeature.JS, "jsExecutionCount", "jsExecutionLimit"), |
27 | + EMAIL_EXEC_COUNT(ApiFeature.EMAIL, "emailCount", "emailLimit"), | ||
28 | + SMS_EXEC_COUNT(ApiFeature.SMS, "smsCount", "smsLimit"); | ||
27 | private static final ApiUsageRecordKey[] JS_RECORD_KEYS = {JS_EXEC_COUNT}; | 29 | private static final ApiUsageRecordKey[] JS_RECORD_KEYS = {JS_EXEC_COUNT}; |
28 | private static final ApiUsageRecordKey[] RE_RECORD_KEYS = {RE_EXEC_COUNT}; | 30 | private static final ApiUsageRecordKey[] RE_RECORD_KEYS = {RE_EXEC_COUNT}; |
29 | private static final ApiUsageRecordKey[] DB_RECORD_KEYS = {STORAGE_DP_COUNT}; | 31 | private static final ApiUsageRecordKey[] DB_RECORD_KEYS = {STORAGE_DP_COUNT}; |
30 | private static final ApiUsageRecordKey[] TRANSPORT_RECORD_KEYS = {TRANSPORT_MSG_COUNT, TRANSPORT_DP_COUNT}; | 32 | private static final ApiUsageRecordKey[] TRANSPORT_RECORD_KEYS = {TRANSPORT_MSG_COUNT, TRANSPORT_DP_COUNT}; |
33 | + private static final ApiUsageRecordKey[] EMAIL_RECORD_KEYS = {EMAIL_EXEC_COUNT}; | ||
34 | + private static final ApiUsageRecordKey[] SMS_RECORD_KEYS = {SMS_EXEC_COUNT}; | ||
31 | 35 | ||
32 | @Getter | 36 | @Getter |
33 | private final ApiFeature apiFeature; | 37 | private final ApiFeature apiFeature; |
@@ -52,6 +56,10 @@ public enum ApiUsageRecordKey { | @@ -52,6 +56,10 @@ public enum ApiUsageRecordKey { | ||
52 | return RE_RECORD_KEYS; | 56 | return RE_RECORD_KEYS; |
53 | case JS: | 57 | case JS: |
54 | return JS_RECORD_KEYS; | 58 | return JS_RECORD_KEYS; |
59 | + case EMAIL: | ||
60 | + return EMAIL_RECORD_KEYS; | ||
61 | + case SMS: | ||
62 | + return SMS_RECORD_KEYS; | ||
55 | default: | 63 | default: |
56 | return new ApiUsageRecordKey[]{}; | 64 | return new ApiUsageRecordKey[]{}; |
57 | } | 65 | } |
@@ -47,6 +47,12 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan | @@ -47,6 +47,12 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan | ||
47 | @Getter | 47 | @Getter |
48 | @Setter | 48 | @Setter |
49 | private ApiUsageStateValue jsExecState; | 49 | private ApiUsageStateValue jsExecState; |
50 | + @Getter | ||
51 | + @Setter | ||
52 | + private ApiUsageStateValue emailExecState; | ||
53 | + @Getter | ||
54 | + @Setter | ||
55 | + private ApiUsageStateValue smsExecState; | ||
50 | 56 | ||
51 | public ApiUsageState() { | 57 | public ApiUsageState() { |
52 | super(); | 58 | super(); |
@@ -64,6 +70,8 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan | @@ -64,6 +70,8 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan | ||
64 | this.dbStorageState = ur.getDbStorageState(); | 70 | this.dbStorageState = ur.getDbStorageState(); |
65 | this.reExecState = ur.getReExecState(); | 71 | this.reExecState = ur.getReExecState(); |
66 | this.jsExecState = ur.getJsExecState(); | 72 | this.jsExecState = ur.getJsExecState(); |
73 | + this.emailExecState = ur.getEmailExecState(); | ||
74 | + this.smsExecState = ur.getSmsExecState(); | ||
67 | } | 75 | } |
68 | 76 | ||
69 | public boolean isTransportEnabled() { | 77 | public boolean isTransportEnabled() { |
@@ -81,4 +89,12 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan | @@ -81,4 +89,12 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan | ||
81 | public boolean isJsExecEnabled() { | 89 | public boolean isJsExecEnabled() { |
82 | return !ApiUsageStateValue.DISABLED.equals(jsExecState); | 90 | return !ApiUsageStateValue.DISABLED.equals(jsExecState); |
83 | } | 91 | } |
92 | + | ||
93 | + public boolean isEmailSendEnabled(){ | ||
94 | + return !ApiUsageStateValue.DISABLED.equals(emailExecState); | ||
95 | + } | ||
96 | + | ||
97 | + public boolean isSmsSendEnabled(){ | ||
98 | + return !ApiUsageStateValue.DISABLED.equals(smsExecState); | ||
99 | + } | ||
84 | } | 100 | } |
@@ -42,6 +42,8 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura | @@ -42,6 +42,8 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura | ||
42 | private long maxJSExecutions; | 42 | private long maxJSExecutions; |
43 | private long maxDPStorageDays; | 43 | private long maxDPStorageDays; |
44 | private int maxRuleNodeExecutionsPerMessage; | 44 | private int maxRuleNodeExecutionsPerMessage; |
45 | + private long maxEmails; | ||
46 | + private long maxSms; | ||
45 | 47 | ||
46 | private double warnThreshold; | 48 | private double warnThreshold; |
47 | 49 | ||
@@ -58,6 +60,10 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura | @@ -58,6 +60,10 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura | ||
58 | return maxREExecutions; | 60 | return maxREExecutions; |
59 | case STORAGE_DP_COUNT: | 61 | case STORAGE_DP_COUNT: |
60 | return maxDPStorageDays; | 62 | return maxDPStorageDays; |
63 | + case EMAIL_EXEC_COUNT: | ||
64 | + return maxEmails; | ||
65 | + case SMS_EXEC_COUNT: | ||
66 | + return maxSms; | ||
61 | } | 67 | } |
62 | return 0L; | 68 | return 0L; |
63 | } | 69 | } |
@@ -450,6 +450,8 @@ public class ModelConstants { | @@ -450,6 +450,8 @@ public class ModelConstants { | ||
450 | public static final String API_USAGE_STATE_DB_STORAGE_COLUMN = "db_storage"; | 450 | public static final String API_USAGE_STATE_DB_STORAGE_COLUMN = "db_storage"; |
451 | public static final String API_USAGE_STATE_RE_EXEC_COLUMN = "re_exec"; | 451 | public static final String API_USAGE_STATE_RE_EXEC_COLUMN = "re_exec"; |
452 | public static final String API_USAGE_STATE_JS_EXEC_COLUMN = "js_exec"; | 452 | public static final String API_USAGE_STATE_JS_EXEC_COLUMN = "js_exec"; |
453 | + public static final String API_USAGE_STATE_EMAIL_EXEC_COLUMN = "email_exec"; | ||
454 | + public static final String API_USAGE_STATE_SMS_EXEC_COLUMN = "sms_exec"; | ||
453 | 455 | ||
454 | /** | 456 | /** |
455 | * Cassandra attributes and timeseries constants. | 457 | * Cassandra attributes and timeseries constants. |
@@ -63,6 +63,12 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements | @@ -63,6 +63,12 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements | ||
63 | @Enumerated(EnumType.STRING) | 63 | @Enumerated(EnumType.STRING) |
64 | @Column(name = ModelConstants.API_USAGE_STATE_JS_EXEC_COLUMN) | 64 | @Column(name = ModelConstants.API_USAGE_STATE_JS_EXEC_COLUMN) |
65 | private ApiUsageStateValue jsExecState = ApiUsageStateValue.ENABLED; | 65 | private ApiUsageStateValue jsExecState = ApiUsageStateValue.ENABLED; |
66 | + @Enumerated(EnumType.STRING) | ||
67 | + @Column(name = ModelConstants.API_USAGE_STATE_EMAIL_EXEC_COLUMN) | ||
68 | + private ApiUsageStateValue emailExecState = ApiUsageStateValue.ENABLED; | ||
69 | + @Enumerated(EnumType.STRING) | ||
70 | + @Column(name = ModelConstants.API_USAGE_STATE_SMS_EXEC_COLUMN) | ||
71 | + private ApiUsageStateValue smsExecState = ApiUsageStateValue.ENABLED; | ||
66 | 72 | ||
67 | public ApiUsageStateEntity() { | 73 | public ApiUsageStateEntity() { |
68 | } | 74 | } |
@@ -83,6 +89,8 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements | @@ -83,6 +89,8 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements | ||
83 | this.dbStorageState = ur.getDbStorageState(); | 89 | this.dbStorageState = ur.getDbStorageState(); |
84 | this.reExecState = ur.getReExecState(); | 90 | this.reExecState = ur.getReExecState(); |
85 | this.jsExecState = ur.getJsExecState(); | 91 | this.jsExecState = ur.getJsExecState(); |
92 | + this.emailExecState = ur.getEmailExecState(); | ||
93 | + this.smsExecState = ur.getSmsExecState(); | ||
86 | } | 94 | } |
87 | 95 | ||
88 | @Override | 96 | @Override |
@@ -99,6 +107,8 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements | @@ -99,6 +107,8 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements | ||
99 | ur.setDbStorageState(dbStorageState); | 107 | ur.setDbStorageState(dbStorageState); |
100 | ur.setReExecState(reExecState); | 108 | ur.setReExecState(reExecState); |
101 | ur.setJsExecState(jsExecState); | 109 | ur.setJsExecState(jsExecState); |
110 | + ur.setEmailExecState(emailExecState); | ||
111 | + ur.setSmsExecState(smsExecState); | ||
102 | return ur; | 112 | return ur; |
103 | } | 113 | } |
104 | 114 |
@@ -78,6 +78,8 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A | @@ -78,6 +78,8 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A | ||
78 | apiUsageState.setReExecState(ApiUsageStateValue.ENABLED); | 78 | apiUsageState.setReExecState(ApiUsageStateValue.ENABLED); |
79 | apiUsageState.setJsExecState(ApiUsageStateValue.ENABLED); | 79 | apiUsageState.setJsExecState(ApiUsageStateValue.ENABLED); |
80 | apiUsageState.setDbStorageState(ApiUsageStateValue.ENABLED); | 80 | apiUsageState.setDbStorageState(ApiUsageStateValue.ENABLED); |
81 | + apiUsageState.setSmsExecState(ApiUsageStateValue.ENABLED); | ||
82 | + apiUsageState.setEmailExecState(ApiUsageStateValue.ENABLED); | ||
81 | apiUsageStateValidator.validate(apiUsageState, ApiUsageState::getTenantId); | 83 | apiUsageStateValidator.validate(apiUsageState, ApiUsageState::getTenantId); |
82 | 84 | ||
83 | ApiUsageState saved = apiUsageStateDao.save(apiUsageState.getTenantId(), apiUsageState); | 85 | ApiUsageState saved = apiUsageStateDao.save(apiUsageState.getTenantId(), apiUsageState); |
@@ -416,5 +416,7 @@ CREATE TABLE IF NOT EXISTS api_usage_state ( | @@ -416,5 +416,7 @@ CREATE TABLE IF NOT EXISTS api_usage_state ( | ||
416 | db_storage varchar(32), | 416 | db_storage varchar(32), |
417 | re_exec varchar(32), | 417 | re_exec varchar(32), |
418 | js_exec varchar(32), | 418 | js_exec varchar(32), |
419 | + email_exec varchar(32), | ||
420 | + sms_exec varchar(32), | ||
419 | CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id) | 421 | CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id) |
420 | ); | 422 | ); |
@@ -442,6 +442,8 @@ CREATE TABLE IF NOT EXISTS api_usage_state ( | @@ -442,6 +442,8 @@ CREATE TABLE IF NOT EXISTS api_usage_state ( | ||
442 | db_storage varchar(32), | 442 | db_storage varchar(32), |
443 | re_exec varchar(32), | 443 | re_exec varchar(32), |
444 | js_exec varchar(32), | 444 | js_exec varchar(32), |
445 | + email_exec varchar(32), | ||
446 | + sms_exec varchar(32), | ||
445 | CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id) | 447 | CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id) |
446 | ); | 448 | ); |
447 | 449 |
@@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.ApiFeature; | @@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.ApiFeature; | ||
20 | import org.thingsboard.server.common.data.ApiUsageStateMailMessage; | 20 | import org.thingsboard.server.common.data.ApiUsageStateMailMessage; |
21 | import org.thingsboard.server.common.data.ApiUsageStateValue; | 21 | import org.thingsboard.server.common.data.ApiUsageStateValue; |
22 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 22 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
23 | +import org.thingsboard.server.common.data.id.TenantId; | ||
23 | 24 | ||
24 | import javax.mail.MessagingException; | 25 | import javax.mail.MessagingException; |
25 | 26 | ||
@@ -27,7 +28,7 @@ public interface MailService { | @@ -27,7 +28,7 @@ public interface MailService { | ||
27 | 28 | ||
28 | void updateMailConfiguration(); | 29 | void updateMailConfiguration(); |
29 | 30 | ||
30 | - void sendEmail(String email, String subject, String message) throws ThingsboardException; | 31 | + void sendEmail(TenantId tenantId, String email, String subject, String message) throws ThingsboardException; |
31 | 32 | ||
32 | void sendTestMail(JsonNode config, String email) throws ThingsboardException; | 33 | void sendTestMail(JsonNode config, String email) throws ThingsboardException; |
33 | 34 | ||
@@ -39,7 +40,7 @@ public interface MailService { | @@ -39,7 +40,7 @@ public interface MailService { | ||
39 | 40 | ||
40 | void sendPasswordWasResetEmail(String loginLink, String email) throws ThingsboardException; | 41 | void sendPasswordWasResetEmail(String loginLink, String email) throws ThingsboardException; |
41 | 42 | ||
42 | - void send(String from, String to, String cc, String bcc, String subject, String body) throws MessagingException; | 43 | + void send(TenantId tenantId, String from, String to, String cc, String bcc, String subject, String body) throws MessagingException; |
43 | 44 | ||
44 | void sendAccountLockoutEmail( String lockoutEmail, String email, Integer maxFailedLoginAttempts) throws ThingsboardException; | 45 | void sendAccountLockoutEmail( String lockoutEmail, String email, Integer maxFailedLoginAttempts) throws ThingsboardException; |
45 | 46 |
@@ -17,14 +17,13 @@ package org.thingsboard.rule.engine.api; | @@ -17,14 +17,13 @@ package org.thingsboard.rule.engine.api; | ||
17 | 17 | ||
18 | import org.thingsboard.rule.engine.api.sms.config.TestSmsRequest; | 18 | import org.thingsboard.rule.engine.api.sms.config.TestSmsRequest; |
19 | import org.thingsboard.server.common.data.exception.ThingsboardException; | 19 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
20 | +import org.thingsboard.server.common.data.id.TenantId; | ||
20 | 21 | ||
21 | public interface SmsService { | 22 | public interface SmsService { |
22 | 23 | ||
23 | void updateSmsConfiguration(); | 24 | void updateSmsConfiguration(); |
24 | 25 | ||
25 | - void sendSms(String numberTo, String message) throws ThingsboardException; | ||
26 | - | ||
27 | - void sendSms(String[] numbersTo, String message) throws ThingsboardException;; | 26 | + void sendSms(TenantId tenantId, String[] numbersTo, String message) throws ThingsboardException;; |
28 | 27 | ||
29 | void sendTestSms(TestSmsRequest testSmsRequest) throws ThingsboardException; | 28 | void sendTestSms(TestSmsRequest testSmsRequest) throws ThingsboardException; |
30 | 29 |
@@ -19,6 +19,7 @@ import io.netty.channel.EventLoopGroup; | @@ -19,6 +19,7 @@ import io.netty.channel.EventLoopGroup; | ||
19 | import org.springframework.data.redis.core.RedisTemplate; | 19 | import org.springframework.data.redis.core.RedisTemplate; |
20 | import org.thingsboard.common.util.ListeningExecutor; | 20 | import org.thingsboard.common.util.ListeningExecutor; |
21 | import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; | 21 | import org.thingsboard.rule.engine.api.sms.SmsSenderFactory; |
22 | +import org.thingsboard.server.common.data.ApiUsageRecordKey; | ||
22 | import org.thingsboard.server.common.data.Customer; | 23 | import org.thingsboard.server.common.data.Customer; |
23 | import org.thingsboard.server.common.data.Device; | 24 | import org.thingsboard.server.common.data.Device; |
24 | import org.thingsboard.server.common.data.DeviceProfile; | 25 | import org.thingsboard.server.common.data.DeviceProfile; |
@@ -26,6 +26,7 @@ import org.thingsboard.rule.engine.api.TbNode; | @@ -26,6 +26,7 @@ import org.thingsboard.rule.engine.api.TbNode; | ||
26 | import org.thingsboard.rule.engine.api.TbNodeConfiguration; | 26 | import org.thingsboard.rule.engine.api.TbNodeConfiguration; |
27 | import org.thingsboard.rule.engine.api.TbNodeException; | 27 | import org.thingsboard.rule.engine.api.TbNodeException; |
28 | import org.thingsboard.rule.engine.api.util.TbNodeUtils; | 28 | import org.thingsboard.rule.engine.api.util.TbNodeUtils; |
29 | +import org.thingsboard.server.common.data.ApiUsageRecordKey; | ||
29 | import org.thingsboard.server.common.data.plugin.ComponentType; | 30 | import org.thingsboard.server.common.data.plugin.ComponentType; |
30 | import org.thingsboard.server.common.msg.TbMsg; | 31 | import org.thingsboard.server.common.msg.TbMsg; |
31 | 32 | ||
@@ -87,7 +88,7 @@ public class TbSendEmailNode implements TbNode { | @@ -87,7 +88,7 @@ public class TbSendEmailNode implements TbNode { | ||
87 | 88 | ||
88 | private void sendEmail(TbContext ctx, EmailPojo email) throws Exception { | 89 | private void sendEmail(TbContext ctx, EmailPojo email) throws Exception { |
89 | if (this.config.isUseSystemSmtpSettings()) { | 90 | if (this.config.isUseSystemSmtpSettings()) { |
90 | - ctx.getMailService().send(email.getFrom(), email.getTo(), email.getCc(), | 91 | + ctx.getMailService().send(ctx.getTenantId(), email.getFrom(), email.getTo(), email.getCc(), |
91 | email.getBcc(), email.getSubject(), email.getBody()); | 92 | email.getBcc(), email.getSubject(), email.getBody()); |
92 | } else { | 93 | } else { |
93 | MimeMessage mailMsg = mailSender.createMimeMessage(); | 94 | MimeMessage mailMsg = mailSender.createMimeMessage(); |
@@ -23,6 +23,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; | @@ -23,6 +23,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration; | ||
23 | import org.thingsboard.rule.engine.api.TbNodeException; | 23 | import org.thingsboard.rule.engine.api.TbNodeException; |
24 | import org.thingsboard.rule.engine.api.sms.SmsSender; | 24 | import org.thingsboard.rule.engine.api.sms.SmsSender; |
25 | import org.thingsboard.rule.engine.api.util.TbNodeUtils; | 25 | import org.thingsboard.rule.engine.api.util.TbNodeUtils; |
26 | +import org.thingsboard.server.common.data.ApiUsageRecordKey; | ||
26 | import org.thingsboard.server.common.data.plugin.ComponentType; | 27 | import org.thingsboard.server.common.data.plugin.ComponentType; |
27 | import org.thingsboard.server.common.msg.TbMsg; | 28 | import org.thingsboard.server.common.msg.TbMsg; |
28 | 29 | ||
@@ -75,7 +76,7 @@ public class TbSendSmsNode implements TbNode { | @@ -75,7 +76,7 @@ public class TbSendSmsNode implements TbNode { | ||
75 | String message = TbNodeUtils.processPattern(this.config.getSmsMessageTemplate(), msg.getMetaData()); | 76 | String message = TbNodeUtils.processPattern(this.config.getSmsMessageTemplate(), msg.getMetaData()); |
76 | String[] numbersToList = numbersTo.split(","); | 77 | String[] numbersToList = numbersTo.split(","); |
77 | if (this.config.isUseSystemSmsSettings()) { | 78 | if (this.config.isUseSystemSmsSettings()) { |
78 | - ctx.getSmsService().sendSms(numbersToList, message); | 79 | + ctx.getSmsService().sendSms(ctx.getTenantId(), numbersToList, message); |
79 | } else { | 80 | } else { |
80 | for (String numberTo : numbersToList) { | 81 | for (String numberTo : numbersToList) { |
81 | this.smsSender.sendSms(numberTo, message); | 82 | this.smsSender.sendSms(numberTo, message); |