Browse Source

User-level notification settings

pull/8819/head
ViacheslavKlimov 3 years ago
parent
commit
014497cd89
  1. 9
      application/src/main/java/org/thingsboard/server/controller/NotificationController.java
  2. 11
      application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java
  3. 7
      common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationSettingsService.java
  4. 6
      common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationDeliveryMethod.java
  5. 64
      common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/UserNotificationSettings.java
  6. 26
      dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java

9
application/src/main/java/org/thingsboard/server/controller/NotificationController.java

@ -44,6 +44,7 @@ import org.thingsboard.server.common.data.notification.NotificationRequest;
import org.thingsboard.server.common.data.notification.NotificationRequestInfo;
import org.thingsboard.server.common.data.notification.NotificationRequestPreview;
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.targets.NotificationRecipient;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.targets.NotificationTargetType;
@ -437,4 +438,12 @@ public class NotificationController extends BaseController {
return notificationCenter.getAvailableDeliveryMethods(user.getTenantId());
}
@PostMapping("/notification/settings/user")
public UserNotificationSettings saveUserNotificationSettings(@RequestBody @Valid UserNotificationSettings settings,
@AuthenticationPrincipal SecurityUser user) {
notificationSettingsService.saveUserNotificationSettings(user.getTenantId(), user.getId(), settings);
return settings;
}
}

11
application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java

@ -37,8 +37,10 @@ import org.thingsboard.server.common.data.notification.NotificationRequestConfig
import org.thingsboard.server.common.data.notification.NotificationRequestStats;
import org.thingsboard.server.common.data.notification.NotificationRequestStatus;
import org.thingsboard.server.common.data.notification.NotificationStatus;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
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.targets.NotificationRecipient;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig;
@ -238,6 +240,15 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
if (ctx.getStats().contains(deliveryMethod, recipient.getId())) {
throw new AlreadySentException();
}
if (recipient instanceof User) {
NotificationType notificationType = ctx.getNotificationTemplate().getNotificationType();
UserNotificationSettings settings = notificationSettingsService.getUserNotificationSettings(ctx.getTenantId(), (User) recipient);
Set<NotificationDeliveryMethod> enabledDeliveryMethods = settings.getEnabledDeliveryMethods(notificationType);
if (!enabledDeliveryMethods.contains(deliveryMethod)) {
throw new RuntimeException("User disabled " + deliveryMethod.getName() + " notifications of this type");
}
}
NotificationChannel notificationChannel = channels.get(deliveryMethod);
DeliveryMethodNotificationTemplate processedTemplate = ctx.getProcessedTemplate(deliveryMethod, recipient);

7
common/dao-api/src/main/java/org/thingsboard/server/dao/notification/NotificationSettingsService.java

@ -15,8 +15,11 @@
*/
package org.thingsboard.server.dao.notification;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
import org.thingsboard.server.common.data.notification.settings.UserNotificationSettings;
public interface NotificationSettingsService {
@ -24,6 +27,10 @@ public interface NotificationSettingsService {
NotificationSettings findNotificationSettings(TenantId tenantId);
void saveUserNotificationSettings(TenantId tenantId, UserId userId, UserNotificationSettings settings);
UserNotificationSettings getUserNotificationSettings(TenantId tenantId, User user);
void createDefaultNotificationConfigs(TenantId tenantId);
void updateDefaultNotificationConfigs(TenantId tenantId);

6
common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationDeliveryMethod.java

@ -18,6 +18,10 @@ package org.thingsboard.server.common.data.notification;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
@RequiredArgsConstructor
public enum NotificationDeliveryMethod {
@ -29,4 +33,6 @@ public enum NotificationDeliveryMethod {
@Getter
private final String name;
public static final Set<NotificationDeliveryMethod> values = Arrays.stream(values()).collect(Collectors.toSet());
}

64
common/data/src/main/java/org/thingsboard/server/common/data/notification/settings/UserNotificationSettings.java

@ -0,0 +1,64 @@
/**
* Copyright © 2016-2023 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.notification.settings;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.util.CollectionsUtil;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
@Data
public class UserNotificationSettings {
private final Map<NotificationType, NotificationTypePrefs> prefs;
@JsonCreator
public UserNotificationSettings(@JsonProperty("prefs") Map<NotificationType, NotificationTypePrefs> prefs) {
this.prefs = prefs;
}
public static final UserNotificationSettings DEFAULT = new UserNotificationSettings(Collections.emptyMap());
public Set<NotificationDeliveryMethod> getEnabledDeliveryMethods(NotificationType notificationType) {
NotificationTypePrefs prefs;
if (this.prefs == null || (prefs = this.prefs.get(notificationType)) == null) {
return NotificationDeliveryMethod.values;
}
if (prefs.isEnabled()) {
Set<NotificationDeliveryMethod> deliveryMethods = prefs.getEnabledDeliveryMethods();
if (CollectionsUtil.isNotEmpty(deliveryMethods)) {
return deliveryMethods;
} else {
return NotificationDeliveryMethod.values;
}
} else {
return Collections.emptySet();
}
}
@Data
public static class NotificationTypePrefs {
private boolean enabled;
private Set<NotificationDeliveryMethod> enabledDeliveryMethods;
}
}

26
dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java

@ -15,6 +15,8 @@
*/
package org.thingsboard.server.dao.notification;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
@ -24,9 +26,12 @@ import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.CacheConstants;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.notification.NotificationType;
import org.thingsboard.server.common.data.notification.settings.NotificationSettings;
import org.thingsboard.server.common.data.notification.settings.UserNotificationSettings;
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
import org.thingsboard.server.common.data.notification.targets.platform.AffectedTenantAdministratorsFilter;
import org.thingsboard.server.common.data.notification.targets.platform.AffectedUserFilter;
@ -39,6 +44,7 @@ import org.thingsboard.server.common.data.notification.targets.platform.UsersFil
import org.thingsboard.server.common.data.notification.targets.platform.UsersFilterType;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.dao.user.UserService;
import java.util.Collections;
import java.util.List;
@ -52,6 +58,7 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
private final NotificationTargetService notificationTargetService;
private final NotificationTemplateService notificationTemplateService;
private final DefaultNotifications defaultNotifications;
private final UserService userService;
private static final String SETTINGS_KEY = "notifications";
@ -81,6 +88,25 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
});
}
@Override
public void saveUserNotificationSettings(TenantId tenantId, UserId userId, UserNotificationSettings settings) {
User user = userService.findUserById(tenantId, userId);
ObjectNode additionalInfo = (ObjectNode) Optional.ofNullable(user.getAdditionalInfo()).orElseGet(JacksonUtil::newObjectNode);
additionalInfo.set("notificationSettings", JacksonUtil.valueToTree(settings));
user.setAdditionalInfo(additionalInfo);
userService.saveUser(user);
}
@Override
public UserNotificationSettings getUserNotificationSettings(TenantId tenantId, User user) {
// TODO: decide whether to use user_settings or store it in the additionalInfo not to make more DB requests
JsonNode notificationSettings = user.getAdditionalInfo().get("notificationSettings");
if (notificationSettings == null || notificationSettings.isNull()) {
return UserNotificationSettings.DEFAULT;
}
return JacksonUtil.treeToValue(notificationSettings, UserNotificationSettings.class);
}
@Transactional(propagation = Propagation.NOT_SUPPORTED) // so that parent transaction is not aborted on method failure
@Override
public void createDefaultNotificationConfigs(TenantId tenantId) {

Loading…
Cancel
Save