WS API Improvement

This commit is contained in:
Andrii Shvaika 2020-06-24 19:38:45 +03:00
parent f4137bc9ea
commit c1164cd068
4 changed files with 94 additions and 31 deletions

View File

@ -247,9 +247,11 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
int dynamicQueryInvocationCntValue = dynamicQueryInvocationCnt.getAndSet(0);
long dynamicQueryInvocationTimeValue = dynamicQueryTimeSpent.getAndSet(0);
long dynamicQueryCnt = subscriptionsBySessionId.values().stream().map(Map::values).count();
if (regularQueryInvocationCntValue > 0 || dynamicQueryInvocationCntValue > 0 || dynamicQueryCnt > 0) {
log.info("Stats: regularQueryInvocationCnt = [{}], regularQueryInvocationTime = [{}], dynamicQueryCnt = [{}] dynamicQueryInvocationCnt = [{}], dynamicQueryInvocationTime = [{}]",
regularQueryInvocationCntValue, regularQueryInvocationTimeValue, dynamicQueryCnt, dynamicQueryInvocationCntValue, dynamicQueryInvocationTimeValue);
}
}
private void clearSubs(TbEntityDataSubCtx ctx) {
Collection<Integer> oldSubIds = ctx.clearSubscriptions();

View File

@ -346,10 +346,8 @@ public class TbEntityDataSubCtx {
newSubsList.forEach(
entity -> {
log.trace("[{}][{}] Found new subscription for entity: {}", sessionRef.getSessionId(), cmdId, entity.getEntityId());
if (curTsCmd != null) {
addSubscription(entity, keysByType, resultToLatestValues);
}
}
);
}
}

View File

@ -46,7 +46,6 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.EntityTypeFilter;
import org.thingsboard.server.dao.util.SqlDao;
import java.math.BigInteger;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@ -132,7 +131,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
String latestJoins = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings);
String whereClause = this.buildWhere(ctx, latestFiltersMapping);
String textSearchQuery = this.buildTextSearchQuery(ctx, selectionMapping, pageLink.getTextSearch());
String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping);
String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping, query.getEntityFilter().getType(), entityType);
String entityTypeStr;
if (query.getEntityFilter().getType().equals(EntityFilterType.RELATIONS_QUERY)) {
entityTypeStr = "e.entity_type";
@ -144,7 +143,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
} else {
entityFieldsSelection = String.format("e.id id, %s entity_type", entityTypeStr);
}
String latestSelection = EntityKeyMapping.buildSelections(latestSelectionMapping);
String latestSelection = EntityKeyMapping.buildSelections(latestSelectionMapping, query.getEntityFilter().getType(), entityType);
String topSelection = "entities.*";
if (!StringUtils.isEmpty(latestSelection)) {
topSelection = topSelection + ", " + latestSelection;
@ -294,7 +293,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
private String relationQuery(EntityQueryContext ctx, RelationsQueryFilter entityFilter) {
EntityId rootId = entityFilter.getRootEntity();
String lvlFilter = getLvlFilter(entityFilter.getMaxLevel());
String selectFields = getSelectTenantId() + ", " + getSelectCustomerId() + ", " +
String selectFields = getSelectCreatedTime() + ", " + getSelectTenantId() + ", " + getSelectCustomerId() + ", " +
" entity.entity_id as id," + getSelectType() + ", " + getSelectName() + ", " +
getSelectLabel() + ", entity.entity_type as entity_type";
String from = getQueryTemplate(entityFilter.getDirection());
@ -348,6 +347,10 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
return from;
}
private String getSelectCreatedTime() {
return "created_time";
}
private String getSelectTenantId() {
return "SELECT CASE" +
" WHEN entity.entity_type = 'TENANT' THEN entity_id" +

View File

@ -31,38 +31,85 @@ import org.thingsboard.server.common.data.query.KeyFilter;
import org.thingsboard.server.common.data.query.KeyFilterPredicate;
import org.thingsboard.server.common.data.query.NumericFilterPredicate;
import org.thingsboard.server.common.data.query.StringFilterPredicate;
import org.thingsboard.server.dao.model.ModelConstants;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Data
public class EntityKeyMapping {
public static final Map<String, String> entityFieldColumnMap = new HashMap<>();
private static final Map<EntityType, Set<String>> allowedEntityFieldMap = new HashMap<>();
private static final Map<String, String> entityFieldColumnMap = new HashMap<>();
private static final String CREATED_TIME = "createdTime";
private static final String ENTITY_TYPE = "entityType";
private static final String NAME = "name";
private static final String TYPE = "type";
private static final String LABEL = "label";
private static final String FIRST_NAME = "firstName";
private static final String LAST_NAME = "lastName";
private static final String EMAIL = "email";
private static final String TITLE = "title";
private static final String REGION = "region";
private static final String COUNTRY = "country";
private static final String STATE = "state";
private static final String CITY = "city";
private static final String ADDRESS = "address";
private static final String ADDRESS_2 = "address2";
private static final String ZIP = "zip";
private static final String PHONE = "phone";
public static final List<String> commonEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME);
public static final List<String> labeledEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME, TYPE, LABEL);
public static final List<String> contactBasedEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME, EMAIL, TITLE, COUNTRY, STATE, CITY, ADDRESS, ADDRESS_2, ZIP, PHONE);
public static final Set<String> commonEntityFieldsSet = new HashSet<>(commonEntityFields);
public static final Set<String> relationQueryEntityFieldsSet = new HashSet<>(Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME, TYPE, LABEL));
static {
entityFieldColumnMap.put("createdTime", "id");
entityFieldColumnMap.put("entityType", "entity_type");
entityFieldColumnMap.put("name", "name");
entityFieldColumnMap.put("type", "type");
entityFieldColumnMap.put("label", "label");
entityFieldColumnMap.put("firstName", "first_name");
entityFieldColumnMap.put("lastName", "last_name");
entityFieldColumnMap.put("email", "email");
entityFieldColumnMap.put("title", "title");
entityFieldColumnMap.put("country", "country");
entityFieldColumnMap.put("state", "state");
entityFieldColumnMap.put("city", "city");
entityFieldColumnMap.put("address", "address");
entityFieldColumnMap.put("address2", "address2");
entityFieldColumnMap.put("zip", "zip");
entityFieldColumnMap.put("phone", "phone");
allowedEntityFieldMap.put(EntityType.DEVICE, new HashSet<>(labeledEntityFields));
allowedEntityFieldMap.put(EntityType.ASSET, new HashSet<>(labeledEntityFields));
allowedEntityFieldMap.put(EntityType.ENTITY_VIEW, new HashSet<>(labeledEntityFields));
allowedEntityFieldMap.put(EntityType.TENANT, new HashSet<>(contactBasedEntityFields));
allowedEntityFieldMap.get(EntityType.TENANT).add(REGION);
allowedEntityFieldMap.put(EntityType.CUSTOMER, new HashSet<>(contactBasedEntityFields));
allowedEntityFieldMap.put(EntityType.USER, new HashSet<>(Arrays.asList(FIRST_NAME, LAST_NAME, EMAIL)));
allowedEntityFieldMap.put(EntityType.DASHBOARD, new HashSet<>(commonEntityFields));
allowedEntityFieldMap.put(EntityType.RULE_CHAIN, new HashSet<>(commonEntityFields));
allowedEntityFieldMap.put(EntityType.RULE_NODE, new HashSet<>(commonEntityFields));
allowedEntityFieldMap.put(EntityType.WIDGET_TYPE, new HashSet<>(commonEntityFields));
allowedEntityFieldMap.put(EntityType.WIDGETS_BUNDLE, new HashSet<>(commonEntityFields));
entityFieldColumnMap.put(CREATED_TIME, ModelConstants.CREATED_TIME_PROPERTY);
entityFieldColumnMap.put(ENTITY_TYPE, ModelConstants.ENTITY_TYPE_PROPERTY);
entityFieldColumnMap.put(REGION, ModelConstants.TENANT_REGION_PROPERTY);
entityFieldColumnMap.put(NAME, "name");
entityFieldColumnMap.put(TYPE, "type");
entityFieldColumnMap.put(LABEL, "label");
entityFieldColumnMap.put(FIRST_NAME, ModelConstants.USER_FIRST_NAME_PROPERTY);
entityFieldColumnMap.put(LAST_NAME, ModelConstants.USER_LAST_NAME_PROPERTY);
entityFieldColumnMap.put(EMAIL, ModelConstants.EMAIL_PROPERTY);
entityFieldColumnMap.put(TITLE, ModelConstants.TITLE_PROPERTY);
entityFieldColumnMap.put(COUNTRY, ModelConstants.COUNTRY_PROPERTY);
entityFieldColumnMap.put(STATE, ModelConstants.STATE_PROPERTY);
entityFieldColumnMap.put(CITY, ModelConstants.CITY_PROPERTY);
entityFieldColumnMap.put(ADDRESS, ModelConstants.ADDRESS_PROPERTY);
entityFieldColumnMap.put(ADDRESS_2, ModelConstants.ADDRESS2_PROPERTY);
entityFieldColumnMap.put(ZIP, ModelConstants.ZIP_PROPERTY);
entityFieldColumnMap.put(PHONE, ModelConstants.PHONE_PROPERTY);
}
private int index;
@ -91,10 +138,23 @@ public class EntityKeyMapping {
return alias + "_ts";
}
public String toSelection() {
public String toSelection(EntityFilterType filterType, EntityType entityType) {
if (entityKey.getType().equals(EntityKeyType.ENTITY_FIELD)) {
Set<String> existingEntityFields;
if (filterType.equals(EntityFilterType.RELATIONS_QUERY)) {
existingEntityFields = relationQueryEntityFieldsSet;
} else {
existingEntityFields = allowedEntityFieldMap.get(entityType);
if (existingEntityFields == null) {
existingEntityFields = commonEntityFieldsSet;
}
}
if (existingEntityFields.contains(entityKey.getKey())) {
String column = entityFieldColumnMap.get(entityKey.getKey());
return String.format("e.%s as %s", column, getValueAlias());
} else {
return String.format("'' as %s", getValueAlias());
}
} else if (entityKey.getType().equals(EntityKeyType.TIME_SERIES)) {
return buildTimeSeriesSelection();
} else {
@ -142,8 +202,8 @@ public class EntityKeyMapping {
}
}
public static String buildSelections(List<EntityKeyMapping> mappings) {
return mappings.stream().map(EntityKeyMapping::toSelection).collect(
public static String buildSelections(List<EntityKeyMapping> mappings, EntityFilterType filterType, EntityType entityType) {
return mappings.stream().map(mapping -> mapping.toSelection(filterType, entityType)).collect(
Collectors.joining(", "));
}