Improvements for user notification settings structure
This commit is contained in:
parent
8f780d0bda
commit
ddfdcef858
@ -443,8 +443,7 @@ public class NotificationController extends BaseController {
|
|||||||
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
|
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
|
||||||
public UserNotificationSettings saveUserNotificationSettings(@RequestBody @Valid UserNotificationSettings settings,
|
public UserNotificationSettings saveUserNotificationSettings(@RequestBody @Valid UserNotificationSettings settings,
|
||||||
@AuthenticationPrincipal SecurityUser user) {
|
@AuthenticationPrincipal SecurityUser user) {
|
||||||
notificationSettingsService.saveUserNotificationSettings(user.getTenantId(), user.getId(), settings);
|
return notificationSettingsService.saveUserNotificationSettings(user.getTenantId(), user.getId(), settings);
|
||||||
return settings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/notification/settings/user")
|
@GetMapping("/notification/settings/user")
|
||||||
|
|||||||
@ -242,10 +242,9 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
|
|||||||
ctx.getStats().reportProcessed(deliveryMethod, recipient.getId());
|
ctx.getStats().reportProcessed(deliveryMethod, recipient.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recipient instanceof User && ctx.getRequest().getRuleId() != null) {
|
if (recipient instanceof User) {
|
||||||
UserNotificationSettings settings = notificationSettingsService.getUserNotificationSettings(ctx.getTenantId(), (User) recipient, false);
|
UserNotificationSettings settings = notificationSettingsService.getUserNotificationSettings(ctx.getTenantId(), (User) recipient, false);
|
||||||
Set<NotificationDeliveryMethod> enabledDeliveryMethods = settings.getEnabledDeliveryMethods(ctx.getNotificationType());
|
if (!settings.isEnabled(ctx.getNotificationType(), deliveryMethod)) {
|
||||||
if (!enabledDeliveryMethods.contains(deliveryMethod)) {
|
|
||||||
throw new RuntimeException("User disabled " + deliveryMethod.getName() + " notifications of this type");
|
throw new RuntimeException("User disabled " + deliveryMethod.getName() + " notifications of this type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,7 +62,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -479,15 +478,27 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
|
|||||||
public void testUserNotificationSettings() throws Exception {
|
public void testUserNotificationSettings() throws Exception {
|
||||||
var entityActionNotificationPref = new UserNotificationSettings.NotificationPref();
|
var entityActionNotificationPref = new UserNotificationSettings.NotificationPref();
|
||||||
entityActionNotificationPref.setEnabled(true);
|
entityActionNotificationPref.setEnabled(true);
|
||||||
entityActionNotificationPref.setEnabledDeliveryMethods(Set.of(NotificationDeliveryMethod.WEB));
|
entityActionNotificationPref.setEnabledDeliveryMethods(Map.of(
|
||||||
|
NotificationDeliveryMethod.WEB, true,
|
||||||
|
NotificationDeliveryMethod.SMS, false,
|
||||||
|
NotificationDeliveryMethod.EMAIL, false
|
||||||
|
));
|
||||||
|
|
||||||
var entitiesLimitNotificationPref = new UserNotificationSettings.NotificationPref();
|
var entitiesLimitNotificationPref = new UserNotificationSettings.NotificationPref();
|
||||||
entitiesLimitNotificationPref.setEnabled(true);
|
entitiesLimitNotificationPref.setEnabled(true);
|
||||||
entitiesLimitNotificationPref.setEnabledDeliveryMethods(Set.of(NotificationDeliveryMethod.SMS));
|
entitiesLimitNotificationPref.setEnabledDeliveryMethods(Map.of(
|
||||||
|
NotificationDeliveryMethod.SMS, true,
|
||||||
|
NotificationDeliveryMethod.WEB, false,
|
||||||
|
NotificationDeliveryMethod.EMAIL, false
|
||||||
|
));
|
||||||
|
|
||||||
var apiUsageLimitNotificationPref = new UserNotificationSettings.NotificationPref();
|
var apiUsageLimitNotificationPref = new UserNotificationSettings.NotificationPref();
|
||||||
apiUsageLimitNotificationPref.setEnabled(false);
|
apiUsageLimitNotificationPref.setEnabled(false);
|
||||||
apiUsageLimitNotificationPref.setEnabledDeliveryMethods(Set.of(NotificationDeliveryMethod.WEB));
|
apiUsageLimitNotificationPref.setEnabledDeliveryMethods(Map.of(
|
||||||
|
NotificationDeliveryMethod.WEB, true,
|
||||||
|
NotificationDeliveryMethod.SMS, false,
|
||||||
|
NotificationDeliveryMethod.EMAIL, false
|
||||||
|
));
|
||||||
|
|
||||||
UserNotificationSettings settings = new UserNotificationSettings(Map.of(
|
UserNotificationSettings settings = new UserNotificationSettings(Map.of(
|
||||||
NotificationType.ENTITY_ACTION, entityActionNotificationPref,
|
NotificationType.ENTITY_ACTION, entityActionNotificationPref,
|
||||||
|
|||||||
@ -27,7 +27,7 @@ public interface NotificationSettingsService {
|
|||||||
|
|
||||||
NotificationSettings findNotificationSettings(TenantId tenantId);
|
NotificationSettings findNotificationSettings(TenantId tenantId);
|
||||||
|
|
||||||
void saveUserNotificationSettings(TenantId tenantId, UserId userId, UserNotificationSettings settings);
|
UserNotificationSettings saveUserNotificationSettings(TenantId tenantId, UserId userId, UserNotificationSettings settings);
|
||||||
|
|
||||||
UserNotificationSettings getUserNotificationSettings(TenantId tenantId, User user, boolean format);
|
UserNotificationSettings getUserNotificationSettings(TenantId tenantId, User user, boolean format);
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import javax.validation.constraints.NotNull;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class UserNotificationSettings {
|
public class UserNotificationSettings {
|
||||||
@ -39,39 +40,42 @@ public class UserNotificationSettings {
|
|||||||
|
|
||||||
public static final UserNotificationSettings DEFAULT = new UserNotificationSettings(Collections.emptyMap());
|
public static final UserNotificationSettings DEFAULT = new UserNotificationSettings(Collections.emptyMap());
|
||||||
|
|
||||||
private static final Set<NotificationDeliveryMethod> deliveryMethods = NotificationTargetType.PLATFORM_USERS.getSupportedDeliveryMethods();
|
public static final Set<NotificationDeliveryMethod> deliveryMethods = NotificationTargetType.PLATFORM_USERS.getSupportedDeliveryMethods();
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public UserNotificationSettings(@JsonProperty("prefs") Map<NotificationType, NotificationPref> prefs) {
|
public UserNotificationSettings(@JsonProperty("prefs") Map<NotificationType, NotificationPref> prefs) {
|
||||||
this.prefs = prefs;
|
this.prefs = prefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<NotificationDeliveryMethod> getEnabledDeliveryMethods(NotificationType notificationType) {
|
public boolean isEnabled(NotificationType notificationType, NotificationDeliveryMethod deliveryMethod) {
|
||||||
NotificationPref pref = prefs.get(notificationType);
|
NotificationPref pref = prefs.get(notificationType);
|
||||||
if (pref != null) {
|
if (pref == null) {
|
||||||
return pref.isEnabled() ? pref.getEnabledDeliveryMethods() : Collections.emptySet();
|
return true;
|
||||||
} else {
|
|
||||||
return deliveryMethods;
|
|
||||||
}
|
}
|
||||||
|
if (!pref.isEnabled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return pref.getEnabledDeliveryMethods().getOrDefault(deliveryMethod, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class NotificationPref {
|
public static class NotificationPref {
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
@NotNull
|
@NotNull
|
||||||
private Set<NotificationDeliveryMethod> enabledDeliveryMethods;
|
private Map<NotificationDeliveryMethod, Boolean> enabledDeliveryMethods;
|
||||||
|
|
||||||
public static NotificationPref createDefault() {
|
public static NotificationPref createDefault() {
|
||||||
NotificationPref pref = new NotificationPref();
|
NotificationPref pref = new NotificationPref();
|
||||||
pref.setEnabled(true);
|
pref.setEnabled(true);
|
||||||
pref.setEnabledDeliveryMethods(deliveryMethods);
|
pref.setEnabledDeliveryMethods(deliveryMethods.stream().collect(Collectors.toMap(v -> v, v -> true)));
|
||||||
return pref;
|
return pref;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@AssertTrue(message = "Only email, Web and SMS delivery methods are allowed")
|
@AssertTrue(message = "Only email, Web and SMS delivery methods are allowed")
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return deliveryMethods.containsAll(enabledDeliveryMethods);
|
return enabledDeliveryMethods.entrySet().stream()
|
||||||
|
.allMatch(entry -> deliveryMethods.contains(entry.getKey()) && entry.getValue() != null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,7 @@ import org.thingsboard.server.dao.user.UserService;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -95,12 +96,13 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveUserNotificationSettings(TenantId tenantId, UserId userId, UserNotificationSettings settings) {
|
public UserNotificationSettings saveUserNotificationSettings(TenantId tenantId, UserId userId, UserNotificationSettings settings) {
|
||||||
User user = userService.findUserById(tenantId, userId);
|
User user = userService.findUserById(tenantId, userId);
|
||||||
ObjectNode additionalInfo = (ObjectNode) Optional.ofNullable(user.getAdditionalInfo()).orElseGet(JacksonUtil::newObjectNode);
|
ObjectNode additionalInfo = (ObjectNode) Optional.ofNullable(user.getAdditionalInfo()).orElseGet(JacksonUtil::newObjectNode);
|
||||||
additionalInfo.set(USER_SETTINGS_KEY, JacksonUtil.valueToTree(settings));
|
additionalInfo.set(USER_SETTINGS_KEY, JacksonUtil.valueToTree(settings));
|
||||||
user.setAdditionalInfo(additionalInfo);
|
user.setAdditionalInfo(additionalInfo);
|
||||||
userService.saveUser(user);
|
userService.saveUser(user);
|
||||||
|
return formatUserNotificationSettings(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -108,20 +110,32 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
|
|||||||
UserNotificationSettings settings = Optional.ofNullable(user.getAdditionalInfo().get(USER_SETTINGS_KEY))
|
UserNotificationSettings settings = Optional.ofNullable(user.getAdditionalInfo().get(USER_SETTINGS_KEY))
|
||||||
.filter(not(JsonNode::isNull))
|
.filter(not(JsonNode::isNull))
|
||||||
.map(json -> JacksonUtil.treeToValue(json, UserNotificationSettings.class))
|
.map(json -> JacksonUtil.treeToValue(json, UserNotificationSettings.class))
|
||||||
.orElse(null);
|
.orElse(UserNotificationSettings.DEFAULT);
|
||||||
if (!format) {
|
if (format) {
|
||||||
return Optional.ofNullable(settings).orElse(UserNotificationSettings.DEFAULT);
|
settings = formatUserNotificationSettings(settings);
|
||||||
}
|
}
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserNotificationSettings formatUserNotificationSettings(UserNotificationSettings settings) {
|
||||||
Map<NotificationType, NotificationPref> prefs = new EnumMap<>(NotificationType.class);
|
Map<NotificationType, NotificationPref> prefs = new EnumMap<>(NotificationType.class);
|
||||||
if (settings != null) {
|
if (settings != null) {
|
||||||
prefs.putAll(settings.getPrefs());
|
prefs.putAll(settings.getPrefs());
|
||||||
}
|
}
|
||||||
NotificationPref defaultPref = NotificationPref.createDefault();
|
NotificationPref defaultPref = NotificationPref.createDefault();
|
||||||
for (NotificationType notificationType : NotificationType.values()) {
|
for (NotificationType notificationType : NotificationType.values()) {
|
||||||
prefs.putIfAbsent(notificationType, defaultPref);
|
NotificationPref pref = prefs.get(notificationType);
|
||||||
|
if (pref == null) {
|
||||||
|
prefs.put(notificationType, defaultPref);
|
||||||
|
} else {
|
||||||
|
var enabledDeliveryMethods = new LinkedHashMap<>(pref.getEnabledDeliveryMethods());
|
||||||
|
// in case a new delivery method was added to the platform
|
||||||
|
UserNotificationSettings.deliveryMethods.forEach(deliveryMethod -> {
|
||||||
|
enabledDeliveryMethods.putIfAbsent(deliveryMethod, true);
|
||||||
|
});
|
||||||
|
pref.setEnabledDeliveryMethods(enabledDeliveryMethods);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
prefs.remove(NotificationType.GENERAL);
|
|
||||||
return new UserNotificationSettings(prefs);
|
return new UserNotificationSettings(prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user