More tests for notification rules; fix unstable tests
This commit is contained in:
parent
64571eeff2
commit
184a554d08
@ -17,6 +17,7 @@ package org.thingsboard.server.service.notification;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.junit.After;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.data.util.Pair;
|
||||
@ -26,6 +27,7 @@ import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.id.NotificationRequestId;
|
||||
import org.thingsboard.server.common.data.id.NotificationTargetId;
|
||||
import org.thingsboard.server.common.data.id.NotificationTemplateId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.id.UUIDBased;
|
||||
import org.thingsboard.server.common.data.id.UserId;
|
||||
import org.thingsboard.server.common.data.notification.Notification;
|
||||
@ -43,6 +45,7 @@ import org.thingsboard.server.common.data.notification.settings.NotificationSett
|
||||
import org.thingsboard.server.common.data.notification.targets.NotificationTarget;
|
||||
import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig;
|
||||
import org.thingsboard.server.common.data.notification.targets.platform.UserListFilter;
|
||||
import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter;
|
||||
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate;
|
||||
import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate;
|
||||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate;
|
||||
@ -54,6 +57,10 @@ import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.security.Authority;
|
||||
import org.thingsboard.server.controller.AbstractControllerTest;
|
||||
import org.thingsboard.server.dao.DaoUtil;
|
||||
import org.thingsboard.server.dao.notification.NotificationRequestService;
|
||||
import org.thingsboard.server.dao.notification.NotificationRuleService;
|
||||
import org.thingsboard.server.dao.notification.NotificationTargetService;
|
||||
import org.thingsboard.server.dao.notification.NotificationTemplateService;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
@ -72,21 +79,40 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
|
||||
|
||||
@MockBean
|
||||
protected SlackService slackService;
|
||||
|
||||
@Autowired
|
||||
protected MailService mailService;
|
||||
|
||||
@Autowired
|
||||
protected NotificationRuleService notificationRuleService;
|
||||
@Autowired
|
||||
protected NotificationTemplateService notificationTemplateService;
|
||||
@Autowired
|
||||
protected NotificationTargetService notificationTargetService;
|
||||
@Autowired
|
||||
protected NotificationRequestService notificationRequestService;
|
||||
|
||||
public static final String DEFAULT_NOTIFICATION_SUBJECT = "Just a test";
|
||||
public static final NotificationType DEFAULT_NOTIFICATION_TYPE = NotificationType.GENERAL;
|
||||
|
||||
@After
|
||||
public void afterEach() {
|
||||
notificationRequestService.deleteNotificationRequestsByTenantId(TenantId.SYS_TENANT_ID);
|
||||
notificationRuleService.deleteNotificationRulesByTenantId(TenantId.SYS_TENANT_ID);
|
||||
notificationTemplateService.deleteNotificationTemplatesByTenantId(TenantId.SYS_TENANT_ID);
|
||||
notificationTargetService.deleteNotificationTargetsByTenantId(TenantId.SYS_TENANT_ID);
|
||||
}
|
||||
|
||||
protected NotificationTarget createNotificationTarget(UserId... usersIds) {
|
||||
NotificationTarget notificationTarget = new NotificationTarget();
|
||||
notificationTarget.setTenantId(tenantId);
|
||||
notificationTarget.setName("Users " + List.of(usersIds));
|
||||
PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig();
|
||||
UserListFilter filter = new UserListFilter();
|
||||
filter.setUsersIds(DaoUtil.toUUIDs(List.of(usersIds)));
|
||||
targetConfig.setUsersFilter(filter);
|
||||
return createNotificationTarget(filter);
|
||||
}
|
||||
|
||||
protected NotificationTarget createNotificationTarget(UsersFilter usersFilter) {
|
||||
NotificationTarget notificationTarget = new NotificationTarget();
|
||||
notificationTarget.setName(usersFilter.toString());
|
||||
PlatformUsersNotificationTargetConfig targetConfig = new PlatformUsersNotificationTargetConfig();
|
||||
targetConfig.setUsersFilter(usersFilter);
|
||||
notificationTarget.setConfiguration(targetConfig);
|
||||
return saveNotificationTarget(notificationTarget);
|
||||
}
|
||||
|
||||
@ -17,12 +17,14 @@ package org.thingsboard.server.service.notification;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.BooleanNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.function.ThrowingRunnable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.server.common.data.DataConstants;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
@ -31,10 +33,15 @@ import org.thingsboard.server.common.data.EntityType;
|
||||
import org.thingsboard.server.common.data.UpdateMessage;
|
||||
import org.thingsboard.server.common.data.User;
|
||||
import org.thingsboard.server.common.data.alarm.Alarm;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmComment;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmCommentType;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
|
||||
import org.thingsboard.server.common.data.alarm.AlarmStatus;
|
||||
import org.thingsboard.server.common.data.asset.Asset;
|
||||
import org.thingsboard.server.common.data.device.data.DefaultDeviceConfiguration;
|
||||
import org.thingsboard.server.common.data.device.data.DefaultDeviceTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.data.DeviceData;
|
||||
import org.thingsboard.server.common.data.device.profile.AlarmCondition;
|
||||
import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter;
|
||||
import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey;
|
||||
@ -42,6 +49,8 @@ import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType;
|
||||
import org.thingsboard.server.common.data.device.profile.AlarmRule;
|
||||
import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm;
|
||||
import org.thingsboard.server.common.data.device.profile.SimpleAlarmConditionSpec;
|
||||
import org.thingsboard.server.common.data.id.AlarmId;
|
||||
import org.thingsboard.server.common.data.id.DeviceId;
|
||||
import org.thingsboard.server.common.data.notification.Notification;
|
||||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
|
||||
import org.thingsboard.server.common.data.notification.NotificationRequest;
|
||||
@ -52,8 +61,11 @@ import org.thingsboard.server.common.data.notification.rule.DefaultNotificationR
|
||||
import org.thingsboard.server.common.data.notification.rule.EscalatedNotificationRuleRecipientsConfig;
|
||||
import org.thingsboard.server.common.data.notification.rule.NotificationRule;
|
||||
import org.thingsboard.server.common.data.notification.rule.NotificationRuleInfo;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmCommentNotificationRuleTriggerConfig;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.AlarmNotificationRuleTriggerConfig.AlarmAction;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.EntitiesLimitNotificationRuleTriggerConfig;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.EntityActionNotificationRuleTriggerConfig;
|
||||
import org.thingsboard.server.common.data.notification.rule.trigger.NewPlatformVersionNotificationRuleTriggerConfig;
|
||||
@ -68,13 +80,16 @@ import org.thingsboard.server.common.data.query.FilterPredicateValue;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||
import org.thingsboard.server.common.data.security.Authority;
|
||||
import org.thingsboard.server.common.msg.notification.NotificationRuleProcessor;
|
||||
import org.thingsboard.server.common.msg.notification.trigger.NewPlatformVersionTrigger;
|
||||
import org.thingsboard.server.dao.notification.DefaultNotifications;
|
||||
import org.thingsboard.server.dao.notification.NotificationRequestService;
|
||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||
import org.thingsboard.server.dao.service.DaoSqlTest;
|
||||
import org.thingsboard.server.dao.util.limits.LimitedApi;
|
||||
import org.thingsboard.server.dao.util.limits.RateLimitService;
|
||||
import org.thingsboard.server.queue.notification.NotificationRuleProcessor;
|
||||
import org.thingsboard.server.service.notification.rule.cache.DefaultNotificationRulesCache;
|
||||
import org.thingsboard.server.service.state.DeviceStateService;
|
||||
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -94,8 +109,15 @@ import static org.assertj.core.api.Assertions.offset;
|
||||
import static org.assertj.core.api.InstanceOfAssertFactories.type;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig.Action.ASSIGNED;
|
||||
import static org.thingsboard.server.common.data.notification.rule.trigger.AlarmAssignmentNotificationRuleTriggerConfig.Action.UNASSIGNED;
|
||||
import static org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent.ACTIVE;
|
||||
import static org.thingsboard.server.common.data.notification.rule.trigger.DeviceActivityNotificationRuleTriggerConfig.DeviceEvent.INACTIVE;
|
||||
|
||||
@DaoSqlTest
|
||||
@TestPropertySource(properties = {
|
||||
"transport.http.enabled=true"
|
||||
})
|
||||
public class NotificationRuleApiTest extends AbstractNotificationApiTest {
|
||||
|
||||
@SpyBean
|
||||
@ -108,6 +130,12 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
|
||||
private RuleChainService ruleChainService;
|
||||
@Autowired
|
||||
private NotificationRuleProcessor notificationRuleProcessor;
|
||||
@Autowired
|
||||
private DefaultNotifications defaultNotifications;
|
||||
@Autowired
|
||||
private DefaultNotificationRulesCache notificationRulesCache;
|
||||
@Autowired
|
||||
private DeviceStateService deviceStateService;
|
||||
|
||||
@Before
|
||||
public void beforeEach() throws Exception {
|
||||
@ -297,7 +325,9 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
|
||||
notification = getWsClient().getLastDataUpdate().getUpdate();
|
||||
assertThat(notification.getSubject()).isEqualTo("critical alarm '" + alarmType + "' is CLEARED_UNACK");
|
||||
|
||||
assertThat(findNotificationRequests(EntityType.ALARM).getData()).filteredOn(NotificationRequest::isScheduled).isEmpty();
|
||||
await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> {
|
||||
assertThat(findNotificationRequests(EntityType.ALARM).getData()).filteredOn(NotificationRequest::isScheduled).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -370,6 +400,122 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationRuleProcessing_alarmAssignment() throws Exception {
|
||||
AlarmAssignmentNotificationRuleTriggerConfig triggerConfig = AlarmAssignmentNotificationRuleTriggerConfig.builder()
|
||||
.alarmTypes(Set.of("test"))
|
||||
.notifyOn(Set.of(ASSIGNED, UNASSIGNED))
|
||||
.build();
|
||||
NotificationTarget target = createNotificationTarget(tenantAdminUserId);
|
||||
String template = "${userEmail} ${action} alarm on ${alarmOriginatorEntityType} '${alarmOriginatorName}'. Assignee: ${assigneeEmail}";
|
||||
createNotificationRule(triggerConfig, "Test", template, target.getId());
|
||||
|
||||
Device device = createDevice("Device A", "123");
|
||||
Alarm alarm = Alarm.builder()
|
||||
.tenantId(tenantId)
|
||||
.originator(device.getId())
|
||||
.cleared(false)
|
||||
.acknowledged(false)
|
||||
.severity(AlarmSeverity.CRITICAL)
|
||||
.type("test")
|
||||
.startTs(System.currentTimeMillis())
|
||||
.build();
|
||||
alarm = doPost("/api/alarm", alarm, Alarm.class);
|
||||
AlarmId alarmId = alarm.getId();
|
||||
|
||||
checkNotificationAfter(() -> {
|
||||
doPost("/api/alarm/" + alarmId + "/assign/" + tenantAdminUserId).andExpect(status().isOk());
|
||||
}, notification -> {
|
||||
assertThat(notification.getText()).isEqualTo(
|
||||
TENANT_ADMIN_EMAIL + " assigned alarm on Device 'Device A'. Assignee: " + TENANT_ADMIN_EMAIL
|
||||
);
|
||||
});
|
||||
|
||||
checkNotificationAfter(() -> {
|
||||
doDelete("/api/alarm/" + alarmId + "/assign").andExpect(status().isOk());
|
||||
}, notification -> {
|
||||
assertThat(notification.getText()).isEqualTo(
|
||||
TENANT_ADMIN_EMAIL + " unassigned alarm on Device 'Device A'. Assignee: "
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationRuleProcessing_alarmComment() throws Exception {
|
||||
AlarmCommentNotificationRuleTriggerConfig triggerConfig = AlarmCommentNotificationRuleTriggerConfig.builder()
|
||||
.alarmTypes(Set.of("test"))
|
||||
.onlyUserComments(true)
|
||||
.notifyOnCommentUpdate(true)
|
||||
.build();
|
||||
NotificationTarget target = createNotificationTarget(tenantAdminUserId);
|
||||
String template = "${userEmail} ${action} comment on alarm ${alarmType}: ${comment}";
|
||||
createNotificationRule(triggerConfig, "Test", template, target.getId());
|
||||
|
||||
Device device = createDevice("Device A", "123");
|
||||
Alarm alarm = Alarm.builder()
|
||||
.tenantId(tenantId)
|
||||
.originator(device.getId())
|
||||
.cleared(false)
|
||||
.acknowledged(false)
|
||||
.severity(AlarmSeverity.CRITICAL)
|
||||
.type("test")
|
||||
.startTs(System.currentTimeMillis())
|
||||
.build();
|
||||
alarm = doPost("/api/alarm", alarm, Alarm.class);
|
||||
AlarmId alarmId = alarm.getId();
|
||||
|
||||
AlarmComment comment = checkNotificationAfter(() -> {
|
||||
return doPost("/api/alarm/" + alarmId + "/comment",
|
||||
AlarmComment.builder()
|
||||
.type(AlarmCommentType.OTHER)
|
||||
.comment(JacksonUtil.newObjectNode()
|
||||
.put("text", "this is bad"))
|
||||
.build(), AlarmComment.class);
|
||||
}, (notification, r) -> {
|
||||
assertThat(notification.getText()).isEqualTo(
|
||||
TENANT_ADMIN_EMAIL + " added comment on alarm test: this is bad"
|
||||
);
|
||||
});
|
||||
|
||||
checkNotificationAfter(() -> {
|
||||
((ObjectNode) comment.getComment()).put("text", "this is very bad");
|
||||
doPost("/api/alarm/" + alarmId + "/comment", comment);
|
||||
}, notification -> {
|
||||
assertThat(notification.getText()).isEqualTo(
|
||||
TENANT_ADMIN_EMAIL + " updated comment on alarm test: this is very bad"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationRuleProcessing_deviceActivity() throws Exception {
|
||||
DeviceActivityNotificationRuleTriggerConfig triggerConfig = DeviceActivityNotificationRuleTriggerConfig.builder()
|
||||
.notifyOn(Set.of(ACTIVE, INACTIVE))
|
||||
.build();
|
||||
NotificationTarget target = createNotificationTarget(tenantAdminUserId);
|
||||
String template = "Device ${deviceName} (${deviceLabel}) of type ${deviceType} is now ${eventType}";
|
||||
createNotificationRule(triggerConfig, "Test", template, target.getId());
|
||||
|
||||
Device device = new Device();
|
||||
device.setName("A");
|
||||
device.setLabel("Test Device A");
|
||||
device.setType("test");
|
||||
DeviceData deviceData = new DeviceData();
|
||||
deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration());
|
||||
deviceData.setConfiguration(new DefaultDeviceConfiguration());
|
||||
device.setDeviceData(deviceData);
|
||||
device = doPost("/api/device", device, Device.class);
|
||||
DeviceId deviceId = device.getId();
|
||||
|
||||
checkNotificationAfter(() -> {
|
||||
deviceStateService.onDeviceActivity(tenantId, deviceId, System.currentTimeMillis());
|
||||
}, notification -> {
|
||||
assertThat(notification.getText()).isEqualTo(
|
||||
"Device A (Test Device A) of type test is now active"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotificationRuleInfo() throws Exception {
|
||||
NotificationDeliveryMethod[] deliveryMethods = {NotificationDeliveryMethod.WEB, NotificationDeliveryMethod.EMAIL};
|
||||
@ -477,6 +623,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
|
||||
triggerConfig.setEntityTypes(Set.of(EntityType.DEVICE));
|
||||
triggerConfig.setCreated(true);
|
||||
NotificationRule rule = createNotificationRule(triggerConfig, "Created", "Created", createNotificationTarget(tenantAdminUserId).getId());
|
||||
notificationRulesCache.evict(tenantId);
|
||||
|
||||
assertThat(getMyNotifications(false, 100)).size().isZero();
|
||||
createDevice("Device 1", "default", "111");
|
||||
@ -487,6 +634,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
|
||||
|
||||
rule.setEnabled(false);
|
||||
saveNotificationRule(rule);
|
||||
notificationRulesCache.evict(tenantId);
|
||||
|
||||
createDevice("Device 2", "default", "222");
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
@ -494,7 +642,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
|
||||
|
||||
rule.setEnabled(true);
|
||||
saveNotificationRule(rule);
|
||||
TimeUnit.SECONDS.sleep(2); // for rule update event to reach rules cache
|
||||
notificationRulesCache.evict(tenantId);
|
||||
|
||||
createDevice("Device 3", "default", "333");
|
||||
await().atMost(30, TimeUnit.SECONDS)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user