|
|
|
@ -17,25 +17,24 @@ package org.thingsboard.server.service.housekeeper; |
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode; |
|
|
|
import com.fasterxml.jackson.databind.node.TextNode; |
|
|
|
import net.bytebuddy.implementation.bytecode.Throw; |
|
|
|
import org.junit.After; |
|
|
|
import org.junit.Before; |
|
|
|
import org.junit.Ignore; |
|
|
|
import org.junit.Test; |
|
|
|
import org.mockito.ArgumentMatcher; |
|
|
|
import org.mockito.Mockito; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.boot.test.mock.mockito.SpyBean; |
|
|
|
import org.springframework.test.context.TestPropertySource; |
|
|
|
import org.testcontainers.shaded.org.apache.commons.lang3.RandomStringUtils; |
|
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
|
import org.thingsboard.rule.engine.metadata.TbGetAttributesNode; |
|
|
|
import org.thingsboard.rule.engine.metadata.TbGetAttributesNodeConfiguration; |
|
|
|
import org.thingsboard.server.common.data.ApiUsageState; |
|
|
|
import org.thingsboard.server.common.data.AttributeScope; |
|
|
|
import org.thingsboard.server.common.data.DataConstants; |
|
|
|
import org.thingsboard.server.common.data.Device; |
|
|
|
import org.thingsboard.server.common.data.EventInfo; |
|
|
|
import org.thingsboard.server.common.data.alarm.Alarm; |
|
|
|
import org.thingsboard.server.common.data.alarm.AlarmQuery; |
|
|
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
|
|
|
import org.thingsboard.server.common.data.alarm.EntityAlarm; |
|
|
|
import org.thingsboard.server.common.data.asset.Asset; |
|
|
|
@ -79,7 +78,6 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService; |
|
|
|
import org.thingsboard.server.dao.usagerecord.ApiUsageStateDao; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos.HousekeeperTaskProto; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos.ToHousekeeperServiceMsg; |
|
|
|
import org.thingsboard.server.service.housekeeper.processor.TelemetryDeletionTaskProcessor; |
|
|
|
import org.thingsboard.server.service.housekeeper.processor.TsHistoryDeletionTaskProcessor; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
@ -156,7 +154,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest { |
|
|
|
|
|
|
|
@Test |
|
|
|
public void whenDeviceIsDeleted_thenCleanUpRelatedData() throws Exception { |
|
|
|
Device device = createDevice("wekfwepf", "wekfwepf"); |
|
|
|
Device device = createDevice("test", "test"); |
|
|
|
createRelatedData(device.getId()); |
|
|
|
|
|
|
|
doDelete("/api/device/" + device.getId()).andExpect(status().isOk()); |
|
|
|
@ -187,7 +185,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest { |
|
|
|
|
|
|
|
@Test |
|
|
|
public void whenUserIsDeleted_thenCleanUpRelatedData() throws Exception { |
|
|
|
Device device = createDevice("vneoruvhwe", "vneoruvhwe"); |
|
|
|
Device device = createDevice("test", "test"); |
|
|
|
UserId userId = customerUserId; |
|
|
|
createRelatedData(userId); |
|
|
|
Alarm alarm = Alarm.builder() |
|
|
|
@ -210,6 +208,20 @@ public class HousekeeperServiceTest extends AbstractControllerTest { |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void whenDeviceIsDeleted_thenDeleteAllAlarms() throws Exception { |
|
|
|
Device device = createDevice("test", "test"); |
|
|
|
for (int i = 1; i <= 1000; i++) { |
|
|
|
createAlarm(device.getId()); |
|
|
|
} |
|
|
|
|
|
|
|
doDelete("/api/device/" + device.getId()).andExpect(status().isOk()); |
|
|
|
|
|
|
|
await().atMost(30, TimeUnit.SECONDS).untilAsserted(() -> { |
|
|
|
verifyNoAlarms(device.getId()); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void whenTenantIsDeleted_thenDeleteAllEntitiesAndCleanUpRelatedData() throws Exception { |
|
|
|
loginDifferentTenant(); |
|
|
|
@ -220,7 +232,7 @@ public class HousekeeperServiceTest extends AbstractControllerTest { |
|
|
|
createRelatedData(differentTenantCustomerId); |
|
|
|
loginDifferentTenant(); |
|
|
|
|
|
|
|
Device device = createDevice("oi324rujoi", "oi324rujoi"); |
|
|
|
Device device = createDevice("test", "test"); |
|
|
|
createRelatedData(device.getId()); |
|
|
|
|
|
|
|
Asset asset = createAsset(); |
|
|
|
@ -258,11 +270,12 @@ public class HousekeeperServiceTest extends AbstractControllerTest { |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@Ignore // FIXME !!!
|
|
|
|
public void whenTaskProcessingFails_thenReprocess() throws Exception { |
|
|
|
TimeoutException error = new TimeoutException("Test timeout"); |
|
|
|
doThrow(error).when(tsHistoryDeletionTaskProcessor).process(any()); |
|
|
|
|
|
|
|
Device device = createDevice("vep9ruv32", "vep9ruv32"); |
|
|
|
Device device = createDevice("test", "test"); |
|
|
|
createRelatedData(device.getId()); |
|
|
|
|
|
|
|
doDelete("/api/device/" + device.getId()).andExpect(status().isOk()); |
|
|
|
@ -286,11 +299,12 @@ public class HousekeeperServiceTest extends AbstractControllerTest { |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@Ignore // FIXME !!!
|
|
|
|
public void whenReprocessingAttemptsExceeded_thenReprocessOnNextStartUp() throws Exception { |
|
|
|
TimeoutException error = new TimeoutException("Test timeout"); |
|
|
|
doThrow(error).when(tsHistoryDeletionTaskProcessor).process(any()); |
|
|
|
|
|
|
|
Device device = createDevice("woeifjiowejf", "woeifjiowejf"); |
|
|
|
Device device = createDevice("test", "test"); |
|
|
|
createRelatedData(device.getId()); |
|
|
|
|
|
|
|
doDelete("/api/device/" + device.getId()).andExpect(status().isOk()); |
|
|
|
@ -332,32 +346,31 @@ public class HousekeeperServiceTest extends AbstractControllerTest { |
|
|
|
|
|
|
|
private void createRelatedData(EntityId entityId) throws Exception { |
|
|
|
createTelemetry(entityId); |
|
|
|
for (AttributeScope scope : List.of(AttributeScope.SERVER_SCOPE, AttributeScope.SHARED_SCOPE, AttributeScope.CLIENT_SCOPE)) { |
|
|
|
for (AttributeScope scope : AttributeScope.values()) { |
|
|
|
createAttribute(entityId, scope, scope + ATTRIBUTE_KEY); |
|
|
|
} |
|
|
|
createEvent(entityId); |
|
|
|
} |
|
|
|
|
|
|
|
private void verifyNoRelatedData(EntityId entityId) throws Exception { |
|
|
|
List<HousekeeperTaskType> expectedTaskTypes = List.of(HousekeeperTaskType.DELETE_TELEMETRY, HousekeeperTaskType.DELETE_ATTRIBUTES, HousekeeperTaskType.DELETE_EVENTS, HousekeeperTaskType.DELETE_ALARMS); |
|
|
|
for (HousekeeperTaskType taskType : expectedTaskTypes) { |
|
|
|
verify(housekeeperClient).submitTask(argThat(task -> task.getTaskType() == taskType && task.getEntityId().equals(entityId))); |
|
|
|
} |
|
|
|
assertThat(entityServiceRegistry.getServiceByEntityType(entityId.getEntityType()).findEntity(tenantId, entityId)).isEmpty(); |
|
|
|
|
|
|
|
assertThat(getLatestTelemetry(entityId)).isNull(); |
|
|
|
assertThat(getTimeseriesHistory(entityId)).isEmpty(); |
|
|
|
for (String scope : List.of(DataConstants.SERVER_SCOPE, DataConstants.SHARED_SCOPE, DataConstants.CLIENT_SCOPE)) { |
|
|
|
for (AttributeScope scope : AttributeScope.values()) { |
|
|
|
assertThat(attributesService.findAll(tenantId, entityId, scope).get()).isEmpty(); |
|
|
|
} |
|
|
|
assertThat(getEvents(entityId)).isEmpty(); |
|
|
|
assertThat(alarmDao.findEntityAlarmRecordsByEntityId(tenantId, entityId)).isEmpty(); |
|
|
|
assertThat(alarmService.findAlarms(tenantId, AlarmQuery.builder().pageLink(new TimePageLink(100)).build()).getData()) |
|
|
|
.filteredOn(alarm -> alarm.getOriginator().equals(entityId)).isEmpty(); |
|
|
|
verifyNoAlarms(entityId); |
|
|
|
assertThat(relationService.findByTo(tenantId, entityId, RelationTypeGroup.COMMON)).isEmpty(); |
|
|
|
assertThat(relationService.findByFrom(tenantId, entityId, RelationTypeGroup.COMMON)).isEmpty(); |
|
|
|
} |
|
|
|
|
|
|
|
private void verifyNoAlarms(EntityId entityId) { |
|
|
|
assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, entityId, new PageLink(1)).getData()).isEmpty(); |
|
|
|
} |
|
|
|
|
|
|
|
private void createAttribute(EntityId entityId, AttributeScope scope, String key) throws Exception { |
|
|
|
attributesService.save(tenantId, entityId, scope, new BaseAttributeKvEntry(System.currentTimeMillis(), new StringDataEntry(key, KV_VALUE))).get(); |
|
|
|
} |
|
|
|
@ -397,8 +410,17 @@ public class HousekeeperServiceTest extends AbstractControllerTest { |
|
|
|
List<EntityAlarm> entityAlarms = alarmDao.findEntityAlarmRecords(tenantId, alarm.getId()); |
|
|
|
assertThat(entityAlarms).anyMatch(entityAlarm -> entityAlarm.getEntityId().equals(deviceId) && entityAlarm.getAlarmType().equals(alarm.getType())); |
|
|
|
assertThat(entityAlarms).anyMatch(entityAlarm -> entityAlarm.getEntityId().equals(propagatedEntityId) && entityAlarm.getAlarmType().equals(alarm.getType())); |
|
|
|
assertThat(alarmService.findAlarms(tenantId, AlarmQuery.builder().pageLink(new TimePageLink(100)).build()).getData()) |
|
|
|
.filteredOn(a -> a.getOriginator().equals(deviceId)).isNotEmpty(); |
|
|
|
assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, deviceId, new PageLink(1)).getData()).isNotEmpty(); |
|
|
|
} |
|
|
|
|
|
|
|
private void createAlarm(DeviceId deviceId) { |
|
|
|
Alarm alarm = doPost("/api/alarm", Alarm.builder() |
|
|
|
.tenantId(tenantId) |
|
|
|
.originator(deviceId) |
|
|
|
.severity(AlarmSeverity.CRITICAL) |
|
|
|
.type("test alarm for " + deviceId + " " + RandomStringUtils.randomAlphabetic(10)) |
|
|
|
.build(), Alarm.class); |
|
|
|
assertThat(alarmService.findAlarmIdsByOriginatorId(tenantId, deviceId, new PageLink(1)).getData()).isNotEmpty(); |
|
|
|
} |
|
|
|
|
|
|
|
private TsKvEntry getLatestTelemetry(EntityId entityId) throws Exception { |
|
|
|
|