Merge pull request #3760 from thingsboard/feature/sms-email-limits
Feature/sms email limits
This commit is contained in:
commit
2b868646bb
@ -34,6 +34,7 @@ import org.thingsboard.rule.engine.api.TbRelationTypes;
|
||||
import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
|
||||
import org.thingsboard.server.actors.ActorSystemContext;
|
||||
import org.thingsboard.server.actors.TbActorRef;
|
||||
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||
import org.thingsboard.server.common.data.Customer;
|
||||
import org.thingsboard.server.common.data.DataConstants;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
|
||||
@ -23,6 +23,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
@ -40,6 +41,8 @@ import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.dao.exception.IncorrectParameterException;
|
||||
import org.thingsboard.server.dao.settings.AdminSettingsService;
|
||||
import org.thingsboard.server.queue.usagestats.TbApiUsageClient;
|
||||
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.mail.MessagingException;
|
||||
@ -58,18 +61,26 @@ public class DefaultMailService implements MailService {
|
||||
public static final String UTF_8 = "UTF-8";
|
||||
public static final int _10K = 10000;
|
||||
public static final int _1M = 1000000;
|
||||
@Autowired
|
||||
private MessageSource messages;
|
||||
|
||||
private final MessageSource messages;
|
||||
private final Configuration freemarkerConfig;
|
||||
private final AdminSettingsService adminSettingsService;
|
||||
private final TbApiUsageClient apiUsageClient;
|
||||
|
||||
@Lazy
|
||||
@Autowired
|
||||
private Configuration freemarkerConfig;
|
||||
private TbApiUsageStateService apiUsageStateService;
|
||||
|
||||
private JavaMailSenderImpl mailSender;
|
||||
|
||||
private String mailFrom;
|
||||
|
||||
@Autowired
|
||||
private AdminSettingsService adminSettingsService;
|
||||
public DefaultMailService(MessageSource messages, Configuration freemarkerConfig, AdminSettingsService adminSettingsService, TbApiUsageClient apiUsageClient) {
|
||||
this.messages = messages;
|
||||
this.freemarkerConfig = freemarkerConfig;
|
||||
this.adminSettingsService = adminSettingsService;
|
||||
this.apiUsageClient = apiUsageClient;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
@ -148,8 +159,11 @@ public class DefaultMailService implements MailService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendEmail(String email, String subject, String message) throws ThingsboardException {
|
||||
public void sendEmail(TenantId tenantId, String email, String subject, String message) throws ThingsboardException {
|
||||
if (apiUsageStateService.getApiUsageState(tenantId).isEmailSendEnabled()) {
|
||||
sendMail(mailSender, mailFrom, email, subject, message);
|
||||
apiUsageClient.report(tenantId, ApiUsageRecordKey.EMAIL_EXEC_COUNT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -223,7 +237,8 @@ public class DefaultMailService implements MailService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String from, String to, String cc, String bcc, String subject, String body) throws MessagingException {
|
||||
public void send(TenantId tenantId, String from, String to, String cc, String bcc, String subject, String body) throws MessagingException {
|
||||
if (apiUsageStateService.getApiUsageState(tenantId).isEmailSendEnabled()) {
|
||||
MimeMessage mailMsg = mailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mailMsg, "UTF-8");
|
||||
helper.setFrom(StringUtils.isBlank(from) ? mailFrom : from);
|
||||
@ -237,6 +252,8 @@ public class DefaultMailService implements MailService {
|
||||
helper.setSubject(subject);
|
||||
helper.setText(body);
|
||||
mailSender.send(helper.getMimeMessage());
|
||||
apiUsageClient.report(tenantId, ApiUsageRecordKey.EMAIL_EXEC_COUNT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -17,7 +17,6 @@ package org.thingsboard.server.service.sms;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.rule.engine.api.SmsService;
|
||||
@ -26,12 +25,15 @@ import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
|
||||
import org.thingsboard.rule.engine.api.sms.config.SmsProviderConfiguration;
|
||||
import org.thingsboard.rule.engine.api.sms.config.TestSmsRequest;
|
||||
import org.thingsboard.server.common.data.AdminSettings;
|
||||
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.id.EntityId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.dao.settings.AdminSettingsService;
|
||||
import org.thingsboard.server.dao.util.mapping.JacksonUtil;
|
||||
import org.thingsboard.server.queue.usagestats.TbApiUsageClient;
|
||||
import org.thingsboard.server.service.apiusage.TbApiUsageStateService;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
@ -40,14 +42,20 @@ import javax.annotation.PreDestroy;
|
||||
@Slf4j
|
||||
public class DefaultSmsService implements SmsService {
|
||||
|
||||
@Autowired
|
||||
private SmsSenderFactory smsSenderFactory;
|
||||
|
||||
@Autowired
|
||||
private AdminSettingsService adminSettingsService;
|
||||
private final SmsSenderFactory smsSenderFactory;
|
||||
private final AdminSettingsService adminSettingsService;
|
||||
private final TbApiUsageStateService apiUsageStateService;
|
||||
private final TbApiUsageClient apiUsageClient;
|
||||
|
||||
private SmsSender smsSender;
|
||||
|
||||
public DefaultSmsService(SmsSenderFactory smsSenderFactory, AdminSettingsService adminSettingsService, TbApiUsageStateService apiUsageStateService, TbApiUsageClient apiUsageClient) {
|
||||
this.smsSenderFactory = smsSenderFactory;
|
||||
this.adminSettingsService = adminSettingsService;
|
||||
this.apiUsageStateService = apiUsageStateService;
|
||||
this.apiUsageClient = apiUsageClient;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
updateSmsConfiguration();
|
||||
@ -78,18 +86,26 @@ public class DefaultSmsService implements SmsService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSms(String numberTo, String message) throws ThingsboardException {
|
||||
private int sendSms(String numberTo, String message) throws ThingsboardException {
|
||||
if (this.smsSender == null) {
|
||||
throw new ThingsboardException("Unable to send SMS: no SMS provider configured!", ThingsboardErrorCode.GENERAL);
|
||||
}
|
||||
this.sendSms(this.smsSender, numberTo, message);
|
||||
return this.sendSms(this.smsSender, numberTo, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSms(String[] numbersTo, String message) throws ThingsboardException {
|
||||
public void sendSms(TenantId tenantId, String[] numbersTo, String message) throws ThingsboardException {
|
||||
if (apiUsageStateService.getApiUsageState(tenantId).isSmsSendEnabled()) {
|
||||
int smsCount = 0;
|
||||
try {
|
||||
for (String numberTo : numbersTo) {
|
||||
this.sendSms(numberTo, message);
|
||||
smsCount += this.sendSms(numberTo, message);
|
||||
}
|
||||
} finally {
|
||||
if (smsCount > 0) {
|
||||
apiUsageClient.report(tenantId, ApiUsageRecordKey.SMS_EXEC_COUNT, smsCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,9 @@ public enum ApiFeature {
|
||||
TRANSPORT("transportApiState", "Device API"),
|
||||
DB("dbApiState", "Telemetry persistence"),
|
||||
RE("ruleEngineApiState", "Rule Engine execution"),
|
||||
JS("jsExecutionApiState", "JavaScript functions execution");
|
||||
JS("jsExecutionApiState", "JavaScript functions execution"),
|
||||
EMAIL("emailApiState", "Email messages"),
|
||||
SMS("smsApiState", "SMS messages");
|
||||
|
||||
@Getter
|
||||
private final String apiStateKey;
|
||||
|
||||
@ -23,11 +23,15 @@ public enum ApiUsageRecordKey {
|
||||
TRANSPORT_DP_COUNT(ApiFeature.TRANSPORT, "transportDataPointsCount", "transportDataPointsLimit"),
|
||||
STORAGE_DP_COUNT(ApiFeature.DB, "storageDataPointsCount", "storageDataPointsLimit"),
|
||||
RE_EXEC_COUNT(ApiFeature.RE, "ruleEngineExecutionCount", "ruleEngineExecutionLimit"),
|
||||
JS_EXEC_COUNT(ApiFeature.JS, "jsExecutionCount", "jsExecutionLimit");
|
||||
JS_EXEC_COUNT(ApiFeature.JS, "jsExecutionCount", "jsExecutionLimit"),
|
||||
EMAIL_EXEC_COUNT(ApiFeature.EMAIL, "emailCount", "emailLimit"),
|
||||
SMS_EXEC_COUNT(ApiFeature.SMS, "smsCount", "smsLimit");
|
||||
private static final ApiUsageRecordKey[] JS_RECORD_KEYS = {JS_EXEC_COUNT};
|
||||
private static final ApiUsageRecordKey[] RE_RECORD_KEYS = {RE_EXEC_COUNT};
|
||||
private static final ApiUsageRecordKey[] DB_RECORD_KEYS = {STORAGE_DP_COUNT};
|
||||
private static final ApiUsageRecordKey[] TRANSPORT_RECORD_KEYS = {TRANSPORT_MSG_COUNT, TRANSPORT_DP_COUNT};
|
||||
private static final ApiUsageRecordKey[] EMAIL_RECORD_KEYS = {EMAIL_EXEC_COUNT};
|
||||
private static final ApiUsageRecordKey[] SMS_RECORD_KEYS = {SMS_EXEC_COUNT};
|
||||
|
||||
@Getter
|
||||
private final ApiFeature apiFeature;
|
||||
@ -52,6 +56,10 @@ public enum ApiUsageRecordKey {
|
||||
return RE_RECORD_KEYS;
|
||||
case JS:
|
||||
return JS_RECORD_KEYS;
|
||||
case EMAIL:
|
||||
return EMAIL_RECORD_KEYS;
|
||||
case SMS:
|
||||
return SMS_RECORD_KEYS;
|
||||
default:
|
||||
return new ApiUsageRecordKey[]{};
|
||||
}
|
||||
|
||||
@ -47,6 +47,12 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
|
||||
@Getter
|
||||
@Setter
|
||||
private ApiUsageStateValue jsExecState;
|
||||
@Getter
|
||||
@Setter
|
||||
private ApiUsageStateValue emailExecState;
|
||||
@Getter
|
||||
@Setter
|
||||
private ApiUsageStateValue smsExecState;
|
||||
|
||||
public ApiUsageState() {
|
||||
super();
|
||||
@ -64,6 +70,8 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
|
||||
this.dbStorageState = ur.getDbStorageState();
|
||||
this.reExecState = ur.getReExecState();
|
||||
this.jsExecState = ur.getJsExecState();
|
||||
this.emailExecState = ur.getEmailExecState();
|
||||
this.smsExecState = ur.getSmsExecState();
|
||||
}
|
||||
|
||||
public boolean isTransportEnabled() {
|
||||
@ -81,4 +89,12 @@ public class ApiUsageState extends BaseData<ApiUsageStateId> implements HasTenan
|
||||
public boolean isJsExecEnabled() {
|
||||
return !ApiUsageStateValue.DISABLED.equals(jsExecState);
|
||||
}
|
||||
|
||||
public boolean isEmailSendEnabled(){
|
||||
return !ApiUsageStateValue.DISABLED.equals(emailExecState);
|
||||
}
|
||||
|
||||
public boolean isSmsSendEnabled(){
|
||||
return !ApiUsageStateValue.DISABLED.equals(smsExecState);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
|
||||
private long maxJSExecutions;
|
||||
private long maxDPStorageDays;
|
||||
private int maxRuleNodeExecutionsPerMessage;
|
||||
private long maxEmails;
|
||||
private long maxSms;
|
||||
|
||||
private double warnThreshold;
|
||||
|
||||
@ -58,6 +60,10 @@ public class DefaultTenantProfileConfiguration implements TenantProfileConfigura
|
||||
return maxREExecutions;
|
||||
case STORAGE_DP_COUNT:
|
||||
return maxDPStorageDays;
|
||||
case EMAIL_EXEC_COUNT:
|
||||
return maxEmails;
|
||||
case SMS_EXEC_COUNT:
|
||||
return maxSms;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@ -450,6 +450,8 @@ public class ModelConstants {
|
||||
public static final String API_USAGE_STATE_DB_STORAGE_COLUMN = "db_storage";
|
||||
public static final String API_USAGE_STATE_RE_EXEC_COLUMN = "re_exec";
|
||||
public static final String API_USAGE_STATE_JS_EXEC_COLUMN = "js_exec";
|
||||
public static final String API_USAGE_STATE_EMAIL_EXEC_COLUMN = "email_exec";
|
||||
public static final String API_USAGE_STATE_SMS_EXEC_COLUMN = "sms_exec";
|
||||
|
||||
/**
|
||||
* Cassandra attributes and timeseries constants.
|
||||
|
||||
@ -63,6 +63,12 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = ModelConstants.API_USAGE_STATE_JS_EXEC_COLUMN)
|
||||
private ApiUsageStateValue jsExecState = ApiUsageStateValue.ENABLED;
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = ModelConstants.API_USAGE_STATE_EMAIL_EXEC_COLUMN)
|
||||
private ApiUsageStateValue emailExecState = ApiUsageStateValue.ENABLED;
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = ModelConstants.API_USAGE_STATE_SMS_EXEC_COLUMN)
|
||||
private ApiUsageStateValue smsExecState = ApiUsageStateValue.ENABLED;
|
||||
|
||||
public ApiUsageStateEntity() {
|
||||
}
|
||||
@ -83,6 +89,8 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
|
||||
this.dbStorageState = ur.getDbStorageState();
|
||||
this.reExecState = ur.getReExecState();
|
||||
this.jsExecState = ur.getJsExecState();
|
||||
this.emailExecState = ur.getEmailExecState();
|
||||
this.smsExecState = ur.getSmsExecState();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,6 +107,8 @@ public class ApiUsageStateEntity extends BaseSqlEntity<ApiUsageState> implements
|
||||
ur.setDbStorageState(dbStorageState);
|
||||
ur.setReExecState(reExecState);
|
||||
ur.setJsExecState(jsExecState);
|
||||
ur.setEmailExecState(emailExecState);
|
||||
ur.setSmsExecState(smsExecState);
|
||||
return ur;
|
||||
}
|
||||
|
||||
|
||||
@ -78,6 +78,8 @@ public class ApiUsageStateServiceImpl extends AbstractEntityService implements A
|
||||
apiUsageState.setReExecState(ApiUsageStateValue.ENABLED);
|
||||
apiUsageState.setJsExecState(ApiUsageStateValue.ENABLED);
|
||||
apiUsageState.setDbStorageState(ApiUsageStateValue.ENABLED);
|
||||
apiUsageState.setSmsExecState(ApiUsageStateValue.ENABLED);
|
||||
apiUsageState.setEmailExecState(ApiUsageStateValue.ENABLED);
|
||||
apiUsageStateValidator.validate(apiUsageState, ApiUsageState::getTenantId);
|
||||
|
||||
ApiUsageState saved = apiUsageStateDao.save(apiUsageState.getTenantId(), apiUsageState);
|
||||
|
||||
@ -416,5 +416,7 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
|
||||
db_storage varchar(32),
|
||||
re_exec varchar(32),
|
||||
js_exec varchar(32),
|
||||
email_exec varchar(32),
|
||||
sms_exec varchar(32),
|
||||
CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id)
|
||||
);
|
||||
|
||||
@ -442,6 +442,8 @@ CREATE TABLE IF NOT EXISTS api_usage_state (
|
||||
db_storage varchar(32),
|
||||
re_exec varchar(32),
|
||||
js_exec varchar(32),
|
||||
email_exec varchar(32),
|
||||
sms_exec varchar(32),
|
||||
CONSTRAINT api_usage_state_unq_key UNIQUE (tenant_id, entity_id)
|
||||
);
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.ApiFeature;
|
||||
import org.thingsboard.server.common.data.ApiUsageStateMailMessage;
|
||||
import org.thingsboard.server.common.data.ApiUsageStateValue;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
|
||||
@ -27,7 +28,7 @@ public interface MailService {
|
||||
|
||||
void updateMailConfiguration();
|
||||
|
||||
void sendEmail(String email, String subject, String message) throws ThingsboardException;
|
||||
void sendEmail(TenantId tenantId, String email, String subject, String message) throws ThingsboardException;
|
||||
|
||||
void sendTestMail(JsonNode config, String email) throws ThingsboardException;
|
||||
|
||||
@ -39,7 +40,7 @@ public interface MailService {
|
||||
|
||||
void sendPasswordWasResetEmail(String loginLink, String email) throws ThingsboardException;
|
||||
|
||||
void send(String from, String to, String cc, String bcc, String subject, String body) throws MessagingException;
|
||||
void send(TenantId tenantId, String from, String to, String cc, String bcc, String subject, String body) throws MessagingException;
|
||||
|
||||
void sendAccountLockoutEmail( String lockoutEmail, String email, Integer maxFailedLoginAttempts) throws ThingsboardException;
|
||||
|
||||
|
||||
@ -17,14 +17,13 @@ package org.thingsboard.rule.engine.api;
|
||||
|
||||
import org.thingsboard.rule.engine.api.sms.config.TestSmsRequest;
|
||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
|
||||
public interface SmsService {
|
||||
|
||||
void updateSmsConfiguration();
|
||||
|
||||
void sendSms(String numberTo, String message) throws ThingsboardException;
|
||||
|
||||
void sendSms(String[] numbersTo, String message) throws ThingsboardException;;
|
||||
void sendSms(TenantId tenantId, String[] numbersTo, String message) throws ThingsboardException;;
|
||||
|
||||
void sendTestSms(TestSmsRequest testSmsRequest) throws ThingsboardException;
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import io.netty.channel.EventLoopGroup;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.thingsboard.common.util.ListeningExecutor;
|
||||
import org.thingsboard.rule.engine.api.sms.SmsSenderFactory;
|
||||
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||
import org.thingsboard.server.common.data.Customer;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
|
||||
@ -26,6 +26,7 @@ import org.thingsboard.rule.engine.api.TbNode;
|
||||
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
|
||||
import org.thingsboard.rule.engine.api.TbNodeException;
|
||||
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
|
||||
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||
import org.thingsboard.server.common.data.plugin.ComponentType;
|
||||
import org.thingsboard.server.common.msg.TbMsg;
|
||||
|
||||
@ -87,7 +88,7 @@ public class TbSendEmailNode implements TbNode {
|
||||
|
||||
private void sendEmail(TbContext ctx, EmailPojo email) throws Exception {
|
||||
if (this.config.isUseSystemSmtpSettings()) {
|
||||
ctx.getMailService().send(email.getFrom(), email.getTo(), email.getCc(),
|
||||
ctx.getMailService().send(ctx.getTenantId(), email.getFrom(), email.getTo(), email.getCc(),
|
||||
email.getBcc(), email.getSubject(), email.getBody());
|
||||
} else {
|
||||
MimeMessage mailMsg = mailSender.createMimeMessage();
|
||||
|
||||
@ -23,6 +23,7 @@ import org.thingsboard.rule.engine.api.TbNodeConfiguration;
|
||||
import org.thingsboard.rule.engine.api.TbNodeException;
|
||||
import org.thingsboard.rule.engine.api.sms.SmsSender;
|
||||
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
|
||||
import org.thingsboard.server.common.data.ApiUsageRecordKey;
|
||||
import org.thingsboard.server.common.data.plugin.ComponentType;
|
||||
import org.thingsboard.server.common.msg.TbMsg;
|
||||
|
||||
@ -75,7 +76,7 @@ public class TbSendSmsNode implements TbNode {
|
||||
String message = TbNodeUtils.processPattern(this.config.getSmsMessageTemplate(), msg.getMetaData());
|
||||
String[] numbersToList = numbersTo.split(",");
|
||||
if (this.config.isUseSystemSmsSettings()) {
|
||||
ctx.getSmsService().sendSms(numbersToList, message);
|
||||
ctx.getSmsService().sendSms(ctx.getTenantId(), numbersToList, message);
|
||||
} else {
|
||||
for (String numberTo : numbersToList) {
|
||||
this.smsSender.sendSms(numberTo, message);
|
||||
|
||||
@ -160,6 +160,30 @@
|
||||
{{ 'tenant-profile.max-rule-node-executions-per-message-range' | translate}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label translate>tenant-profile.max-emails</mat-label>
|
||||
<input matInput required min="0" step="1"
|
||||
formControlName="maxEmails"
|
||||
type="number">
|
||||
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxEmails').hasError('required')">
|
||||
{{ 'tenant-profile.max-emails-required' | translate}}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxEmails').hasError('min')">
|
||||
{{ 'tenant-profile.max-emails-range' | translate}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label translate>tenant-profile.max-sms</mat-label>
|
||||
<input matInput required min="0" step="1"
|
||||
formControlName="maxSms"
|
||||
type="number">
|
||||
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxSms').hasError('required')">
|
||||
{{ 'tenant-profile.max-sms-required' | translate}}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="defaultTenantProfileConfigurationFormGroup.get('maxSms').hasError('min')">
|
||||
{{ 'tenant-profile.max-sms-range' | translate}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="mat-block">
|
||||
<mat-label translate>tenant-profile.transport-tenant-msg-rate-limit</mat-label>
|
||||
<input matInput formControlName="transportTenantMsgRateLimit">
|
||||
|
||||
@ -70,7 +70,9 @@ export class DefaultTenantProfileConfigurationComponent implements ControlValueA
|
||||
maxREExecutions: [null, [Validators.required, Validators.min(0)]],
|
||||
maxJSExecutions: [null, [Validators.required, Validators.min(0)]],
|
||||
maxDPStorageDays: [null, [Validators.required, Validators.min(0)]],
|
||||
maxRuleNodeExecutionsPerMessage: [null, [Validators.required, Validators.min(0)]]
|
||||
maxRuleNodeExecutionsPerMessage: [null, [Validators.required, Validators.min(0)]],
|
||||
maxEmails: [null, [Validators.required, Validators.min(0)]],
|
||||
maxSms: [null, [Validators.required, Validators.min(0)]]
|
||||
});
|
||||
this.defaultTenantProfileConfigurationFormGroup.valueChanges.subscribe(() => {
|
||||
this.updateModel();
|
||||
|
||||
@ -44,6 +44,8 @@ export interface DefaultTenantProfileConfiguration {
|
||||
maxJSExecutions: number;
|
||||
maxDPStorageDays: number;
|
||||
maxRuleNodeExecutionsPerMessage: number;
|
||||
maxEmails: number;
|
||||
maxSms: number;
|
||||
}
|
||||
|
||||
export type TenantProfileConfigurations = DefaultTenantProfileConfiguration;
|
||||
@ -69,7 +71,9 @@ export function createTenantProfileConfiguration(type: TenantProfileType): Tenan
|
||||
maxREExecutions: 0,
|
||||
maxJSExecutions: 0,
|
||||
maxDPStorageDays: 0,
|
||||
maxRuleNodeExecutionsPerMessage: 0
|
||||
maxRuleNodeExecutionsPerMessage: 0,
|
||||
maxEmails: 0,
|
||||
maxSms: 0
|
||||
};
|
||||
configuration = {...defaultConfiguration, type: TenantProfileType.DEFAULT};
|
||||
break;
|
||||
|
||||
@ -2017,7 +2017,13 @@
|
||||
"max-d-p-storage-days-range": "Minimum number of data points storage days can't be negative",
|
||||
"max-rule-node-executions-per-message": "Maximum number of rule node executions per message (0 - unlimited)",
|
||||
"max-rule-node-executions-per-message-required": "Maximum number of rule node executions per message is required.",
|
||||
"max-rule-node-executions-per-message-range": "Minimum number of rule node executions per message can't be negative"
|
||||
"max-rule-node-executions-per-message-range": "Minimum number of rule node executions per message can't be negative",
|
||||
"max-emails": "Maximum number of emails sent (0 - unlimited)",
|
||||
"max-emails-required": "Maximum number of emails sent is required.",
|
||||
"max-emails-range": "Maximum number of emails sent can't be negative",
|
||||
"max-sms": "Maximum number of SMS sent (0 - unlimited)",
|
||||
"max-sms-required": "Maximum number of SMS sent is required.",
|
||||
"max-sms-range": "Maximum number of SMS sent can't be negative"
|
||||
},
|
||||
"timeinterval": {
|
||||
"seconds-interval": "{ seconds, plural, 1 {1 second} other {# seconds} }",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user