Commit afea9585a48697aee2eb1f9068daa72ac190c6d7

Authored by Andrii Shvaika
2 parents 2b1a4379 33f5edb5

Merge branch 'feature/entity-data-query' of github.com:thingsboard/thingsboard i…

…nto feature/entity-data-query
@@ -399,6 +399,14 @@ public abstract class AbstractControllerTest { @@ -399,6 +399,14 @@ public abstract class AbstractControllerTest {
399 return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass); 399 return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass);
400 } 400 }
401 401
  402 + protected <T,R> R doPostWithResponse(String urlTemplate, T content, Class<R> responseClass, String... params) throws Exception {
  403 + return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseClass);
  404 + }
  405 +
  406 + protected <T,R> R doPostWithTypedResponse(String urlTemplate, T content, TypeReference<R> responseType, String... params) throws Exception {
  407 + return readResponse(doPost(urlTemplate, content, params).andExpect(status().isOk()), responseType);
  408 + }
  409 +
402 protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception { 410 protected <T> T doPostAsync(String urlTemplate, T content, Class<T> responseClass, ResultMatcher resultMatcher, String... params) throws Exception {
403 return readResponse(doPostAsync(urlTemplate, content, DEFAULT_TIMEOUT, params).andExpect(resultMatcher), responseClass); 411 return readResponse(doPostAsync(urlTemplate, content, DEFAULT_TIMEOUT, params).andExpect(resultMatcher), responseClass);
404 } 412 }
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.controller;
  17 +
  18 +import com.fasterxml.jackson.core.type.TypeReference;
  19 +import org.junit.After;
  20 +import org.junit.Assert;
  21 +import org.junit.Before;
  22 +import org.junit.Test;
  23 +import org.thingsboard.server.common.data.DataConstants;
  24 +import org.thingsboard.server.common.data.Device;
  25 +import org.thingsboard.server.common.data.EntityType;
  26 +import org.thingsboard.server.common.data.Tenant;
  27 +import org.thingsboard.server.common.data.User;
  28 +import org.thingsboard.server.common.data.id.DeviceId;
  29 +import org.thingsboard.server.common.data.id.EntityId;
  30 +import org.thingsboard.server.common.data.page.PageData;
  31 +import org.thingsboard.server.common.data.query.DeviceTypeFilter;
  32 +import org.thingsboard.server.common.data.query.EntityCountQuery;
  33 +import org.thingsboard.server.common.data.query.EntityData;
  34 +import org.thingsboard.server.common.data.query.EntityDataPageLink;
  35 +import org.thingsboard.server.common.data.query.EntityDataQuery;
  36 +import org.thingsboard.server.common.data.query.EntityDataSortOrder;
  37 +import org.thingsboard.server.common.data.query.EntityKey;
  38 +import org.thingsboard.server.common.data.query.EntityKeyType;
  39 +import org.thingsboard.server.common.data.query.EntityListFilter;
  40 +import org.thingsboard.server.common.data.query.KeyFilter;
  41 +import org.thingsboard.server.common.data.query.NumericFilterPredicate;
  42 +import org.thingsboard.server.common.data.security.Authority;
  43 +
  44 +import java.util.ArrayList;
  45 +import java.util.Collections;
  46 +import java.util.List;
  47 +import java.util.stream.Collectors;
  48 +
  49 +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
  50 +
  51 +public abstract class BaseEntityQueryControllerTest extends AbstractControllerTest {
  52 +
  53 + private Tenant savedTenant;
  54 + private User tenantAdmin;
  55 +
  56 + @Before
  57 + public void beforeTest() throws Exception {
  58 + loginSysAdmin();
  59 +
  60 + Tenant tenant = new Tenant();
  61 + tenant.setTitle("My tenant");
  62 + savedTenant = doPost("/api/tenant", tenant, Tenant.class);
  63 + Assert.assertNotNull(savedTenant);
  64 +
  65 + tenantAdmin = new User();
  66 + tenantAdmin.setAuthority(Authority.TENANT_ADMIN);
  67 + tenantAdmin.setTenantId(savedTenant.getId());
  68 + tenantAdmin.setEmail("tenant2@thingsboard.org");
  69 + tenantAdmin.setFirstName("Joe");
  70 + tenantAdmin.setLastName("Downs");
  71 +
  72 + tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1");
  73 + }
  74 +
  75 + @After
  76 + public void afterTest() throws Exception {
  77 + loginSysAdmin();
  78 +
  79 + doDelete("/api/tenant/" + savedTenant.getId().getId().toString())
  80 + .andExpect(status().isOk());
  81 + }
  82 +
  83 + @Test
  84 + public void testCountEntitiesByQuery() throws Exception {
  85 + List<Device> devices = new ArrayList<>();
  86 + for (int i = 0; i < 97; i++) {
  87 + Device device = new Device();
  88 + device.setName("Device" + i);
  89 + device.setType("default");
  90 + device.setLabel("testLabel" + (int) (Math.random() * 1000));
  91 + devices.add(doPost("/api/device", device, Device.class));
  92 + }
  93 + DeviceTypeFilter filter = new DeviceTypeFilter();
  94 + filter.setDeviceType("default");
  95 + filter.setDeviceNameFilter("");
  96 +
  97 + EntityCountQuery countQuery = new EntityCountQuery(filter);
  98 +
  99 + Long count = doPostWithResponse("/api/entitiesQuery/count", countQuery, Long.class);
  100 + Assert.assertEquals(97, count.longValue());
  101 +
  102 + filter.setDeviceType("unknown");
  103 + count = doPostWithResponse("/api/entitiesQuery/count", countQuery, Long.class);
  104 + Assert.assertEquals(0, count.longValue());
  105 +
  106 + filter.setDeviceType("default");
  107 + filter.setDeviceNameFilter("Device1");
  108 +
  109 + count = doPostWithResponse("/api/entitiesQuery/count", countQuery, Long.class);
  110 + Assert.assertEquals(11, count.longValue());
  111 +
  112 + EntityListFilter entityListFilter = new EntityListFilter();
  113 + entityListFilter.setEntityType(EntityType.DEVICE);
  114 + entityListFilter.setEntityList(devices.stream().map(Device::getId).map(DeviceId::toString).collect(Collectors.toList()));
  115 +
  116 + countQuery = new EntityCountQuery(entityListFilter);
  117 +
  118 + count = doPostWithResponse("/api/entitiesQuery/count", countQuery, Long.class);
  119 + Assert.assertEquals(97, count.longValue());
  120 + }
  121 +
  122 + @Test
  123 + public void testSimpleFindEntityDataByQuery() throws Exception {
  124 + List<Device> devices = new ArrayList<>();
  125 + for (int i = 0; i < 97; i++) {
  126 + Device device = new Device();
  127 + device.setName("Device" + i);
  128 + device.setType("default");
  129 + device.setLabel("testLabel" + (int) (Math.random() * 1000));
  130 + devices.add(doPost("/api/device", device, Device.class));
  131 + }
  132 +
  133 + DeviceTypeFilter filter = new DeviceTypeFilter();
  134 + filter.setDeviceType("default");
  135 + filter.setDeviceNameFilter("");
  136 +
  137 + EntityDataSortOrder sortOrder = new EntityDataSortOrder(
  138 + new EntityKey(EntityKeyType.ENTITY_FIELD, "createdTime"), EntityDataSortOrder.Direction.ASC
  139 + );
  140 + EntityDataPageLink pageLink = new EntityDataPageLink(10, 0, null, sortOrder);
  141 + List<EntityKey> entityFields = Collections.singletonList(new EntityKey(EntityKeyType.ENTITY_FIELD, "name"));
  142 +
  143 + EntityDataQuery query = new EntityDataQuery(filter, pageLink, entityFields, null, null);
  144 +
  145 + PageData<EntityData> data =
  146 + doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {
  147 + });
  148 +
  149 + Assert.assertEquals(97, data.getTotalElements());
  150 + Assert.assertEquals(10, data.getTotalPages());
  151 + Assert.assertTrue(data.hasNext());
  152 + Assert.assertEquals(10, data.getData().size());
  153 +
  154 + List<EntityData> loadedEntities = new ArrayList<>(data.getData());
  155 + while (data.hasNext()) {
  156 + query = query.next();
  157 + data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {
  158 + });
  159 + loadedEntities.addAll(data.getData());
  160 + }
  161 + Assert.assertEquals(97, loadedEntities.size());
  162 +
  163 + List<EntityId> loadedIds = loadedEntities.stream().map(EntityData::getEntityId).collect(Collectors.toList());
  164 + List<EntityId> deviceIds = devices.stream().map(Device::getId).collect(Collectors.toList());
  165 +
  166 + Assert.assertEquals(deviceIds, loadedIds);
  167 +
  168 + List<String> loadedNames = loadedEntities.stream().map(entityData ->
  169 + entityData.getLatest().get(EntityKeyType.ENTITY_FIELD).get("name").getValue()).collect(Collectors.toList());
  170 + List<String> deviceNames = devices.stream().map(Device::getName).collect(Collectors.toList());
  171 +
  172 + Assert.assertEquals(deviceNames, loadedNames);
  173 +
  174 + sortOrder = new EntityDataSortOrder(
  175 + new EntityKey(EntityKeyType.ENTITY_FIELD, "name"), EntityDataSortOrder.Direction.DESC
  176 + );
  177 +
  178 + pageLink = new EntityDataPageLink(10, 0, "device1", sortOrder);
  179 + query = new EntityDataQuery(filter, pageLink, entityFields, null, null);
  180 + data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {
  181 + });
  182 + Assert.assertEquals(11, data.getTotalElements());
  183 + Assert.assertEquals("Device19", data.getData().get(0).getLatest().get(EntityKeyType.ENTITY_FIELD).get("name").getValue());
  184 +
  185 + }
  186 +
  187 + @Test
  188 + public void testFindEntityDataByQueryWithAttributes() throws Exception {
  189 +
  190 + List<Device> devices = new ArrayList<>();
  191 + List<Long> temperatures = new ArrayList<>();
  192 + List<Long> highTemperatures = new ArrayList<>();
  193 + for (int i=0;i<67;i++) {
  194 + Device device = new Device();
  195 + String name = "Device"+i;
  196 + device.setName(name);
  197 + device.setType("default");
  198 + device.setLabel("testLabel"+(int)(Math.random()*1000));
  199 + devices.add(doPost("/api/device?accessToken="+name, device, Device.class));
  200 + long temperature = (long)(Math.random()*100);
  201 + temperatures.add(temperature);
  202 + if (temperature > 45) {
  203 + highTemperatures.add(temperature);
  204 + }
  205 + }
  206 + for (int i=0;i<devices.size();i++) {
  207 + Device device = devices.get(i);
  208 + String payload = "{\"temperature\":"+temperatures.get(i)+"}";
  209 + doPost("/api/plugins/telemetry/"+device.getId()+"/"+ DataConstants.SHARED_SCOPE, payload, String.class, status().isOk());
  210 + }
  211 + Thread.sleep(1000);
  212 +
  213 + DeviceTypeFilter filter = new DeviceTypeFilter();
  214 + filter.setDeviceType("default");
  215 + filter.setDeviceNameFilter("");
  216 +
  217 + EntityDataSortOrder sortOrder = new EntityDataSortOrder(
  218 + new EntityKey(EntityKeyType.ENTITY_FIELD, "createdTime"), EntityDataSortOrder.Direction.ASC
  219 + );
  220 + EntityDataPageLink pageLink = new EntityDataPageLink(10, 0, null, sortOrder);
  221 + List<EntityKey> entityFields = Collections.singletonList(new EntityKey(EntityKeyType.ENTITY_FIELD, "name"));
  222 + List<EntityKey> latestValues = Collections.singletonList(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
  223 +
  224 + EntityDataQuery query = new EntityDataQuery(filter, pageLink, entityFields, latestValues, null);
  225 + PageData<EntityData> data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {
  226 + });
  227 +
  228 + List<EntityData> loadedEntities = new ArrayList<>(data.getData());
  229 + while (data.hasNext()) {
  230 + query = query.next();
  231 + data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {
  232 + });
  233 + loadedEntities.addAll(data.getData());
  234 + }
  235 + Assert.assertEquals(67, loadedEntities.size());
  236 +
  237 + List<String> loadedTemperatures = loadedEntities.stream().map(entityData ->
  238 + entityData.getLatest().get(EntityKeyType.ATTRIBUTE).get("temperature").getValue()).collect(Collectors.toList());
  239 + List<String> deviceTemperatures = temperatures.stream().map(aLong -> Long.toString(aLong)).collect(Collectors.toList());
  240 + Assert.assertEquals(deviceTemperatures, loadedTemperatures);
  241 +
  242 + pageLink = new EntityDataPageLink(10, 0, null, sortOrder);
  243 + KeyFilter highTemperatureFilter = new KeyFilter();
  244 + highTemperatureFilter.setKey(new EntityKey(EntityKeyType.ATTRIBUTE, "temperature"));
  245 + NumericFilterPredicate predicate = new NumericFilterPredicate();
  246 + predicate.setValue(45);
  247 + predicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
  248 + highTemperatureFilter.setPredicate(predicate);
  249 + List<KeyFilter> keyFilters = Collections.singletonList(highTemperatureFilter);
  250 +
  251 + query = new EntityDataQuery(filter, pageLink, entityFields, latestValues, keyFilters);
  252 +
  253 + data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {
  254 + });
  255 + loadedEntities = new ArrayList<>(data.getData());
  256 + while (data.hasNext()) {
  257 + query = query.next();
  258 + data = doPostWithTypedResponse("/api/entitiesQuery/find", query, new TypeReference<PageData<EntityData>>() {
  259 + });
  260 + loadedEntities.addAll(data.getData());
  261 + }
  262 + Assert.assertEquals(highTemperatures.size(), loadedEntities.size());
  263 +
  264 + List<String> loadedHighTemperatures = loadedEntities.stream().map(entityData ->
  265 + entityData.getLatest().get(EntityKeyType.ATTRIBUTE).get("temperature").getValue()).collect(Collectors.toList());
  266 + List<String> deviceHighTemperatures = highTemperatures.stream().map(aLong -> Long.toString(aLong)).collect(Collectors.toList());
  267 +
  268 + Assert.assertEquals(deviceHighTemperatures, loadedHighTemperatures);
  269 +
  270 + }
  271 +}
  1 +/**
  2 + * Copyright © 2016-2020 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.controller.sql;
  17 +
  18 +import org.thingsboard.server.controller.BaseEntityQueryControllerTest;
  19 +import org.thingsboard.server.dao.service.DaoSqlTest;
  20 +
  21 +@DaoSqlTest
  22 +public class EntityQueryControllerSqlTest extends BaseEntityQueryControllerTest {
  23 +}
@@ -20,7 +20,9 @@ import lombok.Getter; @@ -20,7 +20,9 @@ import lombok.Getter;
20 public class EntityCountQuery { 20 public class EntityCountQuery {
21 21
22 @Getter 22 @Getter
23 - private final EntityFilter entityFilter; 23 + private EntityFilter entityFilter;
  24 +
  25 + public EntityCountQuery() {}
24 26
25 public EntityCountQuery(EntityFilter entityFilter) { 27 public EntityCountQuery(EntityFilter entityFilter) {
26 this.entityFilter = entityFilter; 28 this.entityFilter = entityFilter;
@@ -16,15 +16,20 @@ @@ -16,15 +16,20 @@
16 package org.thingsboard.server.common.data.query; 16 package org.thingsboard.server.common.data.query;
17 17
18 import com.fasterxml.jackson.annotation.JsonIgnore; 18 import com.fasterxml.jackson.annotation.JsonIgnore;
  19 +import lombok.AllArgsConstructor;
19 import lombok.Data; 20 import lombok.Data;
20 21
21 @Data 22 @Data
  23 +@AllArgsConstructor
22 public class EntityDataPageLink { 24 public class EntityDataPageLink {
23 25
24 - private final int pageSize;  
25 - private final int page;  
26 - private final String textSearch;  
27 - private final EntityDataSortOrder sortOrder; 26 + private int pageSize;
  27 + private int page;
  28 + private String textSearch;
  29 + private EntityDataSortOrder sortOrder;
  30 +
  31 + public EntityDataPageLink() {
  32 + }
28 33
29 @JsonIgnore 34 @JsonIgnore
30 public EntityDataPageLink nextPageLink() { 35 public EntityDataPageLink nextPageLink() {
@@ -23,13 +23,21 @@ import java.util.List; @@ -23,13 +23,21 @@ import java.util.List;
23 public class EntityDataQuery extends EntityCountQuery { 23 public class EntityDataQuery extends EntityCountQuery {
24 24
25 @Getter 25 @Getter
26 - private final EntityDataPageLink pageLink; 26 + private EntityDataPageLink pageLink;
27 @Getter 27 @Getter
28 - private final List<EntityKey> entityFields; 28 + private List<EntityKey> entityFields;
29 @Getter 29 @Getter
30 - private final List<EntityKey> latestValues; 30 + private List<EntityKey> latestValues;
31 @Getter 31 @Getter
32 - private final List<KeyFilter> keyFilters; 32 + private List<KeyFilter> keyFilters;
  33 +
  34 + public EntityDataQuery() {
  35 + super();
  36 + }
  37 +
  38 + public EntityDataQuery(EntityFilter entityFilter) {
  39 + super(entityFilter);
  40 + }
33 41
34 public EntityDataQuery(EntityFilter entityFilter, 42 public EntityDataQuery(EntityFilter entityFilter,
35 EntityDataPageLink pageLink, 43 EntityDataPageLink pageLink,
@@ -20,8 +20,10 @@ import lombok.Data; @@ -20,8 +20,10 @@ import lombok.Data;
20 @Data 20 @Data
21 public class EntityDataSortOrder { 21 public class EntityDataSortOrder {
22 22
23 - private final EntityKey key;  
24 - private final Direction direction; 23 + private EntityKey key;
  24 + private Direction direction;
  25 +
  26 + public EntityDataSortOrder() {}
25 27
26 public EntityDataSortOrder(EntityKey key) { 28 public EntityDataSortOrder(EntityKey key) {
27 this(key, Direction.ASC); 29 this(key, Direction.ASC);
@@ -15,7 +15,27 @@ @@ -15,7 +15,27 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.query; 16 package org.thingsboard.server.common.data.query;
17 17
  18 +import com.fasterxml.jackson.annotation.JsonIgnore;
  19 +import com.fasterxml.jackson.annotation.JsonSubTypes;
  20 +import com.fasterxml.jackson.annotation.JsonTypeInfo;
  21 +
  22 +@JsonTypeInfo(
  23 + use = JsonTypeInfo.Id.NAME,
  24 + include = JsonTypeInfo.As.PROPERTY,
  25 + property = "type")
  26 +@JsonSubTypes({
  27 + @JsonSubTypes.Type(value = SingleEntityFilter.class, name = "singleEntity"),
  28 + @JsonSubTypes.Type(value = EntityListFilter.class, name = "entityList"),
  29 + @JsonSubTypes.Type(value = EntityNameFilter.class, name = "entityName"),
  30 + @JsonSubTypes.Type(value = AssetTypeFilter.class, name = "assetType"),
  31 + @JsonSubTypes.Type(value = DeviceTypeFilter.class, name = "deviceType"),
  32 + @JsonSubTypes.Type(value = EntityViewTypeFilter.class, name = "entityViewType"),
  33 + @JsonSubTypes.Type(value = RelationsQueryFilter.class, name = "relationsQuery"),
  34 + @JsonSubTypes.Type(value = AssetSearchQueryFilter.class, name = "assetSearchQuery"),
  35 + @JsonSubTypes.Type(value = DeviceSearchQueryFilter.class, name = "deviceSearchQuery"),
  36 + @JsonSubTypes.Type(value = EntityViewSearchQueryFilter.class, name = "entityViewSearchQuery")})
18 public interface EntityFilter { 37 public interface EntityFilter {
19 38
  39 + @JsonIgnore
20 EntityFilterType getType(); 40 EntityFilterType getType();
21 } 41 }
@@ -15,8 +15,22 @@ @@ -15,8 +15,22 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.query; 16 package org.thingsboard.server.common.data.query;
17 17
  18 +import com.fasterxml.jackson.annotation.JsonIgnore;
  19 +import com.fasterxml.jackson.annotation.JsonSubTypes;
  20 +import com.fasterxml.jackson.annotation.JsonTypeInfo;
  21 +
  22 +@JsonTypeInfo(
  23 + use = JsonTypeInfo.Id.NAME,
  24 + include = JsonTypeInfo.As.PROPERTY,
  25 + property = "type")
  26 +@JsonSubTypes({
  27 + @JsonSubTypes.Type(value = StringFilterPredicate.class, name = "STRING"),
  28 + @JsonSubTypes.Type(value = NumericFilterPredicate.class, name = "NUMERIC"),
  29 + @JsonSubTypes.Type(value = BooleanFilterPredicate.class, name = "BOOLEAN"),
  30 + @JsonSubTypes.Type(value = ComplexFilterPredicate.class, name = "COMPLEX")})
18 public interface KeyFilterPredicate { 31 public interface KeyFilterPredicate {
19 32
  33 + @JsonIgnore
20 FilterPredicateType getType(); 34 FilterPredicateType getType();
21 35
22 } 36 }
@@ -67,7 +67,7 @@ public class EntityDataAdapter { @@ -67,7 +67,7 @@ public class EntityDataAdapter {
67 } else { 67 } else {
68 strValue = convertValue(value); 68 strValue = convertValue(value);
69 Object tsObject = row[mapping.getIndex() + 1]; 69 Object tsObject = row[mapping.getIndex() + 1];
70 - ts = Long.parseLong(tsObject.toString()); 70 + ts = tsObject != null ? Long.parseLong(tsObject.toString()) : 0;
71 } 71 }
72 TsValue tsValue = new TsValue(ts, strValue); 72 TsValue tsValue = new TsValue(ts, strValue);
73 latest.computeIfAbsent(entityKey.getType(), entityKeyType -> new HashMap<>()).put(entityKey.getKey(), tsValue); 73 latest.computeIfAbsent(entityKey.getType(), entityKeyType -> new HashMap<>()).put(entityKey.getKey(), tsValue);
@@ -42,7 +42,6 @@ import org.thingsboard.server.common.data.query.EntityData; @@ -42,7 +42,6 @@ import org.thingsboard.server.common.data.query.EntityData;
42 import org.thingsboard.server.common.data.query.EntityDataPageLink; 42 import org.thingsboard.server.common.data.query.EntityDataPageLink;
43 import org.thingsboard.server.common.data.query.EntityDataQuery; 43 import org.thingsboard.server.common.data.query.EntityDataQuery;
44 import org.thingsboard.server.common.data.query.EntityDataSortOrder; 44 import org.thingsboard.server.common.data.query.EntityDataSortOrder;
45 -import org.thingsboard.server.common.data.query.EntityFilter;  
46 import org.thingsboard.server.common.data.query.EntityKey; 45 import org.thingsboard.server.common.data.query.EntityKey;
47 import org.thingsboard.server.common.data.query.EntityKeyType; 46 import org.thingsboard.server.common.data.query.EntityKeyType;
48 import org.thingsboard.server.common.data.query.EntityListFilter; 47 import org.thingsboard.server.common.data.query.EntityListFilter;