|
|
|
@ -16,10 +16,13 @@ |
|
|
|
package org.thingsboard.server.controller; |
|
|
|
|
|
|
|
import com.fasterxml.jackson.core.type.TypeReference; |
|
|
|
import com.fasterxml.jackson.databind.JsonNode; |
|
|
|
import org.awaitility.Awaitility; |
|
|
|
import org.junit.After; |
|
|
|
import org.junit.Assert; |
|
|
|
import org.junit.Before; |
|
|
|
import org.junit.Test; |
|
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
|
import org.thingsboard.server.common.data.DataConstants; |
|
|
|
import org.thingsboard.server.common.data.Device; |
|
|
|
import org.thingsboard.server.common.data.EntityType; |
|
|
|
@ -29,6 +32,8 @@ import org.thingsboard.server.common.data.id.DeviceId; |
|
|
|
import org.thingsboard.server.common.data.id.EntityId; |
|
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
|
import org.thingsboard.server.common.data.query.DeviceTypeFilter; |
|
|
|
import org.thingsboard.server.common.data.query.DynamicValue; |
|
|
|
import org.thingsboard.server.common.data.query.DynamicValueSourceType; |
|
|
|
import org.thingsboard.server.common.data.query.EntityCountQuery; |
|
|
|
import org.thingsboard.server.common.data.query.EntityData; |
|
|
|
import org.thingsboard.server.common.data.query.EntityDataPageLink; |
|
|
|
@ -41,11 +46,13 @@ import org.thingsboard.server.common.data.query.EntityTypeFilter; |
|
|
|
import org.thingsboard.server.common.data.query.FilterPredicateValue; |
|
|
|
import org.thingsboard.server.common.data.query.KeyFilter; |
|
|
|
import org.thingsboard.server.common.data.query.NumericFilterPredicate; |
|
|
|
import org.thingsboard.server.common.data.query.TsValue; |
|
|
|
import org.thingsboard.server.common.data.security.Authority; |
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.List; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; |
|
|
|
@ -299,6 +306,79 @@ public abstract class BaseEntityQueryControllerTest extends AbstractControllerTe |
|
|
|
List<String> deviceHighTemperatures = highTemperatures.stream().map(aLong -> Long.toString(aLong)).collect(Collectors.toList()); |
|
|
|
|
|
|
|
Assert.assertEquals(deviceHighTemperatures, loadedHighTemperatures); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
public void testFindEntityDataByQueryWithDynamicValue() throws Exception { |
|
|
|
int numOfDevices = 2; |
|
|
|
|
|
|
|
for (int i = 0; i < numOfDevices; i++) { |
|
|
|
Device device = new Device(); |
|
|
|
String name = "Device" + i; |
|
|
|
device.setName(name); |
|
|
|
device.setType("default"); |
|
|
|
device.setLabel("testLabel" + (int) (Math.random() * 1000)); |
|
|
|
|
|
|
|
Device savedDevice1 = doPost("/api/device?accessToken=" + name, device, Device.class); |
|
|
|
JsonNode content = JacksonUtil.toJsonNode("{\"alarmActiveTime\": 1" + i + "}"); |
|
|
|
doPost("/api/plugins/telemetry/" + EntityType.DEVICE.name() + "/" + savedDevice1.getUuidId() + "/SERVER_SCOPE", content) |
|
|
|
.andExpect(status().isOk()); |
|
|
|
} |
|
|
|
JsonNode content = JacksonUtil.toJsonNode("{\"dynamicValue\": 0}"); |
|
|
|
doPost("/api/plugins/telemetry/" + EntityType.TENANT.name() + "/" + tenantId.getId() + "/SERVER_SCOPE", content) |
|
|
|
.andExpect(status().isOk()); |
|
|
|
|
|
|
|
|
|
|
|
DeviceTypeFilter filter = new DeviceTypeFilter(); |
|
|
|
filter.setDeviceType("default"); |
|
|
|
filter.setDeviceNameFilter(""); |
|
|
|
|
|
|
|
KeyFilter highTemperatureFilter = new KeyFilter(); |
|
|
|
highTemperatureFilter.setKey(new EntityKey(EntityKeyType.SERVER_ATTRIBUTE, "alarmActiveTime")); |
|
|
|
NumericFilterPredicate predicate = new NumericFilterPredicate(); |
|
|
|
|
|
|
|
DynamicValue<Double> dynamicValue = |
|
|
|
new DynamicValue<>(DynamicValueSourceType.CURRENT_TENANT, "dynamicValue"); |
|
|
|
FilterPredicateValue<Double> predicateValue = new FilterPredicateValue<>(0.0, null, dynamicValue); |
|
|
|
|
|
|
|
predicate.setValue(predicateValue); |
|
|
|
predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); |
|
|
|
highTemperatureFilter.setPredicate(predicate); |
|
|
|
|
|
|
|
List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter); |
|
|
|
|
|
|
|
|
|
|
|
EntityDataSortOrder sortOrder = new EntityDataSortOrder( |
|
|
|
new EntityKey(EntityKeyType.ENTITY_FIELD, "createdTime"), EntityDataSortOrder.Direction.ASC |
|
|
|
); |
|
|
|
EntityDataPageLink pageLink = new EntityDataPageLink(10, 0, null, sortOrder); |
|
|
|
|
|
|
|
List<EntityKey> entityFields = Collections.singletonList(new EntityKey(EntityKeyType.ENTITY_FIELD, "name")); |
|
|
|
List<EntityKey> latestValues = Collections.singletonList(new EntityKey(EntityKeyType.ATTRIBUTE, "alarmActiveTime")); |
|
|
|
|
|
|
|
EntityDataQuery query = new EntityDataQuery(filter, pageLink, entityFields, latestValues, keyFilters); |
|
|
|
|
|
|
|
Awaitility.await() |
|
|
|
.alias("data by query") |
|
|
|
.atMost(30, TimeUnit.SECONDS) |
|
|
|
.until(() -> { |
|
|
|
var data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {}); |
|
|
|
var loadedEntities = new ArrayList<>(data.getData()); |
|
|
|
return loadedEntities.size() == numOfDevices; |
|
|
|
}); |
|
|
|
|
|
|
|
var data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {}); |
|
|
|
var loadedEntities = new ArrayList<>(data.getData()); |
|
|
|
|
|
|
|
Assert.assertEquals(numOfDevices, loadedEntities.size()); |
|
|
|
|
|
|
|
for (int i = 0; i < numOfDevices; i++) { |
|
|
|
var entity = loadedEntities.get(i); |
|
|
|
String name = entity.getLatest().get(EntityKeyType.ENTITY_FIELD).getOrDefault("name", new TsValue(0, "Invalid")).getValue(); |
|
|
|
String alarmActiveTime = entity.getLatest().get(EntityKeyType.ATTRIBUTE).getOrDefault("alarmActiveTime", new TsValue(0, "-1")).getValue(); |
|
|
|
|
|
|
|
Assert.assertEquals("Device" + i, name); |
|
|
|
Assert.assertEquals("1" + i, alarmActiveTime); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|