|
|
@ -18,18 +18,28 @@ package org.thingsboard.server.dao.service; |
|
|
import com.google.common.collect.Lists; |
|
|
import com.google.common.collect.Lists; |
|
|
import com.google.common.util.concurrent.Futures; |
|
|
import com.google.common.util.concurrent.Futures; |
|
|
import com.google.common.util.concurrent.ListenableFuture; |
|
|
import com.google.common.util.concurrent.ListenableFuture; |
|
|
|
|
|
import lombok.Getter; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
import org.apache.commons.lang3.RandomStringUtils; |
|
|
import org.apache.commons.lang3.RandomUtils; |
|
|
import org.apache.commons.lang3.RandomUtils; |
|
|
import org.hamcrest.Matchers; |
|
|
import org.hamcrest.Matchers; |
|
|
import org.junit.Assert; |
|
|
import org.junit.Assert; |
|
|
|
|
|
import org.junit.Before; |
|
|
import org.junit.Test; |
|
|
import org.junit.Test; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.jdbc.core.ResultSetExtractor; |
|
|
import org.springframework.jdbc.core.ResultSetExtractor; |
|
|
|
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
import org.thingsboard.server.common.data.AttributeScope; |
|
|
import org.thingsboard.server.common.data.AttributeScope; |
|
|
|
|
|
import org.thingsboard.server.common.data.Customer; |
|
|
|
|
|
import org.thingsboard.server.common.data.Dashboard; |
|
|
import org.thingsboard.server.common.data.Device; |
|
|
import org.thingsboard.server.common.data.Device; |
|
|
import org.thingsboard.server.common.data.EntityType; |
|
|
import org.thingsboard.server.common.data.EntityType; |
|
|
|
|
|
import org.thingsboard.server.common.data.EntityView; |
|
|
import org.thingsboard.server.common.data.StringUtils; |
|
|
import org.thingsboard.server.common.data.StringUtils; |
|
|
import org.thingsboard.server.common.data.User; |
|
|
import org.thingsboard.server.common.data.User; |
|
|
|
|
|
import org.thingsboard.server.common.data.alarm.AlarmApiCallResult; |
|
|
|
|
|
import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest; |
|
|
|
|
|
import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
|
|
import org.thingsboard.server.common.data.asset.Asset; |
|
|
import org.thingsboard.server.common.data.asset.Asset; |
|
|
import org.thingsboard.server.common.data.edge.Edge; |
|
|
import org.thingsboard.server.common.data.edge.Edge; |
|
|
import org.thingsboard.server.common.data.id.CustomerId; |
|
|
import org.thingsboard.server.common.data.id.CustomerId; |
|
|
@ -46,6 +56,7 @@ import org.thingsboard.server.common.data.kv.KvEntry; |
|
|
import org.thingsboard.server.common.data.kv.LongDataEntry; |
|
|
import org.thingsboard.server.common.data.kv.LongDataEntry; |
|
|
import org.thingsboard.server.common.data.kv.StringDataEntry; |
|
|
import org.thingsboard.server.common.data.kv.StringDataEntry; |
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
import org.thingsboard.server.common.data.page.PageData; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.ApiUsageStateFilter; |
|
|
import org.thingsboard.server.common.data.query.AssetSearchQueryFilter; |
|
|
import org.thingsboard.server.common.data.query.AssetSearchQueryFilter; |
|
|
import org.thingsboard.server.common.data.query.AssetTypeFilter; |
|
|
import org.thingsboard.server.common.data.query.AssetTypeFilter; |
|
|
import org.thingsboard.server.common.data.query.DeviceSearchQueryFilter; |
|
|
import org.thingsboard.server.common.data.query.DeviceSearchQueryFilter; |
|
|
@ -65,6 +76,7 @@ import org.thingsboard.server.common.data.query.FilterPredicateValue; |
|
|
import org.thingsboard.server.common.data.query.KeyFilter; |
|
|
import org.thingsboard.server.common.data.query.KeyFilter; |
|
|
import org.thingsboard.server.common.data.query.NumericFilterPredicate; |
|
|
import org.thingsboard.server.common.data.query.NumericFilterPredicate; |
|
|
import org.thingsboard.server.common.data.query.RelationsQueryFilter; |
|
|
import org.thingsboard.server.common.data.query.RelationsQueryFilter; |
|
|
|
|
|
import org.thingsboard.server.common.data.query.SingleEntityFilter; |
|
|
import org.thingsboard.server.common.data.query.StringFilterPredicate; |
|
|
import org.thingsboard.server.common.data.query.StringFilterPredicate; |
|
|
import org.thingsboard.server.common.data.query.StringFilterPredicate.StringOperation; |
|
|
import org.thingsboard.server.common.data.query.StringFilterPredicate.StringOperation; |
|
|
import org.thingsboard.server.common.data.relation.EntityRelation; |
|
|
import org.thingsboard.server.common.data.relation.EntityRelation; |
|
|
@ -72,15 +84,20 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection; |
|
|
import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; |
|
|
import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter; |
|
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup; |
|
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup; |
|
|
import org.thingsboard.server.common.data.security.Authority; |
|
|
import org.thingsboard.server.common.data.security.Authority; |
|
|
|
|
|
import org.thingsboard.server.dao.alarm.AlarmService; |
|
|
import org.thingsboard.server.dao.asset.AssetService; |
|
|
import org.thingsboard.server.dao.asset.AssetService; |
|
|
import org.thingsboard.server.dao.attributes.AttributesService; |
|
|
import org.thingsboard.server.dao.attributes.AttributesService; |
|
|
|
|
|
import org.thingsboard.server.dao.customer.CustomerService; |
|
|
|
|
|
import org.thingsboard.server.dao.dashboard.DashboardDao; |
|
|
import org.thingsboard.server.dao.device.DeviceService; |
|
|
import org.thingsboard.server.dao.device.DeviceService; |
|
|
import org.thingsboard.server.dao.edge.EdgeService; |
|
|
import org.thingsboard.server.dao.edge.EdgeService; |
|
|
import org.thingsboard.server.dao.entity.EntityService; |
|
|
import org.thingsboard.server.dao.entity.EntityService; |
|
|
|
|
|
import org.thingsboard.server.dao.entityview.EntityViewDao; |
|
|
import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; |
|
|
import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; |
|
|
import org.thingsboard.server.dao.relation.RelationService; |
|
|
import org.thingsboard.server.dao.relation.RelationService; |
|
|
import org.thingsboard.server.dao.sql.relation.RelationRepository; |
|
|
import org.thingsboard.server.dao.sql.relation.RelationRepository; |
|
|
import org.thingsboard.server.dao.timeseries.TimeseriesService; |
|
|
import org.thingsboard.server.dao.timeseries.TimeseriesService; |
|
|
|
|
|
import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; |
|
|
import org.thingsboard.server.dao.user.UserService; |
|
|
import org.thingsboard.server.dao.user.UserService; |
|
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
import java.util.ArrayList; |
|
|
@ -91,12 +108,13 @@ import java.util.HashMap; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
import java.util.Map; |
|
|
import java.util.Map; |
|
|
import java.util.Random; |
|
|
import java.util.Random; |
|
|
|
|
|
import java.util.Set; |
|
|
import java.util.UUID; |
|
|
import java.util.UUID; |
|
|
import java.util.concurrent.ExecutionException; |
|
|
import java.util.concurrent.ExecutionException; |
|
|
import java.util.stream.Collectors; |
|
|
import java.util.stream.Collectors; |
|
|
import java.util.stream.Stream; |
|
|
import java.util.stream.Stream; |
|
|
|
|
|
|
|
|
import static org.hamcrest.MatcherAssert.assertThat; |
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
import static org.junit.Assert.assertEquals; |
|
|
import static org.junit.Assert.assertEquals; |
|
|
import static org.thingsboard.server.common.data.query.EntityKeyType.ATTRIBUTE; |
|
|
import static org.thingsboard.server.common.data.query.EntityKeyType.ATTRIBUTE; |
|
|
import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD; |
|
|
import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD; |
|
|
@ -106,6 +124,7 @@ import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIEL |
|
|
public class EntityServiceTest extends AbstractServiceTest { |
|
|
public class EntityServiceTest extends AbstractServiceTest { |
|
|
|
|
|
|
|
|
static final int ENTITY_COUNT = 5; |
|
|
static final int ENTITY_COUNT = 5; |
|
|
|
|
|
public static final String TEST_CUSTOMER_NAME = "Test"; |
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
AssetService assetService; |
|
|
AssetService assetService; |
|
|
@ -125,6 +144,27 @@ public class EntityServiceTest extends AbstractServiceTest { |
|
|
RelationService relationService; |
|
|
RelationService relationService; |
|
|
@Autowired |
|
|
@Autowired |
|
|
TimeseriesService timeseriesService; |
|
|
TimeseriesService timeseriesService; |
|
|
|
|
|
@Autowired |
|
|
|
|
|
ApiUsageStateService apiUsageStateService; |
|
|
|
|
|
@Autowired |
|
|
|
|
|
CustomerService customerService; |
|
|
|
|
|
@Autowired |
|
|
|
|
|
DashboardDao dashboardDao; |
|
|
|
|
|
@Autowired |
|
|
|
|
|
EntityViewDao entityViewDao; |
|
|
|
|
|
@Autowired |
|
|
|
|
|
AlarmService alarmService; |
|
|
|
|
|
|
|
|
|
|
|
private CustomerId customerId; |
|
|
|
|
|
|
|
|
|
|
|
@Before |
|
|
|
|
|
public void before() { |
|
|
|
|
|
Customer customer = new Customer(); |
|
|
|
|
|
customer.setTenantId(tenantId); |
|
|
|
|
|
customer.setTitle(TEST_CUSTOMER_NAME); |
|
|
|
|
|
customer = customerService.saveCustomer(customer); |
|
|
|
|
|
customerId = customer.getId(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void testCountEntitiesByQuery() throws InterruptedException { |
|
|
public void testCountEntitiesByQuery() throws InterruptedException { |
|
|
@ -810,7 +850,7 @@ public class EntityServiceTest extends AbstractServiceTest { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void createLoopRelations(TenantId tenantId, String type, EntityId... ids) { |
|
|
void createLoopRelations(TenantId tenantId, String type, EntityId... ids) { |
|
|
assertThat("ids lenght", ids.length, Matchers.greaterThanOrEqualTo(1)); |
|
|
assertThat(ids.length).isGreaterThanOrEqualTo(1); |
|
|
//chain all from the head to the tail
|
|
|
//chain all from the head to the tail
|
|
|
for (int i = 1; i < ids.length; i++) { |
|
|
for (int i = 1; i < ids.length; i++) { |
|
|
relationService.saveRelation(tenantId, new EntityRelation(ids[i - 1], ids[i], type, RelationTypeGroup.COMMON)); |
|
|
relationService.saveRelation(tenantId, new EntityRelation(ids[i - 1], ids[i], type, RelationTypeGroup.COMMON)); |
|
|
@ -1179,6 +1219,117 @@ public class EntityServiceTest extends AbstractServiceTest { |
|
|
assertEquals(0, result.getTotalElements()); |
|
|
assertEquals(0, result.getTotalElements()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void testFindEntitiesBySingleEntityFilter() { |
|
|
|
|
|
List<Device> devices = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++) { |
|
|
|
|
|
Device device = new Device(); |
|
|
|
|
|
device.setTenantId(tenantId); |
|
|
|
|
|
device.setName("Device test" + i); |
|
|
|
|
|
device.setType("default"); |
|
|
|
|
|
devices.add(deviceService.saveDevice(device)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
SingleEntityFilter singleEntityFilter = new SingleEntityFilter(); |
|
|
|
|
|
singleEntityFilter.setSingleEntity(devices.get(0).getId()); |
|
|
|
|
|
|
|
|
|
|
|
List<EntityKey> entityFields = List.of( |
|
|
|
|
|
new EntityKey(EntityKeyType.ENTITY_FIELD, "name") |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
EntityDataPageLink pageLink = new EntityDataPageLink(1000, 0, null, null); |
|
|
|
|
|
|
|
|
|
|
|
EntityDataQuery query = new EntityDataQuery(singleEntityFilter, pageLink, entityFields, null, null); |
|
|
|
|
|
|
|
|
|
|
|
PageData<EntityData> result = searchEntities(query); |
|
|
|
|
|
assertEquals(1, result.getTotalElements()); |
|
|
|
|
|
|
|
|
|
|
|
String deviceName = result.getData().get(0).getLatest().get(EntityKeyType.ENTITY_FIELD).get("name").getValue(); |
|
|
|
|
|
assertThat(deviceName).isEqualTo(devices.get(0).getName()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void testFindEntitiesByApiUsageStateFilter() { |
|
|
|
|
|
apiUsageStateService.createDefaultApiUsageState(tenantId, customerId); |
|
|
|
|
|
ApiUsageStateFilter apiUsageStateFilter = new ApiUsageStateFilter(); |
|
|
|
|
|
apiUsageStateFilter.setCustomerId(customerId); |
|
|
|
|
|
|
|
|
|
|
|
List<EntityKey> entityFields = List.of( |
|
|
|
|
|
new EntityKey(EntityKeyType.ENTITY_FIELD, "name") |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
EntityDataPageLink pageLink = new EntityDataPageLink(1000, 0, null, null); |
|
|
|
|
|
EntityDataQuery query = new EntityDataQuery(apiUsageStateFilter, pageLink, entityFields, null, null); |
|
|
|
|
|
PageData<EntityData> result = searchEntities(query); |
|
|
|
|
|
assertEquals(1, result.getTotalElements()); |
|
|
|
|
|
String name = result.getData().get(0).getLatest().get(EntityKeyType.ENTITY_FIELD).get("name").getValue(); |
|
|
|
|
|
assertThat(name).isEqualTo(TEST_CUSTOMER_NAME); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
public void testFindEntitiesByRelationEntityTypeFilter() { |
|
|
|
|
|
Customer customer = new Customer(); |
|
|
|
|
|
customer.setTenantId(tenantId); |
|
|
|
|
|
customer.setTitle("Customer Relation Query"); |
|
|
|
|
|
customer = customerService.saveCustomer(customer); |
|
|
|
|
|
|
|
|
|
|
|
final int assetCount = 2; |
|
|
|
|
|
final int relationsCnt = 4; |
|
|
|
|
|
final int deviceEntitiesCnt = assetCount * relationsCnt; |
|
|
|
|
|
|
|
|
|
|
|
List<Asset> assets = new ArrayList<>(); |
|
|
|
|
|
for (int i = 0; i < assetCount; i++) { |
|
|
|
|
|
Asset building = new Asset(); |
|
|
|
|
|
building.setTenantId(tenantId); |
|
|
|
|
|
building.setCustomerId(customer.getId()); |
|
|
|
|
|
building.setName("Building _" + i); |
|
|
|
|
|
building.setType("building"); |
|
|
|
|
|
building = assetService.saveAsset(building); |
|
|
|
|
|
assets.add(building); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
List<Device> devices = new ArrayList<>(); |
|
|
|
|
|
for (int i = 0; i < deviceEntitiesCnt; i++) { |
|
|
|
|
|
Device device = new Device(); |
|
|
|
|
|
device.setTenantId(tenantId); |
|
|
|
|
|
device.setCustomerId(customer.getId()); |
|
|
|
|
|
device.setName("Test device " + i); |
|
|
|
|
|
device.setType("default"); |
|
|
|
|
|
Device savedDevice = deviceService.saveDevice(device); |
|
|
|
|
|
devices.add(savedDevice); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < assetCount; i++) { |
|
|
|
|
|
for (int j = 0; j < relationsCnt; j++) { |
|
|
|
|
|
EntityRelation relationEntity = new EntityRelation(); |
|
|
|
|
|
relationEntity.setFrom(assets.get(i).getId()); |
|
|
|
|
|
relationEntity.setTo(devices.get(j + (i * relationsCnt)).getId()); |
|
|
|
|
|
relationEntity.setTypeGroup(RelationTypeGroup.COMMON); |
|
|
|
|
|
relationEntity.setType("contains"); |
|
|
|
|
|
relationService.saveRelation(tenantId, relationEntity); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
RelationEntityTypeFilter relationEntityTypeFilter = new RelationEntityTypeFilter("contains", Collections.singletonList(EntityType.DEVICE)); |
|
|
|
|
|
RelationsQueryFilter filter = new RelationsQueryFilter(); |
|
|
|
|
|
filter.setFilters(Collections.singletonList(relationEntityTypeFilter)); |
|
|
|
|
|
filter.setDirection(EntitySearchDirection.FROM); |
|
|
|
|
|
EntityDataPageLink pageLink = new EntityDataPageLink(10, 0, null, null); |
|
|
|
|
|
List<KeyFilter> keyFiltersEqualString = createStringKeyFilters("name", EntityKeyType.ENTITY_FIELD, StringOperation.STARTS_WITH, "Test device "); |
|
|
|
|
|
|
|
|
|
|
|
for (Asset asset : assets) { |
|
|
|
|
|
filter.setRootEntity(asset.getId()); |
|
|
|
|
|
|
|
|
|
|
|
EntityDataQuery query = new EntityDataQuery(filter, pageLink, Collections.emptyList(), Collections.emptyList(), keyFiltersEqualString); |
|
|
|
|
|
PageData<EntityData> relationsResult = entityService.findEntityDataByQuery(tenantId, customer.getId(), query); |
|
|
|
|
|
long relationsResultCnt = entityService.countEntitiesByQuery(tenantId, customer.getId(), query); |
|
|
|
|
|
|
|
|
|
|
|
Assert.assertEquals(relationsCnt, relationsResult.getData().size()); |
|
|
|
|
|
Assert.assertEquals(relationsCnt, relationsResultCnt); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@Test |
|
|
@Test |
|
|
public void testFindEntityDataByQuery_filter_device_type_name_ends_with() { |
|
|
public void testFindEntityDataByQuery_filter_device_type_name_ends_with() { |
|
|
List<Device> devices = new ArrayList<>(); |
|
|
List<Device> devices = new ArrayList<>(); |
|
|
|