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.HasId;
|
||||||
import org.thingsboard.server.common.data.id.MobileAppBundleId;
|
import org.thingsboard.server.common.data.id.MobileAppBundleId;
|
||||||
import org.thingsboard.server.common.data.id.MobileAppId;
|
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.OAuth2ClientId;
|
||||||
import org.thingsboard.server.common.data.id.OtaPackageId;
|
import org.thingsboard.server.common.data.id.OtaPackageId;
|
||||||
import org.thingsboard.server.common.data.id.QueueId;
|
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.id.WidgetsBundleId;
|
||||||
import org.thingsboard.server.common.data.mobile.app.MobileApp;
|
import org.thingsboard.server.common.data.mobile.app.MobileApp;
|
||||||
import org.thingsboard.server.common.data.mobile.bundle.MobileAppBundle;
|
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.oauth2.OAuth2Client;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.page.SortOrder;
|
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.MobileAppBundleService;
|
||||||
import org.thingsboard.server.dao.mobile.MobileAppService;
|
import org.thingsboard.server.dao.mobile.MobileAppService;
|
||||||
import org.thingsboard.server.dao.model.ModelConstants;
|
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.OAuth2ClientService;
|
||||||
import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
|
import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
|
||||||
import org.thingsboard.server.dao.ota.OtaPackageService;
|
import org.thingsboard.server.dao.ota.OtaPackageService;
|
||||||
@ -355,6 +358,9 @@ public abstract class BaseController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
protected TbServiceInfoProvider serviceInfoProvider;
|
protected TbServiceInfoProvider serviceInfoProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected NotificationTargetService notificationTargetService;
|
||||||
|
|
||||||
@Value("${server.log_controller_error_stack_trace}")
|
@Value("${server.log_controller_error_stack_trace}")
|
||||||
@Getter
|
@Getter
|
||||||
private boolean logControllerErrorStackTrace;
|
private boolean logControllerErrorStackTrace;
|
||||||
@ -852,6 +858,10 @@ public abstract class BaseController {
|
|||||||
return checkEntityId(mobileAppBundleId, mobileAppBundleService::findMobileAppBundleById, operation);
|
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) {
|
protected <I extends EntityId> I emptyId(EntityType entityType) {
|
||||||
return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
|
return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -266,6 +266,12 @@ public class NotificationController extends BaseController {
|
|||||||
}
|
}
|
||||||
notificationRequest.setTenantId(user.getTenantId());
|
notificationRequest.setTenantId(user.getTenantId());
|
||||||
checkEntity(notificationRequest.getId(), notificationRequest, NOTIFICATION);
|
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.setOriginatorEntityId(user.getId());
|
||||||
notificationRequest.setInfo(null);
|
notificationRequest.setInfo(null);
|
||||||
@ -316,6 +322,8 @@ public class NotificationController extends BaseController {
|
|||||||
Map<String, Integer> recipientsCountByTarget = new LinkedHashMap<>();
|
Map<String, Integer> recipientsCountByTarget = new LinkedHashMap<>();
|
||||||
Map<NotificationTargetType, NotificationRecipient> firstRecipient = new HashMap<>();
|
Map<NotificationTargetType, NotificationRecipient> firstRecipient = new HashMap<>();
|
||||||
for (NotificationTarget target : targets) {
|
for (NotificationTarget target : targets) {
|
||||||
|
checkEntity(getCurrentUser(), target, Operation.READ);
|
||||||
|
|
||||||
int recipientsCount;
|
int recipientsCount;
|
||||||
List<NotificationRecipient> recipientsPart;
|
List<NotificationRecipient> recipientsPart;
|
||||||
NotificationTargetType targetType = target.getConfiguration().getType();
|
NotificationTargetType targetType = target.getConfiguration().getType();
|
||||||
|
|||||||
@ -127,7 +127,7 @@ public class NotificationTargetController extends BaseController {
|
|||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
||||||
public NotificationTarget getNotificationTargetById(@PathVariable UUID id) throws ThingsboardException {
|
public NotificationTarget getNotificationTargetById(@PathVariable UUID id) throws ThingsboardException {
|
||||||
NotificationTargetId notificationTargetId = new NotificationTargetId(id);
|
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)",
|
@ApiOperation(value = "Get recipients for notification target config (getRecipientsForNotificationTargetConfig)",
|
||||||
@ -214,7 +214,7 @@ public class NotificationTargetController extends BaseController {
|
|||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
|
||||||
public void deleteNotificationTargetById(@PathVariable UUID id) throws Exception {
|
public void deleteNotificationTargetById(@PathVariable UUID id) throws Exception {
|
||||||
NotificationTargetId notificationTargetId = new NotificationTargetId(id);
|
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);
|
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.NotificationRequestStats;
|
||||||
import org.thingsboard.server.common.data.notification.NotificationRequestStatus;
|
import org.thingsboard.server.common.data.notification.NotificationRequestStatus;
|
||||||
import org.thingsboard.server.common.data.notification.NotificationStatus;
|
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.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.info.RuleOriginatedNotificationInfo;
|
||||||
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.settings.UserNotificationSettings;
|
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) {
|
private void processNotificationRequestAsync(NotificationProcessingContext ctx, List<NotificationTarget> targets, FutureCallback<NotificationRequestStats> callback) {
|
||||||
notificationExecutor.submit(() -> {
|
notificationExecutor.submit(() -> {
|
||||||
long startTs = System.currentTimeMillis();
|
long startTs = System.currentTimeMillis();
|
||||||
@ -271,7 +288,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
|
|||||||
}, 256);
|
}, 256);
|
||||||
} else {
|
} else {
|
||||||
recipients = new PageDataIterable<>(pageLink -> {
|
recipients = new PageDataIterable<>(pageLink -> {
|
||||||
return notificationTargetService.findRecipientsForNotificationTargetConfig(ctx.getTenantId(), targetConfig, pageLink);
|
return notificationTargetService.findRecipientsForNotificationTargetConfig(target.getTenantId(), targetConfig, pageLink);
|
||||||
}, 256);
|
}, 256);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
|
|||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.Jws;
|
import io.jsonwebtoken.Jws;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.awaitility.Awaitility;
|
import org.awaitility.Awaitility;
|
||||||
import org.hamcrest.Matcher;
|
import org.hamcrest.Matcher;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
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.TenantProfileId;
|
||||||
import org.thingsboard.server.common.data.id.UUIDBased;
|
import org.thingsboard.server.common.data.id.UUIDBased;
|
||||||
import org.thingsboard.server.common.data.id.UserId;
|
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.MapperType;
|
||||||
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
|
import org.thingsboard.server.common.data.oauth2.OAuth2Client;
|
||||||
import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig;
|
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.common.msg.session.FeatureType;
|
||||||
import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
|
import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
|
||||||
import org.thingsboard.server.dao.Dao;
|
import org.thingsboard.server.dao.Dao;
|
||||||
|
import org.thingsboard.server.dao.DaoUtil;
|
||||||
import org.thingsboard.server.dao.attributes.AttributesService;
|
import org.thingsboard.server.dao.attributes.AttributesService;
|
||||||
import org.thingsboard.server.dao.device.ClaimDevicesService;
|
import org.thingsboard.server.dao.device.ClaimDevicesService;
|
||||||
import org.thingsboard.server.dao.tenant.TenantProfileService;
|
import org.thingsboard.server.dao.tenant.TenantProfileService;
|
||||||
@ -136,6 +153,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -1162,4 +1180,76 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest {
|
|||||||
return oAuth2Client;
|
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);
|
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) {
|
private NotificationRule saveNotificationRule(NotificationRule notificationRule) {
|
||||||
return doPost("/api/notification/rule", notificationRule, NotificationRule.class);
|
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.NotificationTemplateId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.id.UUIDBased;
|
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.NotificationDeliveryMethod;
|
||||||
import org.thingsboard.server.common.data.notification.NotificationRequest;
|
import org.thingsboard.server.common.data.notification.NotificationRequest;
|
||||||
import org.thingsboard.server.common.data.notification.NotificationRequestConfig;
|
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.rule.trigger.config.NotificationRuleTriggerConfig;
|
||||||
import org.thingsboard.server.common.data.notification.settings.NotificationDeliveryMethodConfig;
|
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.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.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.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.security.Authority;
|
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.net.URISyntaxException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -120,25 +106,6 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
|
|||||||
notificationSettingsService.deleteNotificationSettings(TenantId.SYS_TENANT_ID);
|
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) {
|
protected NotificationRequest submitNotificationRequest(NotificationTargetId targetId, String text, NotificationDeliveryMethod... deliveryMethods) {
|
||||||
return submitNotificationRequest(targetId, text, 0, deliveryMethods);
|
return submitNotificationRequest(targetId, text, 0, deliveryMethods);
|
||||||
}
|
}
|
||||||
@ -178,50 +145,6 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
|
|||||||
return findNotificationRequest(notificationRequestId).getStats();
|
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 {
|
protected void saveNotificationSettings(NotificationSettings notificationSettings) throws Exception {
|
||||||
doPost("/api/notification/settings", notificationSettings).andExpect(status().isOk());
|
doPost("/api/notification/settings", notificationSettings).andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
@ -258,15 +181,6 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
|
|||||||
doDelete("/api/notification/request/" + id);
|
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) {
|
protected NotificationRule createNotificationRule(NotificationRuleTriggerConfig triggerConfig, String subject, String text, NotificationTargetId... targets) {
|
||||||
return createNotificationRule(triggerConfig, subject, text, List.of(targets), NotificationDeliveryMethod.WEB);
|
return createNotificationRule(triggerConfig, subject, text, List.of(targets), NotificationDeliveryMethod.WEB);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,11 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.dao.notification;
|
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.TenantId;
|
||||||
import org.thingsboard.server.common.data.id.UserId;
|
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.NotificationSettings;
|
||||||
import org.thingsboard.server.common.data.notification.settings.UserNotificationSettings;
|
import org.thingsboard.server.common.data.notification.settings.UserNotificationSettings;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface NotificationSettingsService {
|
public interface NotificationSettingsService {
|
||||||
|
|
||||||
void saveNotificationSettings(TenantId tenantId, NotificationSettings settings);
|
void saveNotificationSettings(TenantId tenantId, NotificationSettings settings);
|
||||||
@ -36,4 +40,6 @@ public interface NotificationSettingsService {
|
|||||||
|
|
||||||
void updateDefaultNotificationConfigs(TenantId tenantId);
|
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.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface NotificationTemplateService {
|
public interface NotificationTemplateService {
|
||||||
|
|
||||||
@ -32,7 +34,11 @@ public interface NotificationTemplateService {
|
|||||||
|
|
||||||
PageData<NotificationTemplate> findNotificationTemplatesByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes, PageLink pageLink);
|
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);
|
void deleteNotificationTemplateById(TenantId tenantId, NotificationTemplateId id);
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.common.data.notification;
|
package org.thingsboard.server.common.data.notification;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public enum NotificationType {
|
public enum NotificationType {
|
||||||
|
|
||||||
GENERAL,
|
GENERAL,
|
||||||
@ -31,6 +37,9 @@ public enum NotificationType {
|
|||||||
RATE_LIMITS,
|
RATE_LIMITS,
|
||||||
EDGE_CONNECTION,
|
EDGE_CONNECTION,
|
||||||
EDGE_COMMUNICATION_FAILURE,
|
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;
|
package org.thingsboard.server.dao.notification;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
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.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.targets.platform.UsersFilterType;
|
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.NotificationTemplate;
|
||||||
|
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
import org.thingsboard.server.common.data.settings.UserSettings;
|
import org.thingsboard.server.common.data.settings.UserSettings;
|
||||||
import org.thingsboard.server.common.data.settings.UserSettingsType;
|
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) {
|
private boolean isNotificationConfigured(TenantId tenantId, NotificationType... notificationTypes) {
|
||||||
return notificationTemplateService.countNotificationTemplatesByTenantIdAndNotificationTypes(tenantId, List.of(notificationTypes)) > 0;
|
return notificationTemplateService.countNotificationTemplatesByTenantIdAndNotificationTypes(tenantId, List.of(notificationTypes)) > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,7 +109,7 @@ public class DefaultNotificationTargetService extends AbstractEntityService impl
|
|||||||
NotificationTarget notificationTarget = findNotificationTargetById(tenantId, targetId);
|
NotificationTarget notificationTarget = findNotificationTargetById(tenantId, targetId);
|
||||||
Objects.requireNonNull(notificationTarget, "Notification target [" + targetId + "] not found");
|
Objects.requireNonNull(notificationTarget, "Notification target [" + targetId + "] not found");
|
||||||
NotificationTargetConfig configuration = notificationTarget.getConfiguration();
|
NotificationTargetConfig configuration = notificationTarget.getConfiguration();
|
||||||
return findRecipientsForNotificationTargetConfig(tenantId, (PlatformUsersNotificationTargetConfig) configuration, pageLink);
|
return findRecipientsForNotificationTargetConfig(notificationTarget.getTenantId(), (PlatformUsersNotificationTargetConfig) configuration, pageLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.DeleteEntityEvent;
|
||||||
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
|
import org.thingsboard.server.dao.eventsourcing.SaveEntityEvent;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -50,11 +51,19 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NotificationTemplate saveNotificationTemplate(TenantId tenantId, NotificationTemplate notificationTemplate) {
|
public NotificationTemplate saveNotificationTemplate(TenantId tenantId, NotificationTemplate notificationTemplate) {
|
||||||
|
NotificationType notificationType = notificationTemplate.getNotificationType();
|
||||||
if (notificationTemplate.getId() != null) {
|
if (notificationTemplate.getId() != null) {
|
||||||
NotificationTemplate oldNotificationTemplate = findNotificationTemplateById(tenantId, notificationTemplate.getId());
|
NotificationTemplate oldNotificationTemplate = findNotificationTemplateById(tenantId, notificationTemplate.getId());
|
||||||
if (notificationTemplate.getNotificationType() != oldNotificationTemplate.getNotificationType()) {
|
if (notificationType != oldNotificationTemplate.getNotificationType()) {
|
||||||
throw new IllegalArgumentException("Notification type cannot be updated");
|
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 {
|
try {
|
||||||
NotificationTemplate savedTemplate = notificationTemplateDao.saveAndFlush(tenantId, notificationTemplate);
|
NotificationTemplate savedTemplate = notificationTemplateDao.saveAndFlush(tenantId, notificationTemplate);
|
||||||
@ -75,7 +84,19 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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);
|
return notificationTemplateDao.countByTenantIdAndNotificationTypes(tenantId, notificationTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +107,16 @@ public class DefaultNotificationTemplateService extends AbstractEntityService im
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteEntity(TenantId tenantId, EntityId id, boolean force) {
|
public void deleteEntity(TenantId tenantId, EntityId id, boolean force) {
|
||||||
if (!force && notificationRequestDao.existsByTenantIdAndStatusAndTemplateId(tenantId, NotificationRequestStatus.SCHEDULED, (NotificationTemplateId) id)) {
|
if (!force) {
|
||||||
throw new IllegalArgumentException("Notification template is referenced by scheduled notification request");
|
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 {
|
try {
|
||||||
notificationTemplateDao.removeById(tenantId, id.getId());
|
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.Dao;
|
||||||
import org.thingsboard.server.dao.ExportableEntityDao;
|
import org.thingsboard.server.dao.ExportableEntityDao;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface NotificationTemplateDao extends Dao<NotificationTemplate>, ExportableEntityDao<NotificationTemplateId, NotificationTemplate> {
|
public interface NotificationTemplateDao extends Dao<NotificationTemplate>, ExportableEntityDao<NotificationTemplateId, NotificationTemplate> {
|
||||||
|
|
||||||
PageData<NotificationTemplate> findByTenantIdAndNotificationTypesAndPageLink(TenantId tenantId, List<NotificationType> notificationTypes, PageLink pageLink);
|
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);
|
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.sql.JpaAbstractDao;
|
||||||
import org.thingsboard.server.dao.util.SqlDao;
|
import org.thingsboard.server.dao.util.SqlDao;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ public class JpaNotificationTemplateDao extends JpaAbstractDao<NotificationTempl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int countByTenantIdAndNotificationTypes(TenantId tenantId, List<NotificationType> notificationTypes) {
|
public int countByTenantIdAndNotificationTypes(TenantId tenantId, Collection<NotificationType> notificationTypes) {
|
||||||
return notificationTemplateRepository.countByTenantIdAndNotificationTypes(tenantId.getId(), 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.ExportableEntityRepository;
|
||||||
import org.thingsboard.server.dao.model.sql.NotificationTemplateEntity;
|
import org.thingsboard.server.dao.model.sql.NotificationTemplateEntity;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
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 " +
|
@Query("SELECT count(t) FROM NotificationTemplateEntity t WHERE t.tenantId = :tenantId AND " +
|
||||||
"t.notificationType IN :notificationTypes")
|
"t.notificationType IN :notificationTypes")
|
||||||
int countByTenantIdAndNotificationTypes(@Param("tenantId") UUID tenantId,
|
int countByTenantIdAndNotificationTypes(@Param("tenantId") UUID tenantId,
|
||||||
@Param("notificationTypes") List<NotificationType> notificationTypes);
|
@Param("notificationTypes") Collection<NotificationType> notificationTypes);
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Modifying
|
@Modifying
|
||||||
|
|||||||
@ -18,12 +18,15 @@ package org.thingsboard.rule.engine.api;
|
|||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import org.thingsboard.server.common.data.id.NotificationId;
|
import org.thingsboard.server.common.data.id.NotificationId;
|
||||||
import org.thingsboard.server.common.data.id.NotificationRequestId;
|
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.TenantId;
|
||||||
import org.thingsboard.server.common.data.id.UserId;
|
import org.thingsboard.server.common.data.id.UserId;
|
||||||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
|
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
|
||||||
import org.thingsboard.server.common.data.notification.NotificationRequest;
|
import org.thingsboard.server.common.data.notification.NotificationRequest;
|
||||||
import org.thingsboard.server.common.data.notification.NotificationRequestStats;
|
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.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.targets.platform.UsersFilter;
|
||||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
|
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 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 deleteNotificationRequest(TenantId tenantId, NotificationRequestId notificationRequestId);
|
||||||
|
|
||||||
void markNotificationAsRead(TenantId tenantId, UserId recipientId, NotificationId notificationId);
|
void markNotificationAsRead(TenantId tenantId, UserId recipientId, NotificationId notificationId);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user