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')")
 | 
			
		||||
    public UserNotificationSettings saveUserNotificationSettings(@RequestBody @Valid UserNotificationSettings settings,
 | 
			
		||||
                                                                 @AuthenticationPrincipal SecurityUser user) {
 | 
			
		||||
        notificationSettingsService.saveUserNotificationSettings(user.getTenantId(), user.getId(), settings);
 | 
			
		||||
        return settings;
 | 
			
		||||
        return notificationSettingsService.saveUserNotificationSettings(user.getTenantId(), user.getId(), settings);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/notification/settings/user")
 | 
			
		||||
 | 
			
		||||
@ -242,10 +242,9 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple
 | 
			
		||||
            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);
 | 
			
		||||
            Set<NotificationDeliveryMethod> enabledDeliveryMethods = settings.getEnabledDeliveryMethods(ctx.getNotificationType());
 | 
			
		||||
            if (!enabledDeliveryMethods.contains(deliveryMethod)) {
 | 
			
		||||
            if (!settings.isEnabled(ctx.getNotificationType(), deliveryMethod)) {
 | 
			
		||||
                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.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
@ -479,15 +478,27 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
 | 
			
		||||
    public void testUserNotificationSettings() throws Exception {
 | 
			
		||||
        var entityActionNotificationPref = new UserNotificationSettings.NotificationPref();
 | 
			
		||||
        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();
 | 
			
		||||
        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();
 | 
			
		||||
        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(
 | 
			
		||||
                NotificationType.ENTITY_ACTION, entityActionNotificationPref,
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ public interface NotificationSettingsService {
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@ import javax.validation.constraints.NotNull;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
public class UserNotificationSettings {
 | 
			
		||||
@ -39,39 +40,42 @@ public class UserNotificationSettings {
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    public UserNotificationSettings(@JsonProperty("prefs") Map<NotificationType, NotificationPref> prefs) {
 | 
			
		||||
        this.prefs = prefs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Set<NotificationDeliveryMethod> getEnabledDeliveryMethods(NotificationType notificationType) {
 | 
			
		||||
    public boolean isEnabled(NotificationType notificationType, NotificationDeliveryMethod deliveryMethod) {
 | 
			
		||||
        NotificationPref pref = prefs.get(notificationType);
 | 
			
		||||
        if (pref != null) {
 | 
			
		||||
            return pref.isEnabled() ? pref.getEnabledDeliveryMethods() : Collections.emptySet();
 | 
			
		||||
        } else {
 | 
			
		||||
            return deliveryMethods;
 | 
			
		||||
        if (pref == null) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        if (!pref.isEnabled()) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        return pref.getEnabledDeliveryMethods().getOrDefault(deliveryMethod, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Data
 | 
			
		||||
    public static class NotificationPref {
 | 
			
		||||
        private boolean enabled;
 | 
			
		||||
        @NotNull
 | 
			
		||||
        private Set<NotificationDeliveryMethod> enabledDeliveryMethods;
 | 
			
		||||
        private Map<NotificationDeliveryMethod, Boolean> enabledDeliveryMethods;
 | 
			
		||||
 | 
			
		||||
        public static NotificationPref createDefault() {
 | 
			
		||||
            NotificationPref pref = new NotificationPref();
 | 
			
		||||
            pref.setEnabled(true);
 | 
			
		||||
            pref.setEnabledDeliveryMethods(deliveryMethods);
 | 
			
		||||
            pref.setEnabledDeliveryMethods(deliveryMethods.stream().collect(Collectors.toMap(v -> v, v -> true)));
 | 
			
		||||
            return pref;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @JsonIgnore
 | 
			
		||||
        @AssertTrue(message = "Only email, Web and SMS delivery methods are allowed")
 | 
			
		||||
        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.EnumMap;
 | 
			
		||||
import java.util.LinkedHashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
@ -95,12 +96,13 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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);
 | 
			
		||||
        ObjectNode additionalInfo = (ObjectNode) Optional.ofNullable(user.getAdditionalInfo()).orElseGet(JacksonUtil::newObjectNode);
 | 
			
		||||
        additionalInfo.set(USER_SETTINGS_KEY, JacksonUtil.valueToTree(settings));
 | 
			
		||||
        user.setAdditionalInfo(additionalInfo);
 | 
			
		||||
        userService.saveUser(user);
 | 
			
		||||
        return formatUserNotificationSettings(settings);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -108,20 +110,32 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
 | 
			
		||||
        UserNotificationSettings settings = Optional.ofNullable(user.getAdditionalInfo().get(USER_SETTINGS_KEY))
 | 
			
		||||
                .filter(not(JsonNode::isNull))
 | 
			
		||||
                .map(json -> JacksonUtil.treeToValue(json, UserNotificationSettings.class))
 | 
			
		||||
                .orElse(null);
 | 
			
		||||
        if (!format) {
 | 
			
		||||
            return Optional.ofNullable(settings).orElse(UserNotificationSettings.DEFAULT);
 | 
			
		||||
                .orElse(UserNotificationSettings.DEFAULT);
 | 
			
		||||
        if (format) {
 | 
			
		||||
            settings = formatUserNotificationSettings(settings);
 | 
			
		||||
        }
 | 
			
		||||
        return settings;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private UserNotificationSettings formatUserNotificationSettings(UserNotificationSettings settings) {
 | 
			
		||||
        Map<NotificationType, NotificationPref> prefs = new EnumMap<>(NotificationType.class);
 | 
			
		||||
        if (settings != null) {
 | 
			
		||||
            prefs.putAll(settings.getPrefs());
 | 
			
		||||
        }
 | 
			
		||||
        NotificationPref defaultPref = NotificationPref.createDefault();
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user