Browse Source

Added edgeType and edgeSearchQuery support

pull/3811/head
Volodymyr Babak 6 years ago
parent
commit
056889be97
  1. 32
      common/data/src/main/java/org/thingsboard/server/common/data/query/EdgeSearchQueryFilter.java
  2. 32
      common/data/src/main/java/org/thingsboard/server/common/data/query/EdgeTypeFilter.java
  3. 4
      common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilter.java
  4. 2
      common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilterType.java
  5. 30
      dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java
  6. 88
      dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java

32
common/data/src/main/java/org/thingsboard/server/common/data/query/EdgeSearchQueryFilter.java

@ -0,0 +1,32 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.query;
import lombok.Data;
import java.util.List;
@Data
public class EdgeSearchQueryFilter extends EntitySearchQueryFilter {
@Override
public EntityFilterType getType() {
return EntityFilterType.EDGE_SEARCH_QUERY;
}
private List<String> edgeTypes;
}

32
common/data/src/main/java/org/thingsboard/server/common/data/query/EdgeTypeFilter.java

@ -0,0 +1,32 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.query;
import lombok.Data;
@Data
public class EdgeTypeFilter implements EntityFilter {
@Override
public EntityFilterType getType() {
return EntityFilterType.EDGE_TYPE;
}
private String edgeType;
private String edgeNameFilter;
}

4
common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilter.java

@ -31,12 +31,14 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonSubTypes.Type(value = EntityNameFilter.class, name = "entityName"),
@JsonSubTypes.Type(value = AssetTypeFilter.class, name = "assetType"),
@JsonSubTypes.Type(value = DeviceTypeFilter.class, name = "deviceType"),
@JsonSubTypes.Type(value = EdgeTypeFilter.class, name = "edgeType"),
@JsonSubTypes.Type(value = EntityViewTypeFilter.class, name = "entityViewType"),
@JsonSubTypes.Type(value = ApiUsageStateFilter.class, name = "apiUsageState"),
@JsonSubTypes.Type(value = RelationsQueryFilter.class, name = "relationsQuery"),
@JsonSubTypes.Type(value = AssetSearchQueryFilter.class, name = "assetSearchQuery"),
@JsonSubTypes.Type(value = DeviceSearchQueryFilter.class, name = "deviceSearchQuery"),
@JsonSubTypes.Type(value = EntityViewSearchQueryFilter.class, name = "entityViewSearchQuery")})
@JsonSubTypes.Type(value = EntityViewSearchQueryFilter.class, name = "entityViewSearchQuery"),
@JsonSubTypes.Type(value = EdgeSearchQueryFilter.class, name = "edgeSearchQuery")})
public interface EntityFilter {
@JsonIgnore

2
common/data/src/main/java/org/thingsboard/server/common/data/query/EntityFilterType.java

@ -22,10 +22,12 @@ public enum EntityFilterType {
ASSET_TYPE("assetType"),
DEVICE_TYPE("deviceType"),
ENTITY_VIEW_TYPE("entityViewType"),
EDGE_TYPE("edgeType"),
RELATIONS_QUERY("relationsQuery"),
ASSET_SEARCH_QUERY("assetSearchQuery"),
DEVICE_SEARCH_QUERY("deviceSearchQuery"),
ENTITY_VIEW_SEARCH_QUERY("entityViewSearchQuery"),
EDGE_SEARCH_QUERY("edgeSearchQuery"),
API_USAGE_STATE("apiUsageState");
private final String label;

30
dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java

@ -29,6 +29,8 @@ import org.thingsboard.server.common.data.query.AssetSearchQueryFilter;
import org.thingsboard.server.common.data.query.AssetTypeFilter;
import org.thingsboard.server.common.data.query.DeviceSearchQueryFilter;
import org.thingsboard.server.common.data.query.DeviceTypeFilter;
import org.thingsboard.server.common.data.query.EdgeSearchQueryFilter;
import org.thingsboard.server.common.data.query.EdgeTypeFilter;
import org.thingsboard.server.common.data.query.EntityCountQuery;
import org.thingsboard.server.common.data.query.EntityData;
import org.thingsboard.server.common.data.query.EntityDataPageLink;
@ -111,6 +113,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
" THEN (select customer_id from device where id = entity_id)" +
" WHEN entity.entity_type = 'ENTITY_VIEW'" +
" THEN (select customer_id from entity_view where id = entity_id)" +
" WHEN entity.entity_type = 'EDGE'" +
" THEN (select customer_id from edge where id = entity_id)" +
" END as customer_id";
private static final String SELECT_TENANT_ID = "SELECT CASE" +
" WHEN entity.entity_type = 'TENANT' THEN entity_id" +
@ -126,6 +130,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
" THEN (select tenant_id from device where id = entity_id)" +
" WHEN entity.entity_type = 'ENTITY_VIEW'" +
" THEN (select tenant_id from entity_view where id = entity_id)" +
" WHEN entity.entity_type = 'EDGE'" +
" THEN (select tenant_id from edge where id = entity_id)" +
" END as tenant_id";
private static final String SELECT_CREATED_TIME = " CASE" +
" WHEN entity.entity_type = 'TENANT'" +
@ -142,6 +148,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
" THEN (select created_time from device where id = entity_id)" +
" WHEN entity.entity_type = 'ENTITY_VIEW'" +
" THEN (select created_time from entity_view where id = entity_id)" +
" WHEN entity.entity_type = 'EDGE'" +
" THEN (select created_time from edge where id = entity_id)" +
" END as created_time";
private static final String SELECT_NAME = " CASE" +
" WHEN entity.entity_type = 'TENANT'" +
@ -158,6 +166,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
" THEN (select name from device where id = entity_id)" +
" WHEN entity.entity_type = 'ENTITY_VIEW'" +
" THEN (select name from entity_view where id = entity_id)" +
" WHEN entity.entity_type = 'EDGE'" +
" THEN (select name from edge where id = entity_id)" +
" END as name";
private static final String SELECT_TYPE = " CASE" +
" WHEN entity.entity_type = 'USER'" +
@ -168,6 +178,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
" THEN (select type from device where id = entity_id)" +
" WHEN entity.entity_type = 'ENTITY_VIEW'" +
" THEN (select type from entity_view where id = entity_id)" +
" WHEN entity.entity_type = 'EDGE'" +
" THEN (select type from edge where id = entity_id)" +
" ELSE entity.entity_type END as type";
private static final String SELECT_LABEL = " CASE" +
" WHEN entity.entity_type = 'TENANT'" +
@ -184,6 +196,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
" THEN (select label from device where id = entity_id)" +
" WHEN entity.entity_type = 'ENTITY_VIEW'" +
" THEN (select name from entity_view where id = entity_id)" +
" WHEN entity.entity_type = 'EDGE'" +
" THEN (select label from edge where id = entity_id)" +
" END as label";
private static final String SELECT_ADDITIONAL_INFO = " CASE" +
" WHEN entity.entity_type = 'TENANT'" +
@ -200,6 +214,8 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
" THEN (select additional_info from device where id = entity_id)" +
" WHEN entity.entity_type = 'ENTITY_VIEW'" +
" THEN (select additional_info from entity_view where id = entity_id)" +
" WHEN entity.entity_type = 'EDGE'" +
" THEN (select additional_info from edge where id = entity_id)" +
" END as additional_info";
private static final String SELECT_API_USAGE_STATE = "(select aus.id, aus.created_time, aus.tenant_id, '13814000-1dd2-11b2-8080-808080808080'::uuid as customer_id, " +
@ -214,6 +230,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
entityTableMap.put(EntityType.USER, "tb_user");
entityTableMap.put(EntityType.TENANT, "tenant");
entityTableMap.put(EntityType.API_USAGE_STATE, SELECT_API_USAGE_STATE);
entityTableMap.put(EntityType.EDGE, "edge");
}
public static EntityType[] RELATION_QUERY_ENTITY_TYPES = new EntityType[]{
@ -394,6 +411,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
case DEVICE_SEARCH_QUERY:
case ASSET_SEARCH_QUERY:
case ENTITY_VIEW_SEARCH_QUERY:
case EDGE_SEARCH_QUERY:
return this.defaultPermissionQuery(ctx);
default:
if (ctx.getEntityType() == EntityType.TENANT) {
@ -430,11 +448,13 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
case ASSET_TYPE:
case DEVICE_TYPE:
case ENTITY_VIEW_TYPE:
case EDGE_TYPE:
return this.typeQuery(ctx, entityFilter);
case RELATIONS_QUERY:
case DEVICE_SEARCH_QUERY:
case ASSET_SEARCH_QUERY:
case ENTITY_VIEW_SEARCH_QUERY:
case EDGE_SEARCH_QUERY:
case API_USAGE_STATE:
return "";
default:
@ -455,6 +475,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
case ENTITY_VIEW_SEARCH_QUERY:
EntityViewSearchQueryFilter entityViewQuery = (EntityViewSearchQueryFilter) entityFilter;
return entitySearchQuery(ctx, entityViewQuery, EntityType.ENTITY_VIEW, entityViewQuery.getEntityViewTypes());
case EDGE_SEARCH_QUERY:
EdgeSearchQueryFilter edgeQuery = (EdgeSearchQueryFilter) entityFilter;
return entitySearchQuery(ctx, edgeQuery, EntityType.EDGE, edgeQuery.getEdgeTypes());
default:
return entityTableMap.get(ctx.getEntityType());
}
@ -660,6 +683,10 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
type = ((EntityViewTypeFilter) filter).getEntityViewType();
name = ((EntityViewTypeFilter) filter).getEntityViewNameFilter();
break;
case EDGE_TYPE:
type = ((EdgeTypeFilter) filter).getEdgeType();
name = ((EdgeTypeFilter) filter).getEdgeNameFilter();
break;
default:
throw new RuntimeException("Not supported!");
}
@ -685,6 +712,9 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
case ENTITY_VIEW_TYPE:
case ENTITY_VIEW_SEARCH_QUERY:
return EntityType.ENTITY_VIEW;
case EDGE_TYPE:
case EDGE_SEARCH_QUERY:
return EntityType.EDGE;
case RELATIONS_QUERY:
return ((RelationsQueryFilter) entityFilter).getRootEntity().getEntityType();
case API_USAGE_STATE:

88
dao/src/test/java/org/thingsboard/server/dao/service/BaseEntityServiceTest.java

@ -20,6 +20,8 @@ import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.apache.commons.lang3.RandomStringUtils;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@ -31,6 +33,7 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.kv.*;
import org.thingsboard.server.common.data.page.PageData;
@ -189,7 +192,90 @@ public abstract class BaseEntityServiceTest extends AbstractServiceTest {
Assert.assertEquals(0, count);
}
@Test
public void testCountEdgeEntitiesByQuery() throws InterruptedException {
List<Edge> edges = new ArrayList<>();
for (int i = 0; i < 97; i++) {
Edge edge = createEdge(i, "default");
edges.add(edgeService.saveEdge(edge));
}
EdgeTypeFilter filter = new EdgeTypeFilter();
filter.setEdgeType("default");
filter.setEdgeNameFilter("");
EntityCountQuery countQuery = new EntityCountQuery(filter);
long count = entityService.countEntitiesByQuery(tenantId, new CustomerId(CustomerId.NULL_UUID), countQuery);
Assert.assertEquals(97, count);
filter.setEdgeType("unknown");
count = entityService.countEntitiesByQuery(tenantId, new CustomerId(CustomerId.NULL_UUID), countQuery);
Assert.assertEquals(0, count);
filter.setEdgeType("default");
filter.setEdgeNameFilter("Edge1");
count = entityService.countEntitiesByQuery(tenantId, new CustomerId(CustomerId.NULL_UUID), countQuery);
Assert.assertEquals(11, count);
EntityListFilter entityListFilter = new EntityListFilter();
entityListFilter.setEntityType(EntityType.EDGE);
entityListFilter.setEntityList(edges.stream().map(Edge::getId).map(EdgeId::toString).collect(Collectors.toList()));
countQuery = new EntityCountQuery(entityListFilter);
count = entityService.countEntitiesByQuery(tenantId, new CustomerId(CustomerId.NULL_UUID), countQuery);
Assert.assertEquals(97, count);
edgeService.deleteEdgesByTenantId(tenantId);
count = entityService.countEntitiesByQuery(tenantId, new CustomerId(CustomerId.NULL_UUID), countQuery);
Assert.assertEquals(0, count);
}
@Test
public void testCountHierarchicalEntitiesByEdgeSearchQuery() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Edge edge = createEdge(i, "type" + i);
edge = edgeService.saveEdge(edge);
//TO make sure devices have different created time
Thread.sleep(1);
EntityRelation er = new EntityRelation();
er.setFrom(tenantId);
er.setTo(edge.getId());
er.setType("Manages");
er.setTypeGroup(RelationTypeGroup.COMMON);
relationService.saveRelation(tenantId, er);
}
EdgeSearchQueryFilter filter = new EdgeSearchQueryFilter();
filter.setRootEntity(tenantId);
filter.setDirection(EntitySearchDirection.FROM);
filter.setRelationType("Manages");
EntityCountQuery countQuery = new EntityCountQuery(filter);
long count = entityService.countEntitiesByQuery(tenantId, new CustomerId(CustomerId.NULL_UUID), countQuery);
Assert.assertEquals(5, count);
filter.setEdgeTypes(Arrays.asList("type0", "type1"));
count = entityService.countEntitiesByQuery(tenantId, new CustomerId(CustomerId.NULL_UUID), countQuery);
Assert.assertEquals(2, count);
}
@NotNull
private Edge createEdge(int i, String type) {
Edge edge = new Edge();
edge.setTenantId(tenantId);
edge.setName("Edge" + i);
edge.setType(type);
edge.setLabel("EdgeLabel" + i);
edge.setSecret(RandomStringUtils.randomAlphanumeric(20));
edge.setRoutingKey(RandomStringUtils.randomAlphanumeric(20));
edge.setEdgeLicenseKey(RandomStringUtils.randomAlphanumeric(20));
edge.setCloudEndpoint("http://localhost:8080");
return edge;
}
@Test
public void testHierarchicalFindEntityDataWithAttributesByQuery() throws ExecutionException, InterruptedException {
List<Asset> assets = new ArrayList<>();

Loading…
Cancel
Save