From 38c9d5dcd82471ef591c3ee109aa3c39c4c62a94 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Wed, 11 Jan 2023 14:58:18 +0200 Subject: [PATCH] Move delivery methods to notification template; refactoring --- .../main/data/upgrade/3.4.3/schema_update.sql | 2 - .../DefaultNotificationCenter.java | 20 +++++----- ...aultNotificationRuleProcessingService.java | 2 - .../DefaultNotificationSchedulerService.java | 3 +- .../NotificationProcessingContext.java | 11 ++++-- .../channels/EmailNotificationChannel.java | 11 +----- .../channels/SlackNotificationChannel.java | 34 ++++------------- .../AbstractNotificationApiTest.java | 38 ++++++++++++------- .../notification/NotificationApiTest.java | 5 +-- .../NotificationTemplateApiTest.java | 5 +-- .../NotificationDeliveryMethod.java | 2 +- .../notification/NotificationRequest.java | 5 +-- .../data/notification/NotificationType.java | 9 ++--- .../settings/AccountNotificationSettings.java | 15 ++++++++ .../DeliveryMethodNotificationTemplate.java | 17 +++++---- ...ailDeliveryMethodNotificationTemplate.java | 9 +++++ .../template/NotificationTemplate.java | 2 - .../template/NotificationTemplateConfig.java | 5 +-- ...ushDeliveryMethodNotificationTemplate.java | 35 +++++++++++++++++ ...ackDeliveryMethodNotificationTemplate.java | 11 +++++- ...SmsDeliveryMethodNotificationTemplate.java | 31 +++++++++++++++ .../server/dao/model/ModelConstants.java | 3 +- .../model/sql/NotificationRequestEntity.java | 6 --- .../model/sql/NotificationTemplateEntity.java | 6 --- .../main/resources/sql/schema-entities.sql | 2 - .../rule/engine/api/NotificationCenter.java | 3 +- .../notification/TbNotificationNode.java | 1 - .../TbNotificationNodeConfiguration.java | 4 -- 28 files changed, 171 insertions(+), 126 deletions(-) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/notification/template/PushDeliveryMethodNotificationTemplate.java create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/notification/template/SmsDeliveryMethodNotificationTemplate.java diff --git a/application/src/main/data/upgrade/3.4.3/schema_update.sql b/application/src/main/data/upgrade/3.4.3/schema_update.sql index 22d4767900..3efa335102 100644 --- a/application/src/main/data/upgrade/3.4.3/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.3/schema_update.sql @@ -29,7 +29,6 @@ CREATE TABLE IF NOT EXISTS notification_template ( tenant_id UUID NULL CONSTRAINT fk_notification_template_tenant_id REFERENCES tenant(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, notification_type VARCHAR(32) NOT NULL, - notification_subject VARCHAR(255), configuration VARCHAR(10000) NOT NULL ); CREATE INDEX IF NOT EXISTS idx_notification_template_tenant_id_created_time ON notification_template(tenant_id, created_time DESC); @@ -52,7 +51,6 @@ CREATE TABLE IF NOT EXISTS notification_request ( targets VARCHAR(10000) NOT NULL, template_id UUID NOT NULL, info VARCHAR(1000), - delivery_methods VARCHAR(255), additional_config VARCHAR(1000), originator_type VARCHAR(32) NOT NULL, originator_entity_id UUID, 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 8abdf1ff0d..3ad3814043 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 @@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.notification.NotificationType; 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.NotificationTemplate; +import org.thingsboard.server.common.data.notification.template.PushDeliveryMethodNotificationTemplate; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.msg.queue.ServiceType; import org.thingsboard.server.common.msg.queue.TbCallback; @@ -97,7 +98,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple NotificationSettings settings = notificationSettingsService.findNotificationSettings(tenantId); NotificationTemplate notificationTemplate = notificationTemplateService.findNotificationTemplateById(tenantId, notificationRequest.getTemplateId()); - notificationRequest.getDeliveryMethods().forEach(deliveryMethod -> { + notificationTemplate.getConfiguration().getDeliveryMethodsTemplates().keySet().forEach(deliveryMethod -> { if (settings.getDeliveryMethodsConfigs().containsKey(deliveryMethod) && !settings.getDeliveryMethodsConfigs().get(deliveryMethod).isEnabled()) { throw new IllegalArgumentException("Delivery method " + deliveryMethod + " is disabled"); @@ -106,10 +107,6 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple if (!settings.getDeliveryMethodsConfigs().containsKey(deliveryMethod)) { throw new IllegalArgumentException("Slack must be configured in the settings"); } - if (!notificationTemplate.getConfiguration().getTemplates().containsKey(deliveryMethod)) { - throw new IllegalArgumentException("To send notification via Slack, " + - "you need to configure corresponding template"); - } } }); @@ -139,7 +136,7 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple DaoUtil.processBatches(pageLink -> { return notificationTargetService.findRecipientsForNotificationTarget(tenantId, ctx.getCustomerId(), targetId, pageLink); }, 200, recipientsBatch -> { - for (NotificationDeliveryMethod deliveryMethod : savedNotificationRequest.getDeliveryMethods()) { + for (NotificationDeliveryMethod deliveryMethod : ctx.getDeliveryMethods()) { List recipients = recipientsBatch.getData(); log.debug("Sending {} notifications for request {} to recipients batch ({})", deliveryMethod, savedNotificationRequest.getId(), recipients.size()); NotificationChannel notificationChannel = channels.get(deliveryMethod); @@ -168,11 +165,11 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple if (senderId != null) { if (stats.getErrors().isEmpty()) { int sent = stats.getSent().values().stream().mapToInt(AtomicInteger::get).sum(); - sendBasicNotification(tenantId, senderId, NotificationType.COMPLETED, "Notifications sent", + sendBasicNotification(tenantId, senderId, "Notifications sent", "All notifications were successfully sent (" + sent + ")"); } else { int failures = stats.getErrors().values().stream().mapToInt(Map::size).sum(); - sendBasicNotification(tenantId, senderId, NotificationType.FAILURE, "Notification failure", + sendBasicNotification(tenantId, senderId, "Notification failure", "Some notifications were not sent (" + failures + ")"); // TODO: 'Go to request' button } } @@ -211,13 +208,14 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple @Override public ListenableFuture sendNotification(User recipient, String text, NotificationProcessingContext ctx) { + PushDeliveryMethodNotificationTemplate template = ctx.getTemplate(NotificationDeliveryMethod.PUSH); 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(ctx.getNotificationTemplate().getNotificationSubject()) + .subject(template.getSubject()) .text(text) .info(request.getInfo()) .originatorType(request.getOriginatorType()) @@ -238,10 +236,10 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple } @Override - public void sendBasicNotification(TenantId tenantId, UserId recipientId, NotificationType type, String subject, String text) { + public void sendBasicNotification(TenantId tenantId, UserId recipientId, String subject, String text) { Notification notification = Notification.builder() .recipientId(recipientId) - .type(type) + .type(NotificationType.GENERAL) .subject(subject) .text(text) .originatorType(NotificationOriginatorType.SYSTEM) diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationRuleProcessingService.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationRuleProcessingService.java index 0b45a2d5ca..c438052889 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationRuleProcessingService.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationRuleProcessingService.java @@ -47,7 +47,6 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.executors.NotificationExecutorService; import java.util.List; -import java.util.Map; @Service @TbCoreComponent @@ -135,7 +134,6 @@ public class DefaultNotificationRuleProcessingService implements NotificationRul .tenantId(tenantId) .targets(List.of(targetId)) .templateId(notificationRule.getTemplateId()) - .deliveryMethods(notificationRule.getDeliveryMethods()) .additionalConfig(config) .info(notificationInfo) .ruleId(notificationRule.getId()) diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java index fb1192deda..79eda40cdf 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationSchedulerService.java @@ -28,7 +28,6 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.notification.NotificationRequest; import org.thingsboard.server.common.data.notification.NotificationRequestConfig; -import org.thingsboard.server.common.data.notification.NotificationType; import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg; @@ -115,7 +114,7 @@ public class DefaultNotificationSchedulerService extends AbstractPartitionBasedS log.error("Failed to process scheduled notification request {}", notificationRequest.getId(), e); UserId senderId = notificationRequest.getSenderId(); if (senderId != null) { - notificationCenter.sendBasicNotification(tenantId, senderId, NotificationType.FAILURE, "Notification failure", + notificationCenter.sendBasicNotification(tenantId, senderId, "Notification failure", "Failed to process scheduled notification (request " + notificationRequest.getId() + "): " + e.getMessage()); } } 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 d26ff85e9d..ab6ca8f7ea 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 @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.notification.template.NotificationTemp import java.util.HashMap; import java.util.Map; +import java.util.Set; @SuppressWarnings("unchecked") public class NotificationProcessingContext { @@ -49,6 +50,8 @@ public class NotificationProcessingContext { private final NotificationTemplate notificationTemplate; private Map templates; @Getter + private Set deliveryMethods; + @Getter private final NotificationRequestStats stats; @Builder @@ -63,13 +66,13 @@ public class NotificationProcessingContext { public void init() { NotificationTemplateConfig templateConfig = notificationTemplate.getConfiguration(); - templates = templateConfig.getTemplates(); - for (NotificationDeliveryMethod deliveryMethod : request.getDeliveryMethods()) { - DeliveryMethodNotificationTemplate template = templates.get(deliveryMethod); + templates = templateConfig.getDeliveryMethodsTemplates(); + templates.forEach((deliveryMethod, template) -> { if (StringUtils.isEmpty(template.getBody())) { template.setBody(templateConfig.getDefaultTextTemplate()); } - } + }); + deliveryMethods = templates.keySet(); } public T getTemplate(NotificationDeliveryMethod deliveryMethod) { 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 c238476f8f..61da0f8a60 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 @@ -17,7 +17,6 @@ package org.thingsboard.server.service.notification.channels; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.server.common.data.User; @@ -36,16 +35,8 @@ public class EmailNotificationChannel implements NotificationChannel { @Override public ListenableFuture sendNotification(User recipient, String text, NotificationProcessingContext ctx) { EmailDeliveryMethodNotificationTemplate template = ctx.getTemplate(NotificationDeliveryMethod.EMAIL); - String subject = template.getSubject(); - if (StringUtils.isBlank(subject)) { - subject = ctx.getNotificationTemplate().getNotificationSubject(); - } - if (StringUtils.isBlank(subject)) { - subject = ctx.getNotificationTemplate().getNotificationType().getName(); - } - String mailSubject = subject; return executor.submit(() -> { - mailService.sendEmail(recipient.getTenantId(), recipient.getEmail(), mailSubject, text); + mailService.sendEmail(recipient.getTenantId(), recipient.getEmail(), template.getSubject(), text); return null; }); } 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 f25b6d694e..d704494d76 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 @@ -18,14 +18,12 @@ package org.thingsboard.server.service.notification.channels; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import org.thingsboard.rule.engine.api.slack.SlackService; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.notification.AlreadySentException; import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; import org.thingsboard.server.common.data.notification.settings.SlackNotificationDeliveryMethodConfig; -import org.thingsboard.server.common.data.notification.template.SlackConversation; import org.thingsboard.server.common.data.notification.template.SlackDeliveryMethodNotificationTemplate; import org.thingsboard.server.service.executors.ExternalCallExecutorService; import org.thingsboard.server.service.notification.NotificationProcessingContext; @@ -39,33 +37,17 @@ public class SlackNotificationChannel implements NotificationChannel { @Override public ListenableFuture sendNotification(User recipient, String text, 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); - if (StringUtils.isNotEmpty(template.getConversationId())) { // if conversationId is set, we only need to send message once - if (ctx.getStats().contains(NotificationDeliveryMethod.SLACK)) { - return Futures.immediateFailedFuture(new AlreadySentException()); - } else { - return executor.submit(() -> { - slackService.sendMessage(ctx.getTenantId(), config.getBotToken(), template.getConversationId(), text); - return null; - }); - } - } else { - if (StringUtils.isNoneEmpty(recipient.getFirstName(), recipient.getLastName())) { - String username = StringUtils.join(new String[]{recipient.getFirstName(), recipient.getLastName()}, ' '); - return executor.submit(() -> { - SlackConversation conversation = slackService.findConversation(recipient.getTenantId(), config.getBotToken(), SlackConversation.Type.DIRECT, username); - if (conversation == null) { - throw new IllegalArgumentException("Slack user not found for given name '" + username + "'"); - } - slackService.sendMessage(ctx.getTenantId(), config.getBotToken(), conversation.getId(), text); - return null; - }); - } else { - return Futures.immediateFailedFuture(new IllegalArgumentException("Couldn't determine Slack username for the user")); - } - } + return executor.submit(() -> { + slackService.sendMessage(ctx.getTenantId(), config.getBotToken(), template.getConversationId(), text); + return null; + }); } @Override 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 d97fb97825..e3483837d5 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 @@ -38,6 +38,8 @@ import org.thingsboard.server.common.data.notification.template.DeliveryMethodNo 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.notification.template.PushDeliveryMethodNotificationTemplate; +import org.thingsboard.server.common.data.notification.template.SmsDeliveryMethodNotificationTemplate; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; @@ -63,7 +65,7 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest protected MailService mailService; public static final String DEFAULT_NOTIFICATION_SUBJECT = "Just a test"; - public static final NotificationType DEFAULT_NOTIFICATION_TYPE = NotificationType.ADMIN; + public static final NotificationType DEFAULT_NOTIFICATION_TYPE = NotificationType.GENERAL; protected NotificationTarget createNotificationTarget(UserId... usersIds) { NotificationTarget notificationTarget = new NotificationTarget(); @@ -101,7 +103,6 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest .targets(targets) .templateId(notificationTemplate.getId()) .info(notificationInfo) - .deliveryMethods(List.of(deliveryMethods)) .additionalConfig(config) .build(); return doPost("/api/notification/request", notificationRequest, NotificationRequest.class); @@ -113,21 +114,32 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest notificationTemplate.setTenantId(tenantId); notificationTemplate.setName("Notification template for testing"); notificationTemplate.setNotificationType(notificationType); - notificationTemplate.setNotificationSubject(subject); NotificationTemplateConfig config = new NotificationTemplateConfig(); config.setDefaultTextTemplate(text); - config.setTemplates(new HashMap<>()); + config.setDeliveryMethodsTemplates(new HashMap<>()); for (NotificationDeliveryMethod deliveryMethod : deliveryMethods) { - if (deliveryMethod == NotificationDeliveryMethod.EMAIL) { - EmailDeliveryMethodNotificationTemplate emailNotificationTemplate = new EmailDeliveryMethodNotificationTemplate(); - emailNotificationTemplate.setSubject("Hello from test"); - emailNotificationTemplate.setMethod(deliveryMethod); - config.getTemplates().put(deliveryMethod, emailNotificationTemplate); - } else { - DeliveryMethodNotificationTemplate defaultTemplate = new DeliveryMethodNotificationTemplate(); - defaultTemplate.setMethod(deliveryMethod); - config.getTemplates().put(deliveryMethod, defaultTemplate); + DeliveryMethodNotificationTemplate deliveryMethodNotificationTemplate; + switch (deliveryMethod) { + case PUSH: { + PushDeliveryMethodNotificationTemplate template = new PushDeliveryMethodNotificationTemplate(); + template.setSubject(subject); + deliveryMethodNotificationTemplate = template; + break; + } + case EMAIL: { + EmailDeliveryMethodNotificationTemplate template = new EmailDeliveryMethodNotificationTemplate(); + template.setSubject(subject); + deliveryMethodNotificationTemplate = template; + break; + } + case SMS: { + deliveryMethodNotificationTemplate = new SmsDeliveryMethodNotificationTemplate(); + break; + } + default: + throw new IllegalArgumentException("Unsupported delivery method " + deliveryMethod); } + config.getDeliveryMethodsTemplates().put(deliveryMethod, deliveryMethodNotificationTemplate); } notificationTemplate.setConfiguration(config); return doPost("/api/notification/template", notificationTemplate, NotificationTemplate.class); diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java index c91529d232..7aeb83d27f 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationApiTest.java @@ -37,7 +37,6 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.notification.NotificationDao; -import org.thingsboard.server.dao.notification.NotificationRequestDao; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.ws.notification.cmd.UnreadNotificationsCountUpdate; @@ -68,8 +67,6 @@ public class NotificationApiTest extends AbstractNotificationApiTest { @Autowired private NotificationDao notificationDao; @Autowired - private NotificationRequestDao notificationRequestDao; - @Autowired private DbCallbackExecutorService executor; @Before @@ -354,7 +351,7 @@ public class NotificationApiTest extends AbstractNotificationApiTest { @Test public void testNotificationsForALotOfUsers() throws Exception { - int usersCount = 7000; + int usersCount = 5000; List users = new ArrayList<>(); for (int i = 1; i <= usersCount; i++) { 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 aa83c86e55..5069045d04 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 @@ -45,7 +45,6 @@ public class NotificationTemplateApiTest extends AbstractControllerTest { notificationTemplate.setTenantId(tenantId); notificationTemplate.setName(null); notificationTemplate.setNotificationType(null); - notificationTemplate.setNotificationSubject(null); notificationTemplate.setConfiguration(null); String validationError = saveAndGetError(notificationTemplate, status().isBadRequest()); @@ -58,10 +57,9 @@ public class NotificationTemplateApiTest extends AbstractControllerTest { notificationTemplate.setConfiguration(config); config.setDefaultTextTemplate("Default text"); EmailDeliveryMethodNotificationTemplate emailTemplate = new EmailDeliveryMethodNotificationTemplate(); - emailTemplate.setMethod(NotificationDeliveryMethod.EMAIL); emailTemplate.setBody(null); emailTemplate.setSubject(null); - config.setTemplates(Map.of( + config.setDeliveryMethodsTemplates(Map.of( NotificationDeliveryMethod.EMAIL, emailTemplate )); notificationTemplate.setName("