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.notification.rule.NotificationRule;
 | 
			
		||||
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.PageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
 | 
			
		||||
@ -56,9 +57,16 @@ public class NotificationRuleController extends BaseController {
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/rule")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
 | 
			
		||||
    public NotificationRule saveNotificationRule(@RequestBody @Valid NotificationRule notificationRule) throws Exception {
 | 
			
		||||
        notificationRule.setTenantId(getTenantId());
 | 
			
		||||
    public NotificationRule saveNotificationRule(@RequestBody @Valid NotificationRule notificationRule,
 | 
			
		||||
                                                 @AuthenticationPrincipal SecurityUser user) throws Exception {
 | 
			
		||||
        notificationRule.setTenantId(user.getTenantId());
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -66,17 +74,17 @@ public class NotificationRuleController extends BaseController {
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
 | 
			
		||||
    public NotificationRuleInfo getNotificationRuleById(@PathVariable UUID id) throws ThingsboardException {
 | 
			
		||||
        NotificationRuleId notificationRuleId = new NotificationRuleId(id);
 | 
			
		||||
        return checkEntityId(notificationRuleId, notificationRuleService::findNotificationRuleInfoById,  Operation.READ);
 | 
			
		||||
        return checkEntityId(notificationRuleId, notificationRuleService::findNotificationRuleInfoById, Operation.READ);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/rules")
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
 | 
			
		||||
    public PageData<NotificationRuleInfo> getNotificationRules(@RequestParam int pageSize,
 | 
			
		||||
                                                           @RequestParam int page,
 | 
			
		||||
                                                           @RequestParam(required = false) String textSearch,
 | 
			
		||||
                                                           @RequestParam(required = false) String sortProperty,
 | 
			
		||||
                                                           @RequestParam(required = false) String sortOrder,
 | 
			
		||||
                                                           @AuthenticationPrincipal SecurityUser user) throws ThingsboardException {
 | 
			
		||||
                                                               @RequestParam int page,
 | 
			
		||||
                                                               @RequestParam(required = false) String textSearch,
 | 
			
		||||
                                                               @RequestParam(required = false) String sortProperty,
 | 
			
		||||
                                                               @RequestParam(required = false) String sortOrder,
 | 
			
		||||
                                                               @AuthenticationPrincipal SecurityUser user) throws ThingsboardException {
 | 
			
		||||
        // generic permission
 | 
			
		||||
        PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
 | 
			
		||||
        return notificationRuleService.findNotificationRulesInfosByTenantId(user.getTenantId(), pageLink);
 | 
			
		||||
 | 
			
		||||
@ -191,6 +191,8 @@ public class NotificationTargetController extends BaseController {
 | 
			
		||||
                    throw new AccessDeniedException("");
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case SYSTEM_ADMINISTRATORS:
 | 
			
		||||
                throw new AccessDeniedException("");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,9 @@ public class DefaultRateLimitService implements RateLimitService {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean checkRateLimit(TenantId tenantId, LimitedApi api) {
 | 
			
		||||
        if (tenantId.isSysTenantId()) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        String rateLimitConfig = tenantProfileCache.get(tenantId).getProfileConfiguration()
 | 
			
		||||
                .map(api::getLimitConfig).orElse(null);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -123,8 +123,8 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
 | 
			
		||||
        }
 | 
			
		||||
        if (notificationTemplate == null) throw new IllegalArgumentException("Template is missing");
 | 
			
		||||
 | 
			
		||||
        List<NotificationTarget> targets = notificationTargetService.findNotificationTargetsByTenantIdAndIds(tenantId,
 | 
			
		||||
                notificationRequest.getTargets().stream().map(NotificationTargetId::new).collect(Collectors.toList()));
 | 
			
		||||
        List<NotificationTarget> targets = notificationRequest.getTargets().stream().map(NotificationTargetId::new)
 | 
			
		||||
                .map(id -> notificationTargetService.findNotificationTargetById(tenantId, id)).collect(Collectors.toList());
 | 
			
		||||
        Set<NotificationDeliveryMethod> availableDeliveryMethods = getAvailableDeliveryMethods(tenantId);
 | 
			
		||||
 | 
			
		||||
        notificationTemplate.getConfiguration().getDeliveryMethodsTemplates().forEach((deliveryMethod, template) -> {
 | 
			
		||||
 | 
			
		||||
@ -73,11 +73,12 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    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) {
 | 
			
		||||
            notificationExecutor.submit(() -> {
 | 
			
		||||
                try {
 | 
			
		||||
                    processNotificationRule(rule, trigger);
 | 
			
		||||
                    processNotificationRule(tenantId, rule, trigger);
 | 
			
		||||
                } catch (Throwable 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());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processNotificationRule(NotificationRule rule, NotificationRuleTrigger trigger) {
 | 
			
		||||
    private void processNotificationRule(TenantId tenantId, NotificationRule rule, NotificationRuleTrigger trigger) {
 | 
			
		||||
        NotificationRuleTriggerConfig triggerConfig = rule.getTriggerConfig();
 | 
			
		||||
        log.debug("Processing notification rule '{}' for trigger type {}", rule.getName(), rule.getTriggerType());
 | 
			
		||||
 | 
			
		||||
        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()) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@ -112,11 +113,11 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
 | 
			
		||||
                    .flatMap(notificationRequest -> notificationRequest.getTargets().stream())
 | 
			
		||||
                    .distinct().collect(Collectors.toList());
 | 
			
		||||
            NotificationInfo notificationInfo = constructNotificationInfo(trigger, triggerConfig);
 | 
			
		||||
            submitNotificationRequest(targets, rule, trigger.getOriginatorEntityId(), notificationInfo, 0);
 | 
			
		||||
            submitNotificationRequest(tenantId, targets, rule, trigger.getOriginatorEntityId(), notificationInfo, 0);
 | 
			
		||||
 | 
			
		||||
            notificationRequests.forEach(notificationRequest -> {
 | 
			
		||||
                if (notificationRequest.isScheduled()) {
 | 
			
		||||
                    notificationCenter.deleteNotificationRequest(rule.getTenantId(), notificationRequest.getId());
 | 
			
		||||
                    notificationCenter.deleteNotificationRequest(tenantId, notificationRequest.getId());
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            return;
 | 
			
		||||
@ -125,7 +126,7 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
 | 
			
		||||
        if (matchesFilter(trigger, triggerConfig)) {
 | 
			
		||||
            NotificationInfo notificationInfo = constructNotificationInfo(trigger, triggerConfig);
 | 
			
		||||
            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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void submitNotificationRequest(List<UUID> targets, NotificationRule rule,
 | 
			
		||||
    private void submitNotificationRequest(TenantId tenantId, List<UUID> targets, NotificationRule rule,
 | 
			
		||||
                                           EntityId originatorEntityId, NotificationInfo notificationInfo, int delayInSec) {
 | 
			
		||||
        NotificationRequestConfig config = new NotificationRequestConfig();
 | 
			
		||||
        if (delayInSec > 0) {
 | 
			
		||||
            config.setSendingDelayInSec(delayInSec);
 | 
			
		||||
        }
 | 
			
		||||
        NotificationRequest notificationRequest = NotificationRequest.builder()
 | 
			
		||||
                .tenantId(rule.getTenantId())
 | 
			
		||||
                .tenantId(tenantId)
 | 
			
		||||
                .targets(targets)
 | 
			
		||||
                .templateId(rule.getTemplateId())
 | 
			
		||||
                .additionalConfig(config)
 | 
			
		||||
@ -160,7 +161,7 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul
 | 
			
		||||
        notificationExecutor.submit(() -> {
 | 
			
		||||
            try {
 | 
			
		||||
                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) {
 | 
			
		||||
                log.error("Failed to process notification request for rule {}", rule.getId(), e);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -15,18 +15,23 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.service.notification.rule.trigger;
 | 
			
		||||
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
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.rule.trigger.EntitiesLimitNotificationRuleTriggerConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.rule.trigger.NotificationRuleTriggerType;
 | 
			
		||||
import org.thingsboard.server.dao.notification.trigger.EntitiesLimitTrigger;
 | 
			
		||||
import org.thingsboard.server.dao.tenant.TenantService;
 | 
			
		||||
 | 
			
		||||
import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class EntitiesLimitTriggerProcessor implements NotificationRuleTriggerProcessor<EntitiesLimitTrigger, EntitiesLimitNotificationRuleTriggerConfig> {
 | 
			
		||||
 | 
			
		||||
    private final TenantService tenantService;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean matchesFilter(EntitiesLimitTrigger trigger, EntitiesLimitNotificationRuleTriggerConfig triggerConfig) {
 | 
			
		||||
        if (isNotEmpty(triggerConfig.getEntityTypes()) && !triggerConfig.getEntityTypes().contains(trigger.getEntityType())) {
 | 
			
		||||
@ -42,6 +47,8 @@ public class EntitiesLimitTriggerProcessor implements NotificationRuleTriggerPro
 | 
			
		||||
                .currentCount(trigger.getCurrentCount())
 | 
			
		||||
                .limit(trigger.getLimit())
 | 
			
		||||
                .percents((int) (((float)trigger.getCurrentCount() / trigger.getLimit()) * 100))
 | 
			
		||||
                .tenantId(trigger.getTenantId())
 | 
			
		||||
                .tenantName(tenantService.findTenantById(trigger.getTenantId()).getName())
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -62,7 +62,7 @@ public class EntityActionTriggerProcessor implements RuleEngineMsgNotificationRu
 | 
			
		||||
                                msgType.equals(DataConstants.ENTITY_UPDATED) ? ActionType.UPDATED :
 | 
			
		||||
                                msgType.equals(DataConstants.ENTITY_DELETED) ? ActionType.DELETED : null;
 | 
			
		||||
        return EntityActionNotificationInfo.builder()
 | 
			
		||||
                .entityId(actionType != ActionType.DELETED ? msg.getOriginator() : null)
 | 
			
		||||
                .entityId(msg.getOriginator())
 | 
			
		||||
                .entityName(msg.getMetaData().getValue("entityName"))
 | 
			
		||||
                .actionType(actionType)
 | 
			
		||||
                .originatorUserId(UUID.fromString(msg.getMetaData().getValue("userId")))
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.notification.rule.trigger.Notification
 | 
			
		||||
@Builder
 | 
			
		||||
public class EntitiesLimitTrigger implements NotificationRuleTrigger {
 | 
			
		||||
 | 
			
		||||
    private final TenantId tenantId;
 | 
			
		||||
    private final EntityType entityType;
 | 
			
		||||
    private final long currentCount;
 | 
			
		||||
    private final long limit;
 | 
			
		||||
 | 
			
		||||
@ -63,6 +63,8 @@ public interface UserService extends EntityDaoService {
 | 
			
		||||
 | 
			
		||||
    PageData<User> findTenantAdmins(TenantId tenantId, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
    PageData<User> findSysAdmins(PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
    PageData<User> findAllTenantAdmins(PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
    PageData<User> findTenantAdminsByTenantsIds(List<TenantId> tenantsIds, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ import lombok.Builder;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
@ -35,6 +36,8 @@ public class EntitiesLimitNotificationInfo implements NotificationInfo {
 | 
			
		||||
    private long currentCount;
 | 
			
		||||
    private long limit;
 | 
			
		||||
    private int percents;
 | 
			
		||||
    private TenantId tenantId;
 | 
			
		||||
    private String tenantName;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, String> getTemplateData() {
 | 
			
		||||
@ -42,7 +45,9 @@ public class EntitiesLimitNotificationInfo implements NotificationInfo {
 | 
			
		||||
                "entityType", entityType.getNormalName(),
 | 
			
		||||
                "currentCount", String.valueOf(currentCount),
 | 
			
		||||
                "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;
 | 
			
		||||
 | 
			
		||||
import lombok.Getter;
 | 
			
		||||
 | 
			
		||||
@Getter
 | 
			
		||||
public enum NotificationRuleTriggerType {
 | 
			
		||||
 | 
			
		||||
    ALARM,
 | 
			
		||||
@ -23,7 +26,17 @@ public enum NotificationRuleTriggerType {
 | 
			
		||||
    ENTITY_ACTION,
 | 
			
		||||
    RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT,
 | 
			
		||||
    ALARM_ASSIGNMENT,
 | 
			
		||||
    NEW_PLATFORM_VERSION,
 | 
			
		||||
    ENTITIES_LIMIT
 | 
			
		||||
    NEW_PLATFORM_VERSION(false),
 | 
			
		||||
    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 = CustomerUsersFilter.class, name = "CUSTOMER_USERS"),
 | 
			
		||||
        @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 = OriginatorEntityOwnerUsersFilter.class, name = "ORIGINATOR_ENTITY_OWNER_USERS"),
 | 
			
		||||
        @Type(value = AffectedUserFilter.class, name = "AFFECTED_USER")
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,8 @@ public enum UsersFilterType {
 | 
			
		||||
    USER_LIST,
 | 
			
		||||
    CUSTOMER_USERS,
 | 
			
		||||
    TENANT_ADMINISTRATORS,
 | 
			
		||||
    AFFECTED_TENANT_ADMINISTRATORS(true),
 | 
			
		||||
    SYSTEM_ADMINISTRATORS,
 | 
			
		||||
    ALL_USERS,
 | 
			
		||||
    ORIGINATOR_ENTITY_OWNER_USERS(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.settings.NotificationSettings;
 | 
			
		||||
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.AllUsersFilter;
 | 
			
		||||
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.SystemAdministratorsFilter;
 | 
			
		||||
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.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)");
 | 
			
		||||
 | 
			
		||||
        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,
 | 
			
		||||
                    "${entityType}s limit will be reached soon",
 | 
			
		||||
                    "${entityType}s limit will be reached soon for tenant ${tenantName}",
 | 
			
		||||
                    "${entityType}s usage: ${currentCount}/${limit} (${percents}%)");
 | 
			
		||||
            EntitiesLimitNotificationRuleTriggerConfig entitiesLimitRuleTriggerConfig = new EntitiesLimitNotificationRuleTriggerConfig();
 | 
			
		||||
            entitiesLimitRuleTriggerConfig.setEntityTypes(null);
 | 
			
		||||
            entitiesLimitRuleTriggerConfig.setThreshold(0.8f);
 | 
			
		||||
            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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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: {
 | 
			
		||||
                if (!tenantId.equals(TenantId.SYS_TENANT_ID)) {
 | 
			
		||||
                    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));
 | 
			
		||||
            if (notificationRuleProcessingService != null) {
 | 
			
		||||
                notificationRuleProcessingService.process(tenantId, EntitiesLimitTrigger.builder()
 | 
			
		||||
                        .tenantId(tenantId)
 | 
			
		||||
                        .entityType(entityType)
 | 
			
		||||
                        .currentCount(currentCount)
 | 
			
		||||
                        .limit(limit)
 | 
			
		||||
 | 
			
		||||
@ -252,6 +252,11 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
 | 
			
		||||
        return userDao.findTenantAdmins(tenantId.getId(), pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageData<User> findSysAdmins(PageLink pageLink) {
 | 
			
		||||
        return userDao.findAllByAuthority(Authority.SYS_ADMIN, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public PageData<User> findAllTenantAdmins(PageLink pageLink) {
 | 
			
		||||
        return userDao.findAllByAuthority(Authority.TENANT_ADMIN, pageLink);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user