System notification type
This commit is contained in:
		
							parent
							
								
									a0e4a7738e
								
							
						
					
					
						commit
						e9053c0cae
					
				@ -90,6 +90,7 @@ import org.thingsboard.server.common.data.id.EntityViewId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.MobileAppBundleId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.MobileAppId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTargetId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.OAuth2ClientId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.OtaPackageId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.QueueId;
 | 
			
		||||
@ -105,6 +106,7 @@ import org.thingsboard.server.common.data.id.WidgetTypeId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.WidgetsBundleId;
 | 
			
		||||
import org.thingsboard.server.common.data.mobile.app.MobileApp;
 | 
			
		||||
import org.thingsboard.server.common.data.mobile.bundle.MobileAppBundle;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
 | 
			
		||||
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.page.SortOrder;
 | 
			
		||||
@ -141,6 +143,7 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException;
 | 
			
		||||
import org.thingsboard.server.dao.mobile.MobileAppBundleService;
 | 
			
		||||
import org.thingsboard.server.dao.mobile.MobileAppService;
 | 
			
		||||
import org.thingsboard.server.dao.model.ModelConstants;
 | 
			
		||||
import org.thingsboard.server.dao.notification.NotificationTargetService;
 | 
			
		||||
import org.thingsboard.server.dao.oauth2.OAuth2ClientService;
 | 
			
		||||
import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
 | 
			
		||||
import org.thingsboard.server.dao.ota.OtaPackageService;
 | 
			
		||||
@ -355,6 +358,9 @@ public abstract class BaseController {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected TbServiceInfoProvider serviceInfoProvider;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    protected NotificationTargetService notificationTargetService;
 | 
			
		||||
 | 
			
		||||
    @Value("${server.log_controller_error_stack_trace}")
 | 
			
		||||
    @Getter
 | 
			
		||||
    private boolean logControllerErrorStackTrace;
 | 
			
		||||
@ -852,6 +858,10 @@ public abstract class BaseController {
 | 
			
		||||
        return checkEntityId(mobileAppBundleId, mobileAppBundleService::findMobileAppBundleById, operation);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    NotificationTarget checkNotificationTargetId(NotificationTargetId notificationTargetId, Operation operation) throws ThingsboardException {
 | 
			
		||||
        return checkEntityId(notificationTargetId, notificationTargetService::findNotificationTargetById, operation);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected <I extends EntityId> I emptyId(EntityType entityType) {
 | 
			
		||||
        return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -266,6 +266,12 @@ public class NotificationController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
        notificationRequest.setTenantId(user.getTenantId());
 | 
			
		||||
        checkEntity(notificationRequest.getId(), notificationRequest, NOTIFICATION);
 | 
			
		||||
        List<NotificationTargetId> targets = notificationRequest.getTargets().stream()
 | 
			
		||||
                .map(NotificationTargetId::new)
 | 
			
		||||
                .toList();
 | 
			
		||||
        for (NotificationTargetId targetId : targets) {
 | 
			
		||||
            checkNotificationTargetId(targetId, Operation.READ);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        notificationRequest.setOriginatorEntityId(user.getId());
 | 
			
		||||
        notificationRequest.setInfo(null);
 | 
			
		||||
@ -316,6 +322,8 @@ public class NotificationController extends BaseController {
 | 
			
		||||
        Map<String, Integer> recipientsCountByTarget = new LinkedHashMap<>();
 | 
			
		||||
        Map<NotificationTargetType, NotificationRecipient> firstRecipient = new HashMap<>();
 | 
			
		||||
        for (NotificationTarget target : targets) {
 | 
			
		||||
            checkEntity(getCurrentUser(), target, Operation.READ);
 | 
			
		||||
 | 
			
		||||
            int recipientsCount;
 | 
			
		||||
            List<NotificationRecipient> recipientsPart;
 | 
			
		||||
            NotificationTargetType targetType = target.getConfiguration().getType();
 | 
			
		||||
 | 
			
		||||
@ -127,7 +127,7 @@ public class NotificationTargetController extends BaseController {
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
 | 
			
		||||
    public NotificationTarget getNotificationTargetById(@PathVariable UUID id) throws ThingsboardException {
 | 
			
		||||
        NotificationTargetId notificationTargetId = new NotificationTargetId(id);
 | 
			
		||||
        return checkEntityId(notificationTargetId, notificationTargetService::findNotificationTargetById, Operation.READ);
 | 
			
		||||
        return checkNotificationTargetId(notificationTargetId, Operation.READ);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ApiOperation(value = "Get recipients for notification target config (getRecipientsForNotificationTargetConfig)",
 | 
			
		||||
@ -214,7 +214,7 @@ public class NotificationTargetController extends BaseController {
 | 
			
		||||
    @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
 | 
			
		||||
    public void deleteNotificationTargetById(@PathVariable UUID id) throws Exception {
 | 
			
		||||
        NotificationTargetId notificationTargetId = new NotificationTargetId(id);
 | 
			
		||||
        NotificationTarget notificationTarget = checkEntityId(notificationTargetId, notificationTargetService::findNotificationTargetById, Operation.DELETE);
 | 
			
		||||
        NotificationTarget notificationTarget = checkNotificationTargetId(notificationTargetId, Operation.DELETE);
 | 
			
		||||
        doDeleteAndLog(EntityType.NOTIFICATION_TARGET, notificationTarget, notificationTargetService::deleteNotificationTargetById);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,9 @@ import org.thingsboard.server.common.data.notification.NotificationRequestConfig
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationRequestStats;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationRequestStatus;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationStatus;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationType;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.info.GeneralNotificationInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.settings.UserNotificationSettings;
 | 
			
		||||
@ -217,6 +219,21 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void sendSystemNotification(TenantId tenantId, NotificationTargetId targetId, NotificationType type, NotificationInfo info) {
 | 
			
		||||
        log.debug("[{}] Sending {} system notification to {}: {}", tenantId, type, targetId, info);
 | 
			
		||||
        NotificationTemplate notificationTemplate = notificationTemplateService.findTenantOrSystemNotificationTemplate(tenantId, type)
 | 
			
		||||
                .orElseThrow(() -> new IllegalArgumentException("No notification template found for type " + type));
 | 
			
		||||
        NotificationRequest notificationRequest = NotificationRequest.builder()
 | 
			
		||||
                .tenantId(TenantId.SYS_TENANT_ID)
 | 
			
		||||
                .targets(List.of(targetId.getId()))
 | 
			
		||||
                .templateId(notificationTemplate.getId())
 | 
			
		||||
                .info(info)
 | 
			
		||||
                .originatorEntityId(TenantId.SYS_TENANT_ID)
 | 
			
		||||
                .build();
 | 
			
		||||
        processNotificationRequest(TenantId.SYS_TENANT_ID, notificationRequest, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void processNotificationRequestAsync(NotificationProcessingContext ctx, List<NotificationTarget> targets, FutureCallback<NotificationRequestStats> callback) {
 | 
			
		||||
        notificationExecutor.submit(() -> {
 | 
			
		||||
            long startTs = System.currentTimeMillis();
 | 
			
		||||
@ -271,7 +288,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
 | 
			
		||||
                    }, 256);
 | 
			
		||||
                } else {
 | 
			
		||||
                    recipients = new PageDataIterable<>(pageLink -> {
 | 
			
		||||
                        return notificationTargetService.findRecipientsForNotificationTargetConfig(ctx.getTenantId(), targetConfig, pageLink);
 | 
			
		||||
                        return notificationTargetService.findRecipientsForNotificationTargetConfig(target.getTenantId(), targetConfig, pageLink);
 | 
			
		||||
                    }, 256);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
 | 
			
		||||
import io.jsonwebtoken.Claims;
 | 
			
		||||
import io.jsonwebtoken.Jws;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.apache.commons.lang3.RandomStringUtils;
 | 
			
		||||
import org.awaitility.Awaitility;
 | 
			
		||||
import org.hamcrest.Matcher;
 | 
			
		||||
import org.hibernate.exception.ConstraintViolationException;
 | 
			
		||||
@ -99,6 +100,21 @@ import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantProfileId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UUIDBased;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UserId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.Notification;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationType;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.platform.UserListFilter;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.HasSubject;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.MobileAppDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.SmsDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.WebDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.oauth2.MapperType;
 | 
			
		||||
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
 | 
			
		||||
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig;
 | 
			
		||||
@ -116,6 +132,7 @@ import org.thingsboard.server.common.data.tenant.profile.TenantProfileData;
 | 
			
		||||
import org.thingsboard.server.common.msg.session.FeatureType;
 | 
			
		||||
import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
 | 
			
		||||
import org.thingsboard.server.dao.Dao;
 | 
			
		||||
import org.thingsboard.server.dao.DaoUtil;
 | 
			
		||||
import org.thingsboard.server.dao.attributes.AttributesService;
 | 
			
		||||
import org.thingsboard.server.dao.device.ClaimDevicesService;
 | 
			
		||||
import org.thingsboard.server.dao.tenant.TenantProfileService;
 | 
			
		||||
@ -136,6 +153,7 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
@ -1162,4 +1180,76 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
 | 
			
		||||
        return oAuth2Client;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTarget createNotificationTarget(UserId... usersIds) {
 | 
			
		||||
        UserListFilter filter = new UserListFilter();
 | 
			
		||||
        filter.setUsersIds(DaoUtil.toUUIDs(List.of(usersIds)));
 | 
			
		||||
        return createNotificationTarget(filter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTarget createNotificationTarget(UsersFilter usersFilter) {
 | 
			
		||||
        NotificationTarget notificationTarget = new NotificationTarget();
 | 
			
		||||
        notificationTarget.setName(usersFilter.toString() + RandomStringUtils.randomNumeric(5));
 | 
			
		||||
        PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig();
 | 
			
		||||
        targetConfig.setUsersFilter(usersFilter);
 | 
			
		||||
        notificationTarget.setConfiguration(targetConfig);
 | 
			
		||||
        return saveNotificationTarget(notificationTarget);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTarget saveNotificationTarget(NotificationTarget notificationTarget) {
 | 
			
		||||
        return doPost("/api/notification/target", notificationTarget, NotificationTarget.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTemplate createNotificationTemplate(NotificationType notificationType, String subject,
 | 
			
		||||
                                                              String text, NotificationDeliveryMethod... deliveryMethods) {
 | 
			
		||||
        NotificationTemplate notificationTemplate = new NotificationTemplate();
 | 
			
		||||
        notificationTemplate.setTenantId(tenantId);
 | 
			
		||||
        notificationTemplate.setName("Notification template: " + text);
 | 
			
		||||
        notificationTemplate.setNotificationType(notificationType);
 | 
			
		||||
        NotificationTemplateConfig config = new NotificationTemplateConfig();
 | 
			
		||||
        config.setDeliveryMethodsTemplates(new HashMap<>());
 | 
			
		||||
        for (NotificationDeliveryMethod deliveryMethod : deliveryMethods) {
 | 
			
		||||
            DeliveryMethodNotificationTemplate deliveryMethodNotificationTemplate;
 | 
			
		||||
            switch (deliveryMethod) {
 | 
			
		||||
                case WEB: {
 | 
			
		||||
                    deliveryMethodNotificationTemplate = new WebDeliveryMethodNotificationTemplate();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case EMAIL: {
 | 
			
		||||
                    deliveryMethodNotificationTemplate = new EmailDeliveryMethodNotificationTemplate();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case SMS: {
 | 
			
		||||
                    deliveryMethodNotificationTemplate = new SmsDeliveryMethodNotificationTemplate();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case MOBILE_APP:
 | 
			
		||||
                    deliveryMethodNotificationTemplate = new MobileAppDeliveryMethodNotificationTemplate();
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new IllegalArgumentException("Unsupported delivery method " + deliveryMethod);
 | 
			
		||||
            }
 | 
			
		||||
            deliveryMethodNotificationTemplate.setEnabled(true);
 | 
			
		||||
            deliveryMethodNotificationTemplate.setBody(text);
 | 
			
		||||
            if (deliveryMethodNotificationTemplate instanceof HasSubject) {
 | 
			
		||||
                ((HasSubject) deliveryMethodNotificationTemplate).setSubject(subject);
 | 
			
		||||
            }
 | 
			
		||||
            config.getDeliveryMethodsTemplates().put(deliveryMethod, deliveryMethodNotificationTemplate);
 | 
			
		||||
        }
 | 
			
		||||
        notificationTemplate.setConfiguration(config);
 | 
			
		||||
        return saveNotificationTemplate(notificationTemplate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTemplate saveNotificationTemplate(NotificationTemplate notificationTemplate) {
 | 
			
		||||
        return doPost("/api/notification/template", notificationTemplate, NotificationTemplate.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected List<Notification> getMyNotifications(boolean unreadOnly, int limit) throws Exception {
 | 
			
		||||
        return getMyNotifications(NotificationDeliveryMethod.WEB, unreadOnly, limit);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected List<Notification> getMyNotifications(NotificationDeliveryMethod deliveryMethod, boolean unreadOnly, int limit) throws Exception {
 | 
			
		||||
        return doGetTypedWithPageLink("/api/notifications?unreadOnly={unreadOnly}&deliveryMethod={deliveryMethod}&", new TypeReference<PageData<Notification>>() {},
 | 
			
		||||
                new PageLink(limit, 0), unreadOnly, deliveryMethod).getData();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -274,14 +274,6 @@ public class NotificationEdgeTest extends AbstractEdgeTest {
 | 
			
		||||
        return saveNotificationRule(notificationRule);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private NotificationTemplate saveNotificationTemplate(NotificationTemplate notificationTemplate) {
 | 
			
		||||
        return doPost("/api/notification/template", notificationTemplate, NotificationTemplate.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private NotificationTarget saveNotificationTarget(NotificationTarget notificationTarget) {
 | 
			
		||||
        return doPost("/api/notification/target", notificationTarget, NotificationTarget.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private NotificationRule saveNotificationRule(NotificationRule notificationRule) {
 | 
			
		||||
        return doPost("/api/notification/rule", notificationRule, NotificationRule.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -30,8 +30,6 @@ import org.thingsboard.server.common.data.id.NotificationTargetId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTemplateId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UUIDBased;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UserId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.Notification;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationRequest;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationRequestConfig;
 | 
			
		||||
@ -44,18 +42,7 @@ import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo
 | 
			
		||||
import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.settings.NotificationDeliveryMethodConfig;
 | 
			
		||||
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.PlatformUsersNotificationTargetConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.platform.UserListFilter;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.HasSubject;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.MobileAppDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.SmsDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.WebDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.security.Authority;
 | 
			
		||||
@ -71,7 +58,6 @@ import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository;
 | 
			
		||||
 | 
			
		||||
import java.net.URISyntaxException;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
@ -120,25 +106,6 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
 | 
			
		||||
        notificationSettingsService.deleteNotificationSettings(TenantId.SYS_TENANT_ID);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTarget createNotificationTarget(UserId... usersIds) {
 | 
			
		||||
        UserListFilter filter = new UserListFilter();
 | 
			
		||||
        filter.setUsersIds(DaoUtil.toUUIDs(List.of(usersIds)));
 | 
			
		||||
        return createNotificationTarget(filter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTarget createNotificationTarget(UsersFilter usersFilter) {
 | 
			
		||||
        NotificationTarget notificationTarget = new NotificationTarget();
 | 
			
		||||
        notificationTarget.setName(usersFilter.toString());
 | 
			
		||||
        PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig();
 | 
			
		||||
        targetConfig.setUsersFilter(usersFilter);
 | 
			
		||||
        notificationTarget.setConfiguration(targetConfig);
 | 
			
		||||
        return saveNotificationTarget(notificationTarget);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTarget saveNotificationTarget(NotificationTarget notificationTarget) {
 | 
			
		||||
        return doPost("/api/notification/target", notificationTarget, NotificationTarget.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationRequest submitNotificationRequest(NotificationTargetId targetId, String text, NotificationDeliveryMethod... deliveryMethods) {
 | 
			
		||||
        return submitNotificationRequest(targetId, text, 0, deliveryMethods);
 | 
			
		||||
    }
 | 
			
		||||
@ -178,50 +145,6 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
 | 
			
		||||
        return findNotificationRequest(notificationRequestId).getStats();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTemplate createNotificationTemplate(NotificationType notificationType, String subject,
 | 
			
		||||
                                                              String text, NotificationDeliveryMethod... deliveryMethods) {
 | 
			
		||||
        NotificationTemplate notificationTemplate = new NotificationTemplate();
 | 
			
		||||
        notificationTemplate.setTenantId(tenantId);
 | 
			
		||||
        notificationTemplate.setName("Notification template: " + text);
 | 
			
		||||
        notificationTemplate.setNotificationType(notificationType);
 | 
			
		||||
        NotificationTemplateConfig config = new NotificationTemplateConfig();
 | 
			
		||||
        config.setDeliveryMethodsTemplates(new HashMap<>());
 | 
			
		||||
        for (NotificationDeliveryMethod deliveryMethod : deliveryMethods) {
 | 
			
		||||
            DeliveryMethodNotificationTemplate deliveryMethodNotificationTemplate;
 | 
			
		||||
            switch (deliveryMethod) {
 | 
			
		||||
                case WEB: {
 | 
			
		||||
                    deliveryMethodNotificationTemplate = new WebDeliveryMethodNotificationTemplate();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case EMAIL: {
 | 
			
		||||
                    deliveryMethodNotificationTemplate = new EmailDeliveryMethodNotificationTemplate();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case SMS: {
 | 
			
		||||
                    deliveryMethodNotificationTemplate = new SmsDeliveryMethodNotificationTemplate();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case MOBILE_APP:
 | 
			
		||||
                    deliveryMethodNotificationTemplate = new MobileAppDeliveryMethodNotificationTemplate();
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new IllegalArgumentException("Unsupported delivery method " + deliveryMethod);
 | 
			
		||||
            }
 | 
			
		||||
            deliveryMethodNotificationTemplate.setEnabled(true);
 | 
			
		||||
            deliveryMethodNotificationTemplate.setBody(text);
 | 
			
		||||
            if (deliveryMethodNotificationTemplate instanceof HasSubject) {
 | 
			
		||||
                ((HasSubject) deliveryMethodNotificationTemplate).setSubject(subject);
 | 
			
		||||
            }
 | 
			
		||||
            config.getDeliveryMethodsTemplates().put(deliveryMethod, deliveryMethodNotificationTemplate);
 | 
			
		||||
        }
 | 
			
		||||
        notificationTemplate.setConfiguration(config);
 | 
			
		||||
        return saveNotificationTemplate(notificationTemplate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationTemplate saveNotificationTemplate(NotificationTemplate notificationTemplate) {
 | 
			
		||||
        return doPost("/api/notification/template", notificationTemplate, NotificationTemplate.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void saveNotificationSettings(NotificationSettings notificationSettings) throws Exception {
 | 
			
		||||
        doPost("/api/notification/settings", notificationSettings).andExpect(status().isOk());
 | 
			
		||||
    }
 | 
			
		||||
@ -258,15 +181,6 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
 | 
			
		||||
        doDelete("/api/notification/request/" + id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected List<Notification> getMyNotifications(boolean unreadOnly, int limit) throws Exception {
 | 
			
		||||
        return getMyNotifications(NotificationDeliveryMethod.WEB, unreadOnly, limit);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected List<Notification> getMyNotifications(NotificationDeliveryMethod deliveryMethod, boolean unreadOnly, int limit) throws Exception {
 | 
			
		||||
        return doGetTypedWithPageLink("/api/notifications?unreadOnly={unreadOnly}&deliveryMethod={deliveryMethod}&", new TypeReference<PageData<Notification>>() {},
 | 
			
		||||
                new PageLink(limit, 0), unreadOnly, deliveryMethod).getData();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected NotificationRule createNotificationRule(NotificationRuleTriggerConfig triggerConfig, String subject, String text, NotificationTargetId... targets) {
 | 
			
		||||
        return createNotificationRule(triggerConfig, subject, text, List.of(targets), NotificationDeliveryMethod.WEB);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -15,11 +15,15 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.dao.notification;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UserId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationType;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.settings.UserNotificationSettings;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public interface NotificationSettingsService {
 | 
			
		||||
 | 
			
		||||
    void saveNotificationSettings(TenantId tenantId, NotificationSettings settings);
 | 
			
		||||
@ -36,4 +40,6 @@ public interface NotificationSettingsService {
 | 
			
		||||
 | 
			
		||||
    void updateDefaultNotificationConfigs(TenantId tenantId);
 | 
			
		||||
 | 
			
		||||
    void moveMailTemplatesToNotificationCenter(TenantId tenantId, JsonNode mailTemplates, Map<String, NotificationType> mailTemplatesNames);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,9 @@ import org.thingsboard.server.common.data.notification.template.NotificationTemp
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageData;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
public interface NotificationTemplateService {
 | 
			
		||||
 | 
			
		||||
@ -32,7 +34,11 @@ public interface NotificationTemplateService {
 | 
			
		||||
 | 
			
		||||
    PageData<NotificationTemplate> findNotificationTemplatesByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
    int countNotificationTemplatesByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes);
 | 
			
		||||
    Optional<NotificationTemplate> findTenantOrSystemNotificationTemplate(TenantId tenantId, NotificationType notificationType);
 | 
			
		||||
 | 
			
		||||
    Optional<NotificationTemplate> findNotificationTemplateByTenantIdAndType(TenantId tenantId, NotificationType notificationType);
 | 
			
		||||
 | 
			
		||||
    int countNotificationTemplatesByTenantIdAndNotificationTypes(TenantId tenantId, Collection<NotificationType> notificationTypes);
 | 
			
		||||
 | 
			
		||||
    void deleteNotificationTemplateById(TenantId tenantId, NotificationTemplateId id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,12 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.common.data.notification;
 | 
			
		||||
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Getter;
 | 
			
		||||
import lombok.NoArgsConstructor;
 | 
			
		||||
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@NoArgsConstructor
 | 
			
		||||
public enum NotificationType {
 | 
			
		||||
 | 
			
		||||
    GENERAL,
 | 
			
		||||
@ -31,6 +37,9 @@ public enum NotificationType {
 | 
			
		||||
    RATE_LIMITS,
 | 
			
		||||
    EDGE_CONNECTION,
 | 
			
		||||
    EDGE_COMMUNICATION_FAILURE,
 | 
			
		||||
    TASK_PROCESSING_FAILURE
 | 
			
		||||
    TASK_PROCESSING_FAILURE;
 | 
			
		||||
 | 
			
		||||
    @Getter
 | 
			
		||||
    private boolean system; // for future use and compatibility with PE
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,8 +15,11 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.dao.notification;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.JsonNode;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.ObjectNode;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
import org.springframework.cache.annotation.CacheEvict;
 | 
			
		||||
import org.springframework.cache.annotation.Cacheable;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
@ -41,7 +44,9 @@ import org.thingsboard.server.common.data.notification.targets.platform.SystemAd
 | 
			
		||||
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.UsersFilterType;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig;
 | 
			
		||||
import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.settings.UserSettings;
 | 
			
		||||
import org.thingsboard.server.common.data.settings.UserSettingsType;
 | 
			
		||||
@ -249,6 +254,52 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void moveMailTemplatesToNotificationCenter(TenantId tenantId, JsonNode mailTemplates, Map<String, NotificationType> mailTemplatesNames) {
 | 
			
		||||
        mailTemplatesNames.forEach((mailTemplateName, notificationType) -> {
 | 
			
		||||
            moveMailTemplateToNotificationCenter(tenantId, mailTemplates, mailTemplateName, notificationType);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void moveMailTemplateToNotificationCenter(TenantId tenantId, JsonNode mailTemplates, String mailTemplateName, NotificationType notificationType) {
 | 
			
		||||
        JsonNode mailTemplate = mailTemplates.get(mailTemplateName);
 | 
			
		||||
        if (mailTemplate == null || mailTemplate.isNull() || !mailTemplate.has("subject") || !mailTemplate.has("body")) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String subject = mailTemplate.get("subject").asText();
 | 
			
		||||
        String body = mailTemplate.get("body").asText();
 | 
			
		||||
        body = body.replace("targetEmail", "recipientEmail");
 | 
			
		||||
 | 
			
		||||
        NotificationTemplate notificationTemplate = null;
 | 
			
		||||
        if (tenantId.isSysTenantId()) {
 | 
			
		||||
            // updating system notification template, not touching tenants' templates
 | 
			
		||||
            notificationTemplate = notificationTemplateService.findNotificationTemplateByTenantIdAndType(tenantId, notificationType).orElse(null);
 | 
			
		||||
        }
 | 
			
		||||
        if (notificationTemplate == null) {
 | 
			
		||||
            log.debug("[{}] Creating {} template", tenantId, notificationType);
 | 
			
		||||
            notificationTemplate = new NotificationTemplate();
 | 
			
		||||
        } else {
 | 
			
		||||
            log.debug("[{}] Updating {} template", tenantId, notificationType);
 | 
			
		||||
        }
 | 
			
		||||
        String name = StringUtils.capitalize(notificationType.name().toLowerCase().replaceAll("_", " ")) + " notification";
 | 
			
		||||
        notificationTemplate.setName(name);
 | 
			
		||||
        notificationTemplate.setTenantId(tenantId);
 | 
			
		||||
        notificationTemplate.setNotificationType(notificationType);
 | 
			
		||||
        NotificationTemplateConfig notificationTemplateConfig = new NotificationTemplateConfig();
 | 
			
		||||
 | 
			
		||||
        EmailDeliveryMethodNotificationTemplate emailNotificationTemplate = new EmailDeliveryMethodNotificationTemplate();
 | 
			
		||||
        emailNotificationTemplate.setEnabled(true);
 | 
			
		||||
        emailNotificationTemplate.setSubject(subject);
 | 
			
		||||
        emailNotificationTemplate.setBody(body);
 | 
			
		||||
 | 
			
		||||
        notificationTemplateConfig.setDeliveryMethodsTemplates(Map.of(NotificationDeliveryMethod.EMAIL, emailNotificationTemplate));
 | 
			
		||||
        notificationTemplate.setConfiguration(notificationTemplateConfig);
 | 
			
		||||
        notificationTemplateService.saveNotificationTemplate(tenantId, notificationTemplate);
 | 
			
		||||
 | 
			
		||||
        ((ObjectNode) mailTemplates).remove(mailTemplateName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isNotificationConfigured(TenantId tenantId, NotificationType... notificationTypes) {
 | 
			
		||||
        return notificationTemplateService.countNotificationTemplatesByTenantIdAndNotificationTypes(tenantId, List.of(notificationTypes)) > 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -109,7 +109,7 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
 | 
			
		||||
        NotificationTarget notificationTarget = findNotificationTargetById(tenantId, targetId);
 | 
			
		||||
        Objects.requireNonNull(notificationTarget, "Notification target [" + targetId + "] not found");
 | 
			
		||||
        NotificationTargetConfig configuration = notificationTarget.getConfiguration();
 | 
			
		||||
        return findRecipientsForNotificationTargetConfig(tenantId, (PlatformUsersNotificationTargetConfig) configuration, pageLink);
 | 
			
		||||
        return findRecipientsForNotificationTargetConfig(notificationTarget.getTenantId(), (PlatformUsersNotificationTargetConfig) configuration, pageLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,7 @@ import org.thingsboard.server.dao.entity.EntityDaoService;
 | 
			
		||||
import org.thingsboard.server.dao.eventsourcing.DeleteEntityEvent;
 | 
			
		||||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
@ -50,11 +51,19 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public NotificationTemplate saveNotificationTemplate(TenantId tenantId, NotificationTemplate notificationTemplate) {
 | 
			
		||||
        NotificationType notificationType = notificationTemplate.getNotificationType();
 | 
			
		||||
        if (notificationTemplate.getId() != null) {
 | 
			
		||||
            NotificationTemplate oldNotificationTemplate = findNotificationTemplateById(tenantId, notificationTemplate.getId());
 | 
			
		||||
            if (notificationTemplate.getNotificationType() != oldNotificationTemplate.getNotificationType()) {
 | 
			
		||||
            if (notificationType != oldNotificationTemplate.getNotificationType()) {
 | 
			
		||||
                throw new IllegalArgumentException("Notification type cannot be updated");
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (notificationType.isSystem()) {
 | 
			
		||||
                int systemTemplatesCount = countNotificationTemplatesByTenantIdAndNotificationTypes(tenantId, List.of(notificationType));
 | 
			
		||||
                if (systemTemplatesCount > 0) {
 | 
			
		||||
                    throw new IllegalArgumentException("There can only be one notification template of this type");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            NotificationTemplate savedTemplate = notificationTemplateDao.saveAndFlush(tenantId, notificationTemplate);
 | 
			
		||||
@ -75,7 +84,19 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int countNotificationTemplatesByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes) {
 | 
			
		||||
    public Optional<NotificationTemplate> findTenantOrSystemNotificationTemplate(TenantId tenantId, NotificationType notificationType) {
 | 
			
		||||
        return findNotificationTemplateByTenantIdAndType(tenantId, notificationType)
 | 
			
		||||
                .or(() -> findNotificationTemplateByTenantIdAndType(TenantId.SYS_TENANT_ID, notificationType));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Optional<NotificationTemplate> findNotificationTemplateByTenantIdAndType(TenantId tenantId, NotificationType notificationType) {
 | 
			
		||||
        return findNotificationTemplatesByTenantIdAndNotificationTypes(tenantId, List.of(notificationType), new PageLink(1)).getData()
 | 
			
		||||
                .stream().findFirst();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int countNotificationTemplatesByTenantIdAndNotificationTypes(TenantId tenantId, Collection<NotificationType> notificationTypes) {
 | 
			
		||||
        return notificationTemplateDao.countByTenantIdAndNotificationTypes(tenantId, notificationTypes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -86,8 +107,16 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void deleteEntity(TenantId tenantId, EntityId id, boolean force) {
 | 
			
		||||
        if (!force && notificationRequestDao.existsByTenantIdAndStatusAndTemplateId(tenantId, NotificationRequestStatus.SCHEDULED, (NotificationTemplateId) id)) {
 | 
			
		||||
            throw new IllegalArgumentException("Notification template is referenced by scheduled notification request");
 | 
			
		||||
        if (!force) {
 | 
			
		||||
            if (notificationRequestDao.existsByTenantIdAndStatusAndTemplateId(tenantId, NotificationRequestStatus.SCHEDULED, (NotificationTemplateId) id)) {
 | 
			
		||||
                throw new IllegalArgumentException("Notification template is referenced by scheduled notification request");
 | 
			
		||||
            }
 | 
			
		||||
            if (tenantId.isSysTenantId()) {
 | 
			
		||||
                NotificationTemplate notificationTemplate = findNotificationTemplateById(tenantId, (NotificationTemplateId) id);
 | 
			
		||||
                if (notificationTemplate.getNotificationType().isSystem()) {
 | 
			
		||||
                    throw new IllegalArgumentException("System notification template cannot be deleted");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        try {
 | 
			
		||||
            notificationTemplateDao.removeById(tenantId, id.getId());
 | 
			
		||||
 | 
			
		||||
@ -24,13 +24,14 @@ import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.dao.Dao;
 | 
			
		||||
import org.thingsboard.server.dao.ExportableEntityDao;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public interface NotificationTemplateDao extends Dao<NotificationTemplate>, ExportableEntityDao<NotificationTemplateId, NotificationTemplate> {
 | 
			
		||||
 | 
			
		||||
    PageData<NotificationTemplate> findByTenantIdAndNotificationTypesAndPageLink(TenantId tenantId, List<NotificationType> notificationTypes, PageLink pageLink);
 | 
			
		||||
 | 
			
		||||
    int countByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes);
 | 
			
		||||
    int countByTenantIdAndNotificationTypes(TenantId tenantId, Collection<NotificationType> notificationTypes);
 | 
			
		||||
 | 
			
		||||
    void removeByTenantId(TenantId tenantId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,7 @@ import org.thingsboard.server.dao.notification.NotificationTemplateDao;
 | 
			
		||||
import org.thingsboard.server.dao.sql.JpaAbstractDao;
 | 
			
		||||
import org.thingsboard.server.dao.util.SqlDao;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@ -53,7 +54,7 @@ public class JpaNotificationTemplateDao extends JpaAbstractDao<NotificationTempl
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int countByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes) {
 | 
			
		||||
    public int countByTenantIdAndNotificationTypes(TenantId tenantId, Collection<NotificationType> notificationTypes) {
 | 
			
		||||
        return notificationTemplateRepository.countByTenantIdAndNotificationTypes(tenantId.getId(), notificationTypes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.notification.NotificationType;
 | 
			
		||||
import org.thingsboard.server.dao.ExportableEntityRepository;
 | 
			
		||||
import org.thingsboard.server.dao.model.sql.NotificationTemplateEntity;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@ -45,7 +46,7 @@ public interface NotificationTemplateRepository extends JpaRepository<Notificati
 | 
			
		||||
    @Query("SELECT count(t) FROM NotificationTemplateEntity t WHERE t.tenantId = :tenantId AND " +
 | 
			
		||||
            "t.notificationType IN :notificationTypes")
 | 
			
		||||
    int countByTenantIdAndNotificationTypes(@Param("tenantId") UUID tenantId,
 | 
			
		||||
                                            @Param("notificationTypes") List<NotificationType> notificationTypes);
 | 
			
		||||
                                            @Param("notificationTypes") Collection<NotificationType> notificationTypes);
 | 
			
		||||
 | 
			
		||||
    @Transactional
 | 
			
		||||
    @Modifying
 | 
			
		||||
 | 
			
		||||
@ -18,12 +18,15 @@ package org.thingsboard.rule.engine.api;
 | 
			
		||||
import com.google.common.util.concurrent.FutureCallback;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationRequestId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.NotificationTargetId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.UserId;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationRequest;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationRequestStats;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.NotificationType;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.info.GeneralNotificationInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter;
 | 
			
		||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
 | 
			
		||||
 | 
			
		||||
@ -35,6 +38,8 @@ public interface NotificationCenter {
 | 
			
		||||
 | 
			
		||||
    void sendGeneralWebNotification(TenantId tenantId, UsersFilter recipients, NotificationTemplate template, GeneralNotificationInfo info);
 | 
			
		||||
 | 
			
		||||
    void sendSystemNotification(TenantId tenantId, NotificationTargetId targetId, NotificationType type, NotificationInfo info); // for future use and compatibility with PE
 | 
			
		||||
 | 
			
		||||
    void deleteNotificationRequest(TenantId tenantId, NotificationRequestId notificationRequestId);
 | 
			
		||||
 | 
			
		||||
    void markNotificationAsRead(TenantId tenantId, UserId recipientId, NotificationId notificationId);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user