diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java index d95668e50f..7eb78edd57 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java @@ -23,7 +23,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.rule.engine.api.NotificationCenter; -import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.NotificationId; import org.thingsboard.server.common.data.id.NotificationRequestId; @@ -76,8 +75,8 @@ import java.util.stream.Collectors; @Service @Slf4j @RequiredArgsConstructor -@SuppressWarnings("UnstableApiUsage") -public class DefaultNotificationCenter extends AbstractSubscriptionService implements NotificationCenter, NotificationChannel { +@SuppressWarnings({"UnstableApiUsage", "rawtypes"}) +public class DefaultNotificationCenter extends AbstractSubscriptionService implements NotificationCenter, NotificationChannel { private final NotificationTargetService notificationTargetService; private final NotificationRequestService notificationRequestService; @@ -97,7 +96,8 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple NotificationSettings settings = notificationSettingsService.findNotificationSettings(tenantId); NotificationTemplate notificationTemplate = notificationTemplateService.findNotificationTemplateById(tenantId, notificationRequest.getTemplateId()); - notificationTemplate.getConfiguration().getDeliveryMethodsTemplates().keySet().forEach(deliveryMethod -> { + notificationTemplate.getConfiguration().getDeliveryMethodsTemplates().forEach((deliveryMethod, template) -> { + if (!template.isEnabled()) return; if (settings.getDeliveryMethodsConfigs().containsKey(deliveryMethod) && !settings.getDeliveryMethodsConfigs().get(deliveryMethod).isEnabled()) { throw new IllegalArgumentException("Delivery method " + deliveryMethod + " is disabled"); @@ -182,14 +182,13 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple if (ctx.getStats().contains(deliveryMethod, recipient.getId())) { return Futures.immediateFailedFuture(new AlreadySentException()); } - String text; + DeliveryMethodNotificationTemplate processedTemplate; try { - DeliveryMethodNotificationTemplate template = ctx.getTemplate(deliveryMethod); - text = TbNodeUtils.processTemplate(template.getBody(), ctx.createTemplateContext(recipient)); + processedTemplate = ctx.getProcessedTemplate(deliveryMethod, recipient); } catch (Exception e) { return Futures.immediateFailedFuture(e); } - return notificationChannel.sendNotification(recipient, text, ctx); + return notificationChannel.sendNotification(recipient, processedTemplate, ctx); } private void forwardToNotificationSchedulerService(TenantId tenantId, NotificationRequestId notificationRequestId) { @@ -206,16 +205,15 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple } @Override - public ListenableFuture sendNotification(User recipient, String text, NotificationProcessingContext ctx) { - PushDeliveryMethodNotificationTemplate template = ctx.getTemplate(NotificationDeliveryMethod.PUSH); + public ListenableFuture sendNotification(User recipient, PushDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { NotificationRequest request = ctx.getRequest(); log.trace("Creating notification for recipient {} (notification request id: {})", recipient.getId(), request.getId()); Notification notification = Notification.builder() .requestId(request.getId()) .recipientId(recipient.getId()) .type(ctx.getNotificationTemplate().getNotificationType()) - .subject(template.getSubject()) - .text(text) + .subject(processedTemplate.getSubject()) + .text(processedTemplate.getBody()) .info(request.getInfo()) .status(NotificationStatus.SENT) .build(); @@ -281,11 +279,14 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple @Override public void deleteNotificationRequest(TenantId tenantId, NotificationRequestId notificationRequestId) { log.debug("Deleting notification request {}", notificationRequestId); + NotificationRequest notificationRequest = notificationRequestService.findNotificationRequestById(tenantId, notificationRequestId);// TODO: add caching notificationRequestService.deleteNotificationRequestById(tenantId, notificationRequestId); - onNotificationRequestUpdate(tenantId, NotificationRequestUpdate.builder() - .notificationRequestId(notificationRequestId) - .deleted(true) - .build()); + if (notificationRequest.isSent()) { + onNotificationRequestUpdate(tenantId, NotificationRequestUpdate.builder() + .notificationRequestId(notificationRequestId) + .deleted(true) + .build()); + } clusterService.broadcastEntityStateChangeEvent(tenantId, notificationRequestId, ComponentLifecycleEvent.DELETED); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/NotificationProcessingContext.java b/application/src/main/java/org/thingsboard/server/service/notification/NotificationProcessingContext.java index adf0f84a4b..1f054b8938 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/NotificationProcessingContext.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/NotificationProcessingContext.java @@ -19,20 +19,22 @@ import com.google.common.base.Strings; import lombok.Builder; import lombok.Getter; import org.apache.commons.lang3.StringUtils; +import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.notification.info.AlarmOriginatedNotificationInfo; 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.info.RuleNodeOriginatedNotificationInfo; +import org.thingsboard.server.common.data.notification.info.AlarmOriginatedNotificationInfo; 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.template.DeliveryMethodNotificationTemplate; +import org.thingsboard.server.common.data.notification.template.HasSubject; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -48,7 +50,7 @@ public class NotificationProcessingContext { @Getter private final NotificationTemplate notificationTemplate; - private Map templates; + private final Map templates; @Getter private Set deliveryMethods; @Getter @@ -61,29 +63,50 @@ public class NotificationProcessingContext { this.request = request; this.settings = settings; this.notificationTemplate = template; + this.templates = new EnumMap<>(NotificationDeliveryMethod.class); this.stats = new NotificationRequestStats(); } public void init() { NotificationTemplateConfig templateConfig = notificationTemplate.getConfiguration(); - templates = templateConfig.getDeliveryMethodsTemplates(); - templates.forEach((deliveryMethod, template) -> { + templateConfig.getDeliveryMethodsTemplates().forEach((deliveryMethod, template) -> { + if (!template.isEnabled()) return; + + template = template.copy(); if (StringUtils.isEmpty(template.getBody())) { template.setBody(templateConfig.getDefaultTextTemplate()); } + if (template instanceof HasSubject) { + if (StringUtils.isEmpty(((HasSubject) template).getSubject())) { + ((HasSubject) template).setSubject(templateConfig.getNotificationSubject()); + } + } + templates.put(deliveryMethod, template); }); deliveryMethods = templates.keySet(); } - public T getTemplate(NotificationDeliveryMethod deliveryMethod) { - return (T) templates.get(deliveryMethod); - } - public C getDeliveryMethodConfig(NotificationDeliveryMethod deliveryMethod) { return (C) settings.getDeliveryMethodsConfigs().get(deliveryMethod); } - public Map createTemplateContext(User recipient) { + protected T getProcessedTemplate(NotificationDeliveryMethod deliveryMethod, User recipient) { + Map templateContext = createTemplateContext(recipient); + + T template = (T) templates.get(deliveryMethod).copy(); + template.setBody(processTemplate(template.getBody(), templateContext)); + if (template instanceof HasSubject) { + String subject = ((HasSubject) template).getSubject(); + ((HasSubject) template).setSubject(processTemplate(subject, templateContext)); + } + return template; + } + + private String processTemplate(String template, Map context) { + return TbNodeUtils.processTemplate(template, context); + } + + private Map createTemplateContext(User recipient) { Map templateContext = new HashMap<>(); templateContext.put("email", recipient.getEmail()); templateContext.put("firstName", Strings.nullToEmpty(recipient.getFirstName())); diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/EmailNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/EmailNotificationChannel.java index 61da0f8a60..0b10ddfbc8 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/EmailNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/EmailNotificationChannel.java @@ -27,16 +27,15 @@ import org.thingsboard.server.service.notification.NotificationProcessingContext @Component @RequiredArgsConstructor -public class EmailNotificationChannel implements NotificationChannel { +public class EmailNotificationChannel implements NotificationChannel { private final MailService mailService; private final MailExecutorService executor; @Override - public ListenableFuture sendNotification(User recipient, String text, NotificationProcessingContext ctx) { - EmailDeliveryMethodNotificationTemplate template = ctx.getTemplate(NotificationDeliveryMethod.EMAIL); + public ListenableFuture sendNotification(User recipient, EmailDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { return executor.submit(() -> { - mailService.sendEmail(recipient.getTenantId(), recipient.getEmail(), template.getSubject(), text); + mailService.sendEmail(recipient.getTenantId(), recipient.getEmail(), processedTemplate.getSubject(), processedTemplate.getBody()); return null; }); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/NotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/NotificationChannel.java index 85113d3469..f38fe94bdc 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/NotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/NotificationChannel.java @@ -18,11 +18,12 @@ package org.thingsboard.server.service.notification.channels; import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; +import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate; import org.thingsboard.server.service.notification.NotificationProcessingContext; -public interface NotificationChannel { +public interface NotificationChannel { - ListenableFuture sendNotification(User recipient, String text, NotificationProcessingContext ctx); + ListenableFuture sendNotification(User recipient, T processedTemplate, NotificationProcessingContext ctx); NotificationDeliveryMethod getDeliveryMethod(); diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/SlackNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/SlackNotificationChannel.java index d704494d76..2bd6c12785 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/SlackNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/SlackNotificationChannel.java @@ -30,22 +30,20 @@ import org.thingsboard.server.service.notification.NotificationProcessingContext @Component @RequiredArgsConstructor -public class SlackNotificationChannel implements NotificationChannel { +public class SlackNotificationChannel implements NotificationChannel { private final SlackService slackService; private final ExternalCallExecutorService executor; @Override - public ListenableFuture sendNotification(User recipient, String text, NotificationProcessingContext ctx) { + public ListenableFuture sendNotification(User recipient, SlackDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { if (ctx.getStats().contains(NotificationDeliveryMethod.SLACK)) { return Futures.immediateFailedFuture(new AlreadySentException()); } - SlackDeliveryMethodNotificationTemplate template = ctx.getTemplate(NotificationDeliveryMethod.SLACK); SlackNotificationDeliveryMethodConfig config = ctx.getDeliveryMethodConfig(NotificationDeliveryMethod.SLACK); - return executor.submit(() -> { - slackService.sendMessage(ctx.getTenantId(), config.getBotToken(), template.getConversationId(), text); + slackService.sendMessage(ctx.getTenantId(), config.getBotToken(), processedTemplate.getConversationId(), processedTemplate.getBody()); return null; }); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/SmsNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/SmsNotificationChannel.java index 8d155e25f2..8bcbd7bca3 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/SmsNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/SmsNotificationChannel.java @@ -23,22 +23,25 @@ import org.springframework.stereotype.Component; import org.thingsboard.rule.engine.api.SmsService; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; +import org.thingsboard.server.common.data.notification.template.SmsDeliveryMethodNotificationTemplate; import org.thingsboard.server.service.notification.NotificationProcessingContext; import org.thingsboard.server.service.sms.SmsExecutorService; @Component @RequiredArgsConstructor -public class SmsNotificationChannel implements NotificationChannel { +public class SmsNotificationChannel implements NotificationChannel { private final SmsService smsService; private final SmsExecutorService executor; @Override - public ListenableFuture sendNotification(User recipient, String text, NotificationProcessingContext ctx) { + public ListenableFuture sendNotification(User recipient, SmsDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { String phone = recipient.getPhone(); - if (StringUtils.isBlank(phone)) return Futures.immediateFailedFuture(new RuntimeException("User does not have phone number")); + if (StringUtils.isBlank(phone)) + return Futures.immediateFailedFuture(new RuntimeException("User does not have phone number")); + return executor.submit(() -> { - smsService.sendSms(recipient.getTenantId(), recipient.getCustomerId(), new String[]{phone}, text); + smsService.sendSms(recipient.getTenantId(), recipient.getCustomerId(), new String[]{phone}, processedTemplate.getBody()); return null; }); } diff --git a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java index eb2a6b4022..341eca8ef5 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/AbstractNotificationApiTest.java @@ -28,7 +28,6 @@ import org.thingsboard.server.common.data.id.NotificationTargetId; 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.info.NotificationInfo; import org.thingsboard.server.common.data.notification.NotificationRequest; import org.thingsboard.server.common.data.notification.NotificationRequestConfig; import org.thingsboard.server.common.data.notification.NotificationType; @@ -140,6 +139,7 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest default: throw new IllegalArgumentException("Unsupported delivery method " + deliveryMethod); } + deliveryMethodNotificationTemplate.setEnabled(true); config.getDeliveryMethodsTemplates().put(deliveryMethod, deliveryMethodNotificationTemplate); } notificationTemplate.setConfiguration(config); diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationTemplateApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationTemplateApiTest.java index 5069045d04..f121e3f06a 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationTemplateApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationTemplateApiTest.java @@ -56,7 +56,9 @@ public class NotificationTemplateApiTest extends AbstractControllerTest { NotificationTemplateConfig config = new NotificationTemplateConfig(); notificationTemplate.setConfiguration(config); config.setDefaultTextTemplate("Default text"); + config.setNotificationSubject(null); EmailDeliveryMethodNotificationTemplate emailTemplate = new EmailDeliveryMethodNotificationTemplate(); + emailTemplate.setEnabled(true); emailTemplate.setBody(null); emailTemplate.setSubject(null); config.setDeliveryMethodsTemplates(Map.of( @@ -66,15 +68,14 @@ public class NotificationTemplateApiTest extends AbstractControllerTest { validationError = saveAndGetError(notificationTemplate, status().isBadRequest()); assertThat(validationError) - .doesNotContain("defaultTextTemplate must be specified") - .contains("subject must not be") + .contains("notificationSubject must be") .contains("name is malformed"); config.setDefaultTextTemplate(null); validationError = saveAndGetError(notificationTemplate, status().isBadRequest()); assertThat(validationError) - .contains("defaultTextTemplate must be specified"); + .contains("defaultTextTemplate").contains("must be specified"); } private String saveAndGetError(NotificationTemplate notificationTemplate, ResultMatcher statusMatcher) throws Exception { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java index 8c262a144b..67da203907 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java @@ -75,4 +75,9 @@ public class NotificationRequest extends BaseData impleme return originatorEntityId instanceof UserId ? (UserId) originatorEntityId : null; } + @JsonIgnore + public boolean isSent() { + return status == NotificationRequestStatus.SENT; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/DeliveryMethodNotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/DeliveryMethodNotificationTemplate.java index 90a17f17f9..74054db839 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/DeliveryMethodNotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/DeliveryMethodNotificationTemplate.java @@ -15,11 +15,13 @@ */ package org.thingsboard.server.common.data.notification.template; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; import lombok.Data; +import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; @JsonIgnoreProperties(ignoreUnknown = true) @@ -31,10 +33,20 @@ import org.thingsboard.server.common.data.notification.NotificationDeliveryMetho @Type(name = "SLACK", value = SlackDeliveryMethodNotificationTemplate.class) }) @Data +@NoArgsConstructor public abstract class DeliveryMethodNotificationTemplate { + private boolean enabled; private String body; + public DeliveryMethodNotificationTemplate(DeliveryMethodNotificationTemplate other) { + this.enabled = other.enabled; + this.body = other.body; + } + public abstract NotificationDeliveryMethod getMethod(); + @JsonIgnore + public abstract DeliveryMethodNotificationTemplate copy(); + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/EmailDeliveryMethodNotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/EmailDeliveryMethodNotificationTemplate.java index dc2679278e..a043087730 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/EmailDeliveryMethodNotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/EmailDeliveryMethodNotificationTemplate.java @@ -17,20 +17,29 @@ package org.thingsboard.server.common.data.notification.template; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; -import javax.validation.constraints.NotBlank; - @Data +@NoArgsConstructor @EqualsAndHashCode(callSuper = true) -public class EmailDeliveryMethodNotificationTemplate extends DeliveryMethodNotificationTemplate { +public class EmailDeliveryMethodNotificationTemplate extends DeliveryMethodNotificationTemplate implements HasSubject { - @NotBlank private String subject; + public EmailDeliveryMethodNotificationTemplate(EmailDeliveryMethodNotificationTemplate other) { + super(other); + this.subject = other.subject; + } + @Override public NotificationDeliveryMethod getMethod() { return NotificationDeliveryMethod.EMAIL; } + @Override + public EmailDeliveryMethodNotificationTemplate copy() { + return new EmailDeliveryMethodNotificationTemplate(this); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/HasSubject.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/HasSubject.java new file mode 100644 index 0000000000..b61db380c6 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/HasSubject.java @@ -0,0 +1,24 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data.notification.template; + +public interface HasSubject { + + String getSubject(); + + void setSubject(String subject); + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplateConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplateConfig.java index 0aa0619c14..3fc07686d6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplateConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/NotificationTemplateConfig.java @@ -28,19 +28,27 @@ import java.util.Map; @Data public class NotificationTemplateConfig { + private String notificationSubject; private String defaultTextTemplate; @Valid @NotEmpty private Map deliveryMethodsTemplates; @JsonIgnore - @AssertTrue(message = "defaultTextTemplate must be specified if one absent for delivery method") + @AssertTrue(message = "defaultTextTemplate and notificationSubject must be specified if one absent for delivery method") public boolean isValid() { - if (deliveryMethodsTemplates.values().stream().anyMatch(template -> StringUtils.isEmpty(template.getBody()))) { - return StringUtils.isNotEmpty(defaultTextTemplate); - } else { - return true; + for (DeliveryMethodNotificationTemplate template : deliveryMethodsTemplates.values()) { + if (StringUtils.isEmpty(template.getBody()) && StringUtils.isEmpty(defaultTextTemplate)) { + return false; + } + if (template instanceof HasSubject) { + String subject = ((HasSubject) template).getSubject(); + if (StringUtils.isEmpty(subject) && StringUtils.isEmpty(notificationSubject)) { + return false; + } + } } + return true; } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/PushDeliveryMethodNotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/PushDeliveryMethodNotificationTemplate.java index af96599cd7..ad0f261afa 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/PushDeliveryMethodNotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/PushDeliveryMethodNotificationTemplate.java @@ -17,19 +17,33 @@ package org.thingsboard.server.common.data.notification.template; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; @Data +@NoArgsConstructor @EqualsAndHashCode(callSuper = true) -public class PushDeliveryMethodNotificationTemplate extends DeliveryMethodNotificationTemplate { +public class PushDeliveryMethodNotificationTemplate extends DeliveryMethodNotificationTemplate implements HasSubject { private String subject; private String icon; private String actionButtonConfig; + public PushDeliveryMethodNotificationTemplate(PushDeliveryMethodNotificationTemplate other) { + super(other); + this.subject = other.subject; + this.icon = other.icon; + this.actionButtonConfig = other.actionButtonConfig; + } + @Override public NotificationDeliveryMethod getMethod() { return NotificationDeliveryMethod.PUSH; } + @Override + public PushDeliveryMethodNotificationTemplate copy() { + return new PushDeliveryMethodNotificationTemplate(this); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SlackDeliveryMethodNotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SlackDeliveryMethodNotificationTemplate.java index 046834357d..ac5020bf4b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SlackDeliveryMethodNotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SlackDeliveryMethodNotificationTemplate.java @@ -17,11 +17,13 @@ package org.thingsboard.server.common.data.notification.template; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import javax.validation.constraints.NotEmpty; @Data +@NoArgsConstructor @EqualsAndHashCode(callSuper = true) public class SlackDeliveryMethodNotificationTemplate extends DeliveryMethodNotificationTemplate { @@ -29,9 +31,20 @@ public class SlackDeliveryMethodNotificationTemplate extends DeliveryMethodNotif @NotEmpty private String conversationId; + public SlackDeliveryMethodNotificationTemplate(SlackDeliveryMethodNotificationTemplate other) { + super(other); + this.conversationType = other.conversationType; + this.conversationId = other.conversationId; + } + @Override public NotificationDeliveryMethod getMethod() { return NotificationDeliveryMethod.SLACK; } + @Override + public SlackDeliveryMethodNotificationTemplate copy() { + return new SlackDeliveryMethodNotificationTemplate(this); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SmsDeliveryMethodNotificationTemplate.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SmsDeliveryMethodNotificationTemplate.java index 4217dc4f09..7bb937d17f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SmsDeliveryMethodNotificationTemplate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SmsDeliveryMethodNotificationTemplate.java @@ -17,15 +17,26 @@ package org.thingsboard.server.common.data.notification.template; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; @Data +@NoArgsConstructor @EqualsAndHashCode(callSuper = true) public class SmsDeliveryMethodNotificationTemplate extends DeliveryMethodNotificationTemplate { + public SmsDeliveryMethodNotificationTemplate(SmsDeliveryMethodNotificationTemplate other) { + super(other); + } + @Override public NotificationDeliveryMethod getMethod() { return NotificationDeliveryMethod.SMS; } + @Override + public DeliveryMethodNotificationTemplate copy() { + return new SmsDeliveryMethodNotificationTemplate(this); + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java index e9a3d19715..e02c9f80b8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/EntityKeyMapping.java @@ -94,7 +94,7 @@ public class EntityKeyMapping { allowedEntityFieldMap.get(EntityType.TENANT).add(REGION); allowedEntityFieldMap.put(EntityType.CUSTOMER, new HashSet<>(contactBasedEntityFields)); - allowedEntityFieldMap.put(EntityType.USER, new HashSet<>(Arrays.asList(CREATED_TIME, FIRST_NAME, LAST_NAME, EMAIL, ADDITIONAL_INFO))); + allowedEntityFieldMap.put(EntityType.USER, new HashSet<>(Arrays.asList(CREATED_TIME, FIRST_NAME, LAST_NAME, EMAIL, PHONE, ADDITIONAL_INFO))); allowedEntityFieldMap.put(EntityType.DASHBOARD, new HashSet<>(dashboardEntityFields)); allowedEntityFieldMap.put(EntityType.RULE_CHAIN, new HashSet<>(commonEntityFields));