Notification system fixes, new notification targets
This commit is contained in:
parent
b10e162b19
commit
197207035b
@ -32,6 +32,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
|
|||||||
import org.thingsboard.server.common.data.id.NotificationRuleId;
|
import org.thingsboard.server.common.data.id.NotificationRuleId;
|
||||||
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
|
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
|
||||||
import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo;
|
import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo;
|
||||||
|
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
|
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
|
||||||
@ -56,9 +57,16 @@ public class NotificationRuleController extends BaseController {
|
|||||||
|
|
||||||
@PostMapping("/rule")
|
@PostMapping("/rule")
|
||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
||||||
public NotificationRule saveNotificationRule(@RequestBody @Valid NotificationRule notificationRule) throws Exception {
|
public NotificationRule saveNotificationRule(@RequestBody @Valid NotificationRule notificationRule,
|
||||||
notificationRule.setTenantId(getTenantId());
|
@AuthenticationPrincipal SecurityUser user) throws Exception {
|
||||||
|
notificationRule.setTenantId(user.getTenantId());
|
||||||
checkEntity(notificationRule.getId(), notificationRule, NOTIFICATION);
|
checkEntity(notificationRule.getId(), notificationRule, NOTIFICATION);
|
||||||
|
|
||||||
|
NotificationRuleTriggerType triggerType = notificationRule.getTriggerType();
|
||||||
|
if ((user.isTenantAdmin() && !triggerType.isTenantLevel()) || (user.isSystemAdmin() && triggerType.isTenantLevel())) {
|
||||||
|
throw new IllegalArgumentException("Trigger type " + triggerType + " is not available");
|
||||||
|
}
|
||||||
|
|
||||||
return doSaveAndLog(EntityType.NOTIFICATION_RULE, notificationRule, notificationRuleService::saveNotificationRule);
|
return doSaveAndLog(EntityType.NOTIFICATION_RULE, notificationRule, notificationRuleService::saveNotificationRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,17 +74,17 @@ public class NotificationRuleController extends BaseController {
|
|||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
||||||
public NotificationRuleInfo getNotificationRuleById(@PathVariable UUID id) throws ThingsboardException {
|
public NotificationRuleInfo getNotificationRuleById(@PathVariable UUID id) throws ThingsboardException {
|
||||||
NotificationRuleId notificationRuleId = new NotificationRuleId(id);
|
NotificationRuleId notificationRuleId = new NotificationRuleId(id);
|
||||||
return checkEntityId(notificationRuleId, notificationRuleService::findNotificationRuleInfoById, Operation.READ);
|
return checkEntityId(notificationRuleId, notificationRuleService::findNotificationRuleInfoById, Operation.READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/rules")
|
@GetMapping("/rules")
|
||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
||||||
public PageData<NotificationRuleInfo> getNotificationRules(@RequestParam int pageSize,
|
public PageData<NotificationRuleInfo> getNotificationRules(@RequestParam int pageSize,
|
||||||
@RequestParam int page,
|
@RequestParam int page,
|
||||||
@RequestParam(required = false) String textSearch,
|
@RequestParam(required = false) String textSearch,
|
||||||
@RequestParam(required = false) String sortProperty,
|
@RequestParam(required = false) String sortProperty,
|
||||||
@RequestParam(required = false) String sortOrder,
|
@RequestParam(required = false) String sortOrder,
|
||||||
@AuthenticationPrincipal SecurityUser user) throws ThingsboardException {
|
@AuthenticationPrincipal SecurityUser user) throws ThingsboardException {
|
||||||
// generic permission
|
// generic permission
|
||||||
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
|
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
|
||||||
return notificationRuleService.findNotificationRulesInfosByTenantId(user.getTenantId(), pageLink);
|
return notificationRuleService.findNotificationRulesInfosByTenantId(user.getTenantId(), pageLink);
|
||||||
|
|||||||
@ -191,6 +191,8 @@ public class NotificationTargetController extends BaseController {
|
|||||||
throw new AccessDeniedException("");
|
throw new AccessDeniedException("");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SYSTEM_ADMINISTRATORS:
|
||||||
|
throw new AccessDeniedException("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,9 @@ public class DefaultRateLimitService implements RateLimitService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkRateLimit(TenantId tenantId, LimitedApi api) {
|
public boolean checkRateLimit(TenantId tenantId, LimitedApi api) {
|
||||||
|
if (tenantId.isSysTenantId()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
String rateLimitConfig = tenantProfileCache.get(tenantId).getProfileConfiguration()
|
String rateLimitConfig = tenantProfileCache.get(tenantId).getProfileConfiguration()
|
||||||
.map(api::getLimitConfig).orElse(null);
|
.map(api::getLimitConfig).orElse(null);
|
||||||
|
|
||||||
|
|||||||
@ -123,8 +123,8 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
|
|||||||
}
|
}
|
||||||
if (notificationTemplate == null) throw new IllegalArgumentException("Template is missing");
|
if (notificationTemplate == null) throw new IllegalArgumentException("Template is missing");
|
||||||
|
|
||||||
List<NotificationTarget> targets = notificationTargetService.findNotificationTargetsByTenantIdAndIds(tenantId,
|
List<NotificationTarget> targets = notificationRequest.getTargets().stream().map(NotificationTargetId::new)
|
||||||
notificationRequest.getTargets().stream().map(NotificationTargetId::new).collect(Collectors.toList()));
|
.map(id -> notificationTargetService.findNotificationTargetById(tenantId, id)).collect(Collectors.toList());
|
||||||
Set<NotificationDeliveryMethod> availableDeliveryMethods = getAvailableDeliveryMethods(tenantId);
|
Set<NotificationDeliveryMethod> availableDeliveryMethods = getAvailableDeliveryMethods(tenantId);
|
||||||
|
|
||||||
notificationTemplate.getConfiguration().getDeliveryMethodsTemplates().forEach((deliveryMethod, template) -> {
|
notificationTemplate.getConfiguration().getDeliveryMethodsTemplates().forEach((deliveryMethod, template) -> {
|
||||||
|
|||||||
@ -73,11 +73,12 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(TenantId tenantId, NotificationRuleTrigger trigger) {
|
public void process(TenantId tenantId, NotificationRuleTrigger trigger) {
|
||||||
List<NotificationRule> rules = notificationRuleService.findNotificationRulesByTenantIdAndTriggerType(tenantId, trigger.getType());
|
List<NotificationRule> rules = notificationRuleService.findNotificationRulesByTenantIdAndTriggerType(
|
||||||
|
trigger.getType().isTenantLevel() ? tenantId : TenantId.SYS_TENANT_ID, trigger.getType());
|
||||||
for (NotificationRule rule : rules) {
|
for (NotificationRule rule : rules) {
|
||||||
notificationExecutor.submit(() -> {
|
notificationExecutor.submit(() -> {
|
||||||
try {
|
try {
|
||||||
processNotificationRule(rule, trigger);
|
processNotificationRule(tenantId, rule, trigger);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error("Failed to process notification rule {} for trigger type {} with trigger object {}", rule.getId(), rule.getTriggerType(), trigger, e);
|
log.error("Failed to process notification rule {} for trigger type {} with trigger object {}", rule.getId(), rule.getTriggerType(), trigger, e);
|
||||||
}
|
}
|
||||||
@ -97,12 +98,12 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
|
|||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processNotificationRule(NotificationRule rule, NotificationRuleTrigger trigger) {
|
private void processNotificationRule(TenantId tenantId, NotificationRule rule, NotificationRuleTrigger trigger) {
|
||||||
NotificationRuleTriggerConfig triggerConfig = rule.getTriggerConfig();
|
NotificationRuleTriggerConfig triggerConfig = rule.getTriggerConfig();
|
||||||
log.debug("Processing notification rule '{}' for trigger type {}", rule.getName(), rule.getTriggerType());
|
log.debug("Processing notification rule '{}' for trigger type {}", rule.getName(), rule.getTriggerType());
|
||||||
|
|
||||||
if (matchesClearRule(trigger, triggerConfig)) {
|
if (matchesClearRule(trigger, triggerConfig)) {
|
||||||
List<NotificationRequest> notificationRequests = notificationRequestService.findNotificationRequestsByRuleIdAndOriginatorEntityId(rule.getTenantId(), rule.getId(), trigger.getOriginatorEntityId());
|
List<NotificationRequest> notificationRequests = notificationRequestService.findNotificationRequestsByRuleIdAndOriginatorEntityId(tenantId, rule.getId(), trigger.getOriginatorEntityId());
|
||||||
if (notificationRequests.isEmpty()) {
|
if (notificationRequests.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -112,11 +113,11 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
|
|||||||
.flatMap(notificationRequest -> notificationRequest.getTargets().stream())
|
.flatMap(notificationRequest -> notificationRequest.getTargets().stream())
|
||||||
.distinct().collect(Collectors.toList());
|
.distinct().collect(Collectors.toList());
|
||||||
NotificationInfo notificationInfo = constructNotificationInfo(trigger, triggerConfig);
|
NotificationInfo notificationInfo = constructNotificationInfo(trigger, triggerConfig);
|
||||||
submitNotificationRequest(targets, rule, trigger.getOriginatorEntityId(), notificationInfo, 0);
|
submitNotificationRequest(tenantId, targets, rule, trigger.getOriginatorEntityId(), notificationInfo, 0);
|
||||||
|
|
||||||
notificationRequests.forEach(notificationRequest -> {
|
notificationRequests.forEach(notificationRequest -> {
|
||||||
if (notificationRequest.isScheduled()) {
|
if (notificationRequest.isScheduled()) {
|
||||||
notificationCenter.deleteNotificationRequest(rule.getTenantId(), notificationRequest.getId());
|
notificationCenter.deleteNotificationRequest(tenantId, notificationRequest.getId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -125,7 +126,7 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
|
|||||||
if (matchesFilter(trigger, triggerConfig)) {
|
if (matchesFilter(trigger, triggerConfig)) {
|
||||||
NotificationInfo notificationInfo = constructNotificationInfo(trigger, triggerConfig);
|
NotificationInfo notificationInfo = constructNotificationInfo(trigger, triggerConfig);
|
||||||
rule.getRecipientsConfig().getTargetsTable().forEach((delay, targets) -> {
|
rule.getRecipientsConfig().getTargetsTable().forEach((delay, targets) -> {
|
||||||
submitNotificationRequest(targets, rule, trigger.getOriginatorEntityId(), notificationInfo, delay);
|
submitNotificationRequest(tenantId, targets, rule, trigger.getOriginatorEntityId(), notificationInfo, delay);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,14 +143,14 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
|
|||||||
return triggerProcessors.get(triggerConfig.getTriggerType()).constructNotificationInfo(trigger, triggerConfig);
|
return triggerProcessors.get(triggerConfig.getTriggerType()).constructNotificationInfo(trigger, triggerConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void submitNotificationRequest(List<UUID> targets, NotificationRule rule,
|
private void submitNotificationRequest(TenantId tenantId, List<UUID> targets, NotificationRule rule,
|
||||||
EntityId originatorEntityId, NotificationInfo notificationInfo, int delayInSec) {
|
EntityId originatorEntityId, NotificationInfo notificationInfo, int delayInSec) {
|
||||||
NotificationRequestConfig config = new NotificationRequestConfig();
|
NotificationRequestConfig config = new NotificationRequestConfig();
|
||||||
if (delayInSec > 0) {
|
if (delayInSec > 0) {
|
||||||
config.setSendingDelayInSec(delayInSec);
|
config.setSendingDelayInSec(delayInSec);
|
||||||
}
|
}
|
||||||
NotificationRequest notificationRequest = NotificationRequest.builder()
|
NotificationRequest notificationRequest = NotificationRequest.builder()
|
||||||
.tenantId(rule.getTenantId())
|
.tenantId(tenantId)
|
||||||
.targets(targets)
|
.targets(targets)
|
||||||
.templateId(rule.getTemplateId())
|
.templateId(rule.getTemplateId())
|
||||||
.additionalConfig(config)
|
.additionalConfig(config)
|
||||||
@ -160,7 +161,7 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
|
|||||||
notificationExecutor.submit(() -> {
|
notificationExecutor.submit(() -> {
|
||||||
try {
|
try {
|
||||||
log.debug("Submitting notification request for rule '{}' with delay of {} sec to targets {}", rule.getName(), delayInSec, targets);
|
log.debug("Submitting notification request for rule '{}' with delay of {} sec to targets {}", rule.getName(), delayInSec, targets);
|
||||||
notificationCenter.processNotificationRequest(rule.getTenantId(), notificationRequest);
|
notificationCenter.processNotificationRequest(tenantId, notificationRequest);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to process notification request for rule {}", rule.getId(), e);
|
log.error("Failed to process notification request for rule {}", rule.getId(), e);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,18 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.service.notification.rule.trigger;
|
package org.thingsboard.server.service.notification.rule.trigger;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.server.common.data.notification.info.EntitiesLimitNotificationInfo;
|
import org.thingsboard.server.common.data.notification.info.EntitiesLimitNotificationInfo;
|
||||||
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
|
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
|
||||||
import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitNotificationRuleTriggerConfig;
|
import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitNotificationRuleTriggerConfig;
|
||||||
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
|
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
|
||||||
import org.thingsboard.server.dao.notification.trigger.EntitiesLimitTrigger;
|
import org.thingsboard.server.dao.notification.trigger.EntitiesLimitTrigger;
|
||||||
|
import org.thingsboard.server.dao.tenant.TenantService;
|
||||||
|
|
||||||
import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
|
import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class EntitiesLimitTriggerProcessor implements NotificationRuleTriggerProcessor<EntitiesLimitTrigger, EntitiesLimitNotificationRuleTriggerConfig> {
|
public class EntitiesLimitTriggerProcessor implements NotificationRuleTriggerProcessor<EntitiesLimitTrigger, EntitiesLimitNotificationRuleTriggerConfig> {
|
||||||
|
|
||||||
|
private final TenantService tenantService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matchesFilter(EntitiesLimitTrigger trigger, EntitiesLimitNotificationRuleTriggerConfig triggerConfig) {
|
public boolean matchesFilter(EntitiesLimitTrigger trigger, EntitiesLimitNotificationRuleTriggerConfig triggerConfig) {
|
||||||
if (isNotEmpty(triggerConfig.getEntityTypes()) && !triggerConfig.getEntityTypes().contains(trigger.getEntityType())) {
|
if (isNotEmpty(triggerConfig.getEntityTypes()) && !triggerConfig.getEntityTypes().contains(trigger.getEntityType())) {
|
||||||
@ -42,6 +47,8 @@ public class EntitiesLimitTriggerProcessor implements NotificationRuleTriggerPro
|
|||||||
.currentCount(trigger.getCurrentCount())
|
.currentCount(trigger.getCurrentCount())
|
||||||
.limit(trigger.getLimit())
|
.limit(trigger.getLimit())
|
||||||
.percents((int) (((float)trigger.getCurrentCount() / trigger.getLimit()) * 100))
|
.percents((int) (((float)trigger.getCurrentCount() / trigger.getLimit()) * 100))
|
||||||
|
.tenantId(trigger.getTenantId())
|
||||||
|
.tenantName(tenantService.findTenantById(trigger.getTenantId()).getName())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -62,7 +62,7 @@ public class EntityActionTriggerProcessor implements RuleEngineMsgNotificationRu
|
|||||||
msgType.equals(DataConstants.ENTITY_UPDATED) ? ActionType.UPDATED :
|
msgType.equals(DataConstants.ENTITY_UPDATED) ? ActionType.UPDATED :
|
||||||
msgType.equals(DataConstants.ENTITY_DELETED) ? ActionType.DELETED : null;
|
msgType.equals(DataConstants.ENTITY_DELETED) ? ActionType.DELETED : null;
|
||||||
return EntityActionNotificationInfo.builder()
|
return EntityActionNotificationInfo.builder()
|
||||||
.entityId(actionType != ActionType.DELETED ? msg.getOriginator() : null)
|
.entityId(msg.getOriginator())
|
||||||
.entityName(msg.getMetaData().getValue("entityName"))
|
.entityName(msg.getMetaData().getValue("entityName"))
|
||||||
.actionType(actionType)
|
.actionType(actionType)
|
||||||
.originatorUserId(UUID.fromString(msg.getMetaData().getValue("userId")))
|
.originatorUserId(UUID.fromString(msg.getMetaData().getValue("userId")))
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.notification.rule.trigger.Notification
|
|||||||
@Builder
|
@Builder
|
||||||
public class EntitiesLimitTrigger implements NotificationRuleTrigger {
|
public class EntitiesLimitTrigger implements NotificationRuleTrigger {
|
||||||
|
|
||||||
|
private final TenantId tenantId;
|
||||||
private final EntityType entityType;
|
private final EntityType entityType;
|
||||||
private final long currentCount;
|
private final long currentCount;
|
||||||
private final long limit;
|
private final long limit;
|
||||||
|
|||||||
@ -63,6 +63,8 @@ public interface UserService extends EntityDaoService {
|
|||||||
|
|
||||||
PageData<User> findTenantAdmins(TenantId tenantId, PageLink pageLink);
|
PageData<User> findTenantAdmins(TenantId tenantId, PageLink pageLink);
|
||||||
|
|
||||||
|
PageData<User> findSysAdmins(PageLink pageLink);
|
||||||
|
|
||||||
PageData<User> findAllTenantAdmins(PageLink pageLink);
|
PageData<User> findAllTenantAdmins(PageLink pageLink);
|
||||||
|
|
||||||
PageData<User> findTenantAdminsByTenantsIds(List<TenantId> tenantsIds, PageLink pageLink);
|
PageData<User> findTenantAdminsByTenantsIds(List<TenantId> tenantsIds, PageLink pageLink);
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import lombok.Builder;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import org.thingsboard.server.common.data.EntityType;
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -35,6 +36,8 @@ public class EntitiesLimitNotificationInfo implements NotificationInfo {
|
|||||||
private long currentCount;
|
private long currentCount;
|
||||||
private long limit;
|
private long limit;
|
||||||
private int percents;
|
private int percents;
|
||||||
|
private TenantId tenantId;
|
||||||
|
private String tenantName;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getTemplateData() {
|
public Map<String, String> getTemplateData() {
|
||||||
@ -42,7 +45,9 @@ public class EntitiesLimitNotificationInfo implements NotificationInfo {
|
|||||||
"entityType", entityType.getNormalName(),
|
"entityType", entityType.getNormalName(),
|
||||||
"currentCount", String.valueOf(currentCount),
|
"currentCount", String.valueOf(currentCount),
|
||||||
"limit", String.valueOf(limit),
|
"limit", String.valueOf(limit),
|
||||||
"percents", String.valueOf(percents)
|
"percents", String.valueOf(percents),
|
||||||
|
"tenantId", tenantId.toString(),
|
||||||
|
"tenantName", tenantName
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.common.data.notification.rule.trigger;
|
package org.thingsboard.server.common.data.notification.rule.trigger;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
public enum NotificationRuleTriggerType {
|
public enum NotificationRuleTriggerType {
|
||||||
|
|
||||||
ALARM,
|
ALARM,
|
||||||
@ -23,7 +26,17 @@ public enum NotificationRuleTriggerType {
|
|||||||
ENTITY_ACTION,
|
ENTITY_ACTION,
|
||||||
RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT,
|
RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT,
|
||||||
ALARM_ASSIGNMENT,
|
ALARM_ASSIGNMENT,
|
||||||
NEW_PLATFORM_VERSION,
|
NEW_PLATFORM_VERSION(false),
|
||||||
ENTITIES_LIMIT
|
ENTITIES_LIMIT(false);
|
||||||
|
|
||||||
|
private final boolean tenantLevel;
|
||||||
|
|
||||||
|
NotificationRuleTriggerType(boolean tenantLevel) {
|
||||||
|
this.tenantLevel = tenantLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationRuleTriggerType() {
|
||||||
|
this(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2023 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.notification.targets.platform;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AffectedTenantAdministratorsFilter implements UsersFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsersFilterType getType() {
|
||||||
|
return UsersFilterType.AFFECTED_TENANT_ADMINISTRATORS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2023 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.common.data.notification.targets.platform;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SystemAdministratorsFilter implements UsersFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UsersFilterType getType() {
|
||||||
|
return UsersFilterType.SYSTEM_ADMINISTRATORS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -27,6 +27,8 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|||||||
@Type(value = UserListFilter.class, name = "USER_LIST"),
|
@Type(value = UserListFilter.class, name = "USER_LIST"),
|
||||||
@Type(value = CustomerUsersFilter.class, name = "CUSTOMER_USERS"),
|
@Type(value = CustomerUsersFilter.class, name = "CUSTOMER_USERS"),
|
||||||
@Type(value = TenantAdministratorsFilter.class, name = "TENANT_ADMINISTRATORS"),
|
@Type(value = TenantAdministratorsFilter.class, name = "TENANT_ADMINISTRATORS"),
|
||||||
|
@Type(value = AffectedTenantAdministratorsFilter.class, name = "AFFECTED_TENANT_ADMINISTRATORS"),
|
||||||
|
@Type(value = SystemAdministratorsFilter.class, name = "SYSTEM_ADMINISTRATORS"),
|
||||||
@Type(value = AllUsersFilter.class, name = "ALL_USERS"),
|
@Type(value = AllUsersFilter.class, name = "ALL_USERS"),
|
||||||
@Type(value = OriginatorEntityOwnerUsersFilter.class, name = "ORIGINATOR_ENTITY_OWNER_USERS"),
|
@Type(value = OriginatorEntityOwnerUsersFilter.class, name = "ORIGINATOR_ENTITY_OWNER_USERS"),
|
||||||
@Type(value = AffectedUserFilter.class, name = "AFFECTED_USER")
|
@Type(value = AffectedUserFilter.class, name = "AFFECTED_USER")
|
||||||
|
|||||||
@ -27,6 +27,8 @@ public enum UsersFilterType {
|
|||||||
USER_LIST,
|
USER_LIST,
|
||||||
CUSTOMER_USERS,
|
CUSTOMER_USERS,
|
||||||
TENANT_ADMINISTRATORS,
|
TENANT_ADMINISTRATORS,
|
||||||
|
AFFECTED_TENANT_ADMINISTRATORS(true),
|
||||||
|
SYSTEM_ADMINISTRATORS,
|
||||||
ALL_USERS,
|
ALL_USERS,
|
||||||
ORIGINATOR_ENTITY_OWNER_USERS(true),
|
ORIGINATOR_ENTITY_OWNER_USERS(true),
|
||||||
AFFECTED_USER(true);
|
AFFECTED_USER(true);
|
||||||
|
|||||||
@ -48,10 +48,12 @@ import org.thingsboard.server.common.data.notification.rule.trigger.Notification
|
|||||||
import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig;
|
import org.thingsboard.server.common.data.notification.rule.trigger.RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig;
|
||||||
import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
|
import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
|
||||||
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
|
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
|
||||||
|
import org.thingsboard.server.common.data.notification.targets.platform.AffectedTenantAdministratorsFilter;
|
||||||
import org.thingsboard.server.common.data.notification.targets.platform.AffectedUserFilter;
|
import org.thingsboard.server.common.data.notification.targets.platform.AffectedUserFilter;
|
||||||
import org.thingsboard.server.common.data.notification.targets.platform.AllUsersFilter;
|
import org.thingsboard.server.common.data.notification.targets.platform.AllUsersFilter;
|
||||||
import org.thingsboard.server.common.data.notification.targets.platform.OriginatorEntityOwnerUsersFilter;
|
import org.thingsboard.server.common.data.notification.targets.platform.OriginatorEntityOwnerUsersFilter;
|
||||||
import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig;
|
import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig;
|
||||||
|
import org.thingsboard.server.common.data.notification.targets.platform.SystemAdministratorsFilter;
|
||||||
import org.thingsboard.server.common.data.notification.targets.platform.TenantAdministratorsFilter;
|
import org.thingsboard.server.common.data.notification.targets.platform.TenantAdministratorsFilter;
|
||||||
import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter;
|
import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter;
|
||||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
|
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
|
||||||
@ -119,14 +121,17 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
|
|||||||
"Maintenance work is scheduled for tomorrow (7:00 a.m. - 9:00 a.m. UTC)");
|
"Maintenance work is scheduled for tomorrow (7:00 a.m. - 9:00 a.m. UTC)");
|
||||||
|
|
||||||
if (tenantId.isSysTenantId()) {
|
if (tenantId.isSysTenantId()) {
|
||||||
|
NotificationTarget sysAdmins = createTarget(tenantId, "System administrators", new SystemAdministratorsFilter(), "All system administrators");
|
||||||
|
NotificationTarget affectedTenantAdmins = createTarget(tenantId, "Affected tenant's administrators", new AffectedTenantAdministratorsFilter(), "");
|
||||||
|
|
||||||
NotificationTemplate entitiesLimitNotificationTemplate = createTemplate(tenantId, "Entities limit notification", NotificationType.ENTITIES_LIMIT,
|
NotificationTemplate entitiesLimitNotificationTemplate = createTemplate(tenantId, "Entities limit notification", NotificationType.ENTITIES_LIMIT,
|
||||||
"${entityType}s limit will be reached soon",
|
"${entityType}s limit will be reached soon for tenant ${tenantName}",
|
||||||
"${entityType}s usage: ${currentCount}/${limit} (${percents}%)");
|
"${entityType}s usage: ${currentCount}/${limit} (${percents}%)");
|
||||||
EntitiesLimitNotificationRuleTriggerConfig entitiesLimitRuleTriggerConfig = new EntitiesLimitNotificationRuleTriggerConfig();
|
EntitiesLimitNotificationRuleTriggerConfig entitiesLimitRuleTriggerConfig = new EntitiesLimitNotificationRuleTriggerConfig();
|
||||||
entitiesLimitRuleTriggerConfig.setEntityTypes(null);
|
entitiesLimitRuleTriggerConfig.setEntityTypes(null);
|
||||||
entitiesLimitRuleTriggerConfig.setThreshold(0.8f);
|
entitiesLimitRuleTriggerConfig.setThreshold(0.8f);
|
||||||
createRule(tenantId, "Entities limit", entitiesLimitNotificationTemplate.getId(), entitiesLimitRuleTriggerConfig,
|
createRule(tenantId, "Entities limit", entitiesLimitNotificationTemplate.getId(), entitiesLimitRuleTriggerConfig,
|
||||||
List.of(tenantAdmins.getId()), "Send notification to tenant admins when count of entities of some type reached 80% threshold of the limit");
|
List.of(affectedTenantAdmins.getId(), sysAdmins.getId()), "Send notification to tenant admins when count of entities of some type reached 80% threshold of the limit");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -142,6 +142,10 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case AFFECTED_TENANT_ADMINISTRATORS:
|
||||||
|
return userService.findTenantAdmins(tenantId, pageLink);
|
||||||
|
case SYSTEM_ADMINISTRATORS:
|
||||||
|
return userService.findSysAdmins(pageLink);
|
||||||
case ALL_USERS: {
|
case ALL_USERS: {
|
||||||
if (!tenantId.equals(TenantId.SYS_TENANT_ID)) {
|
if (!tenantId.equals(TenantId.SYS_TENANT_ID)) {
|
||||||
return userService.findUsersByTenantId(tenantId, pageLink);
|
return userService.findUsersByTenantId(tenantId, pageLink);
|
||||||
|
|||||||
@ -49,6 +49,7 @@ public class DefaultApiLimitService implements ApiLimitService {
|
|||||||
long currentCount = entityService.countEntitiesByQuery(tenantId, new CustomerId(EntityId.NULL_UUID), new EntityCountQuery(filter));
|
long currentCount = entityService.countEntitiesByQuery(tenantId, new CustomerId(EntityId.NULL_UUID), new EntityCountQuery(filter));
|
||||||
if (notificationRuleProcessingService != null) {
|
if (notificationRuleProcessingService != null) {
|
||||||
notificationRuleProcessingService.process(tenantId, EntitiesLimitTrigger.builder()
|
notificationRuleProcessingService.process(tenantId, EntitiesLimitTrigger.builder()
|
||||||
|
.tenantId(tenantId)
|
||||||
.entityType(entityType)
|
.entityType(entityType)
|
||||||
.currentCount(currentCount)
|
.currentCount(currentCount)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
|||||||
@ -252,6 +252,11 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
|
|||||||
return userDao.findTenantAdmins(tenantId.getId(), pageLink);
|
return userDao.findTenantAdmins(tenantId.getId(), pageLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageData<User> findSysAdmins(PageLink pageLink) {
|
||||||
|
return userDao.findAllByAuthority(Authority.SYS_ADMIN, pageLink);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageData<User> findAllTenantAdmins(PageLink pageLink) {
|
public PageData<User> findAllTenantAdmins(PageLink pageLink) {
|
||||||
return userDao.findAllByAuthority(Authority.TENANT_ADMIN, pageLink);
|
return userDao.findAllByAuthority(Authority.TENANT_ADMIN, pageLink);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user