Commit c1164cd068fb71a7d4248b20743fb5a1e882167c

Authored by Andrii Shvaika
1 parent f4137bc9

WS API Improvement

... ... @@ -247,8 +247,10 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
247 247 int dynamicQueryInvocationCntValue = dynamicQueryInvocationCnt.getAndSet(0);
248 248 long dynamicQueryInvocationTimeValue = dynamicQueryTimeSpent.getAndSet(0);
249 249 long dynamicQueryCnt = subscriptionsBySessionId.values().stream().map(Map::values).count();
250   - log.info("Stats: regularQueryInvocationCnt = [{}], regularQueryInvocationTime = [{}], dynamicQueryCnt = [{}] dynamicQueryInvocationCnt = [{}], dynamicQueryInvocationTime = [{}]",
251   - regularQueryInvocationCntValue, regularQueryInvocationTimeValue, dynamicQueryCnt, dynamicQueryInvocationCntValue, dynamicQueryInvocationTimeValue);
  250 + if (regularQueryInvocationCntValue > 0 || dynamicQueryInvocationCntValue > 0 || dynamicQueryCnt > 0) {
  251 + log.info("Stats: regularQueryInvocationCnt = [{}], regularQueryInvocationTime = [{}], dynamicQueryCnt = [{}] dynamicQueryInvocationCnt = [{}], dynamicQueryInvocationTime = [{}]",
  252 + regularQueryInvocationCntValue, regularQueryInvocationTimeValue, dynamicQueryCnt, dynamicQueryInvocationCntValue, dynamicQueryInvocationTimeValue);
  253 + }
252 254 }
253 255
254 256 private void clearSubs(TbEntityDataSubCtx ctx) {
... ...
... ... @@ -346,9 +346,7 @@ public class TbEntityDataSubCtx {
346 346 newSubsList.forEach(
347 347 entity -> {
348 348 log.trace("[{}][{}] Found new subscription for entity: {}", sessionRef.getSessionId(), cmdId, entity.getEntityId());
349   - if (curTsCmd != null) {
350   - addSubscription(entity, keysByType, resultToLatestValues);
351   - }
  349 + addSubscription(entity, keysByType, resultToLatestValues);
352 350 }
353 351 );
354 352 }
... ...
... ... @@ -46,7 +46,6 @@ import org.thingsboard.server.common.data.relation.EntitySearchDirection;
46 46 import org.thingsboard.server.common.data.relation.EntityTypeFilter;
47 47 import org.thingsboard.server.dao.util.SqlDao;
48 48
49   -import java.math.BigInteger;
50 49 import java.util.Collections;
51 50 import java.util.HashMap;
52 51 import java.util.List;
... ... @@ -132,7 +131,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
132 131 String latestJoins = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings);
133 132 String whereClause = this.buildWhere(ctx, latestFiltersMapping);
134 133 String textSearchQuery = this.buildTextSearchQuery(ctx, selectionMapping, pageLink.getTextSearch());
135   - String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping);
  134 + String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping, query.getEntityFilter().getType(), entityType);
136 135 String entityTypeStr;
137 136 if (query.getEntityFilter().getType().equals(EntityFilterType.RELATIONS_QUERY)) {
138 137 entityTypeStr = "e.entity_type";
... ... @@ -144,7 +143,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
144 143 } else {
145 144 entityFieldsSelection = String.format("e.id id, %s entity_type", entityTypeStr);
146 145 }
147   - String latestSelection = EntityKeyMapping.buildSelections(latestSelectionMapping);
  146 + String latestSelection = EntityKeyMapping.buildSelections(latestSelectionMapping, query.getEntityFilter().getType(), entityType);
148 147 String topSelection = "entities.*";
149 148 if (!StringUtils.isEmpty(latestSelection)) {
150 149 topSelection = topSelection + ", " + latestSelection;
... ... @@ -294,7 +293,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
294 293 private String relationQuery(EntityQueryContext ctx, RelationsQueryFilter entityFilter) {
295 294 EntityId rootId = entityFilter.getRootEntity();
296 295 String lvlFilter = getLvlFilter(entityFilter.getMaxLevel());
297   - String selectFields = getSelectTenantId() + ", " + getSelectCustomerId() + ", " +
  296 + String selectFields = getSelectCreatedTime() + ", " + getSelectTenantId() + ", " + getSelectCustomerId() + ", " +
298 297 " entity.entity_id as id," + getSelectType() + ", " + getSelectName() + ", " +
299 298 getSelectLabel() + ", entity.entity_type as entity_type";
300 299 String from = getQueryTemplate(entityFilter.getDirection());
... ... @@ -348,6 +347,10 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
348 347 return from;
349 348 }
350 349
  350 + private String getSelectCreatedTime() {
  351 + return "created_time";
  352 + }
  353 +
351 354 private String getSelectTenantId() {
352 355 return "SELECT CASE" +
353 356 " WHEN entity.entity_type = 'TENANT' THEN entity_id" +
... ...
... ... @@ -31,38 +31,85 @@ import org.thingsboard.server.common.data.query.KeyFilter;
31 31 import org.thingsboard.server.common.data.query.KeyFilterPredicate;
32 32 import org.thingsboard.server.common.data.query.NumericFilterPredicate;
33 33 import org.thingsboard.server.common.data.query.StringFilterPredicate;
  34 +import org.thingsboard.server.dao.model.ModelConstants;
34 35
35 36 import java.util.ArrayList;
  37 +import java.util.Arrays;
36 38 import java.util.Collections;
37 39 import java.util.HashMap;
  40 +import java.util.HashSet;
38 41 import java.util.List;
39 42 import java.util.Map;
40 43 import java.util.Optional;
  44 +import java.util.Set;
41 45 import java.util.stream.Collectors;
42 46 import java.util.stream.Stream;
43 47
44 48 @Data
45 49 public class EntityKeyMapping {
46 50
47   - public static final Map<String, String> entityFieldColumnMap = new HashMap<>();
  51 + private static final Map<EntityType, Set<String>> allowedEntityFieldMap = new HashMap<>();
  52 + private static final Map<String, String> entityFieldColumnMap = new HashMap<>();
  53 +
  54 + private static final String CREATED_TIME = "createdTime";
  55 + private static final String ENTITY_TYPE = "entityType";
  56 + private static final String NAME = "name";
  57 + private static final String TYPE = "type";
  58 + private static final String LABEL = "label";
  59 + private static final String FIRST_NAME = "firstName";
  60 + private static final String LAST_NAME = "lastName";
  61 + private static final String EMAIL = "email";
  62 + private static final String TITLE = "title";
  63 + private static final String REGION = "region";
  64 + private static final String COUNTRY = "country";
  65 + private static final String STATE = "state";
  66 + private static final String CITY = "city";
  67 + private static final String ADDRESS = "address";
  68 + private static final String ADDRESS_2 = "address2";
  69 + private static final String ZIP = "zip";
  70 + private static final String PHONE = "phone";
  71 +
  72 + public static final List<String> commonEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME);
  73 + public static final List<String> labeledEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME, TYPE, LABEL);
  74 + public static final List<String> contactBasedEntityFields = Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME, EMAIL, TITLE, COUNTRY, STATE, CITY, ADDRESS, ADDRESS_2, ZIP, PHONE);
  75 +
  76 + public static final Set<String> commonEntityFieldsSet = new HashSet<>(commonEntityFields);
  77 + public static final Set<String> relationQueryEntityFieldsSet = new HashSet<>(Arrays.asList(CREATED_TIME, ENTITY_TYPE, NAME, TYPE, LABEL));
48 78
49 79 static {
50   - entityFieldColumnMap.put("createdTime", "id");
51   - entityFieldColumnMap.put("entityType", "entity_type");
52   - entityFieldColumnMap.put("name", "name");
53   - entityFieldColumnMap.put("type", "type");
54   - entityFieldColumnMap.put("label", "label");
55   - entityFieldColumnMap.put("firstName", "first_name");
56   - entityFieldColumnMap.put("lastName", "last_name");
57   - entityFieldColumnMap.put("email", "email");
58   - entityFieldColumnMap.put("title", "title");
59   - entityFieldColumnMap.put("country", "country");
60   - entityFieldColumnMap.put("state", "state");
61   - entityFieldColumnMap.put("city", "city");
62   - entityFieldColumnMap.put("address", "address");
63   - entityFieldColumnMap.put("address2", "address2");
64   - entityFieldColumnMap.put("zip", "zip");
65   - entityFieldColumnMap.put("phone", "phone");
  80 + allowedEntityFieldMap.put(EntityType.DEVICE, new HashSet<>(labeledEntityFields));
  81 + allowedEntityFieldMap.put(EntityType.ASSET, new HashSet<>(labeledEntityFields));
  82 + allowedEntityFieldMap.put(EntityType.ENTITY_VIEW, new HashSet<>(labeledEntityFields));
  83 +
  84 + allowedEntityFieldMap.put(EntityType.TENANT, new HashSet<>(contactBasedEntityFields));
  85 + allowedEntityFieldMap.get(EntityType.TENANT).add(REGION);
  86 + allowedEntityFieldMap.put(EntityType.CUSTOMER, new HashSet<>(contactBasedEntityFields));
  87 +
  88 + allowedEntityFieldMap.put(EntityType.USER, new HashSet<>(Arrays.asList(FIRST_NAME, LAST_NAME, EMAIL)));
  89 +
  90 + allowedEntityFieldMap.put(EntityType.DASHBOARD, new HashSet<>(commonEntityFields));
  91 + allowedEntityFieldMap.put(EntityType.RULE_CHAIN, new HashSet<>(commonEntityFields));
  92 + allowedEntityFieldMap.put(EntityType.RULE_NODE, new HashSet<>(commonEntityFields));
  93 + allowedEntityFieldMap.put(EntityType.WIDGET_TYPE, new HashSet<>(commonEntityFields));
  94 + allowedEntityFieldMap.put(EntityType.WIDGETS_BUNDLE, new HashSet<>(commonEntityFields));
  95 +
  96 + entityFieldColumnMap.put(CREATED_TIME, ModelConstants.CREATED_TIME_PROPERTY);
  97 + entityFieldColumnMap.put(ENTITY_TYPE, ModelConstants.ENTITY_TYPE_PROPERTY);
  98 + entityFieldColumnMap.put(REGION, ModelConstants.TENANT_REGION_PROPERTY);
  99 + entityFieldColumnMap.put(NAME, "name");
  100 + entityFieldColumnMap.put(TYPE, "type");
  101 + entityFieldColumnMap.put(LABEL, "label");
  102 + entityFieldColumnMap.put(FIRST_NAME, ModelConstants.USER_FIRST_NAME_PROPERTY);
  103 + entityFieldColumnMap.put(LAST_NAME, ModelConstants.USER_LAST_NAME_PROPERTY);
  104 + entityFieldColumnMap.put(EMAIL, ModelConstants.EMAIL_PROPERTY);
  105 + entityFieldColumnMap.put(TITLE, ModelConstants.TITLE_PROPERTY);
  106 + entityFieldColumnMap.put(COUNTRY, ModelConstants.COUNTRY_PROPERTY);
  107 + entityFieldColumnMap.put(STATE, ModelConstants.STATE_PROPERTY);
  108 + entityFieldColumnMap.put(CITY, ModelConstants.CITY_PROPERTY);
  109 + entityFieldColumnMap.put(ADDRESS, ModelConstants.ADDRESS_PROPERTY);
  110 + entityFieldColumnMap.put(ADDRESS_2, ModelConstants.ADDRESS2_PROPERTY);
  111 + entityFieldColumnMap.put(ZIP, ModelConstants.ZIP_PROPERTY);
  112 + entityFieldColumnMap.put(PHONE, ModelConstants.PHONE_PROPERTY);
66 113 }
67 114
68 115 private int index;
... ... @@ -91,10 +138,23 @@ public class EntityKeyMapping {
91 138 return alias + "_ts";
92 139 }
93 140
94   - public String toSelection() {
  141 + public String toSelection(EntityFilterType filterType, EntityType entityType) {
95 142 if (entityKey.getType().equals(EntityKeyType.ENTITY_FIELD)) {
96   - String column = entityFieldColumnMap.get(entityKey.getKey());
97   - return String.format("e.%s as %s", column, getValueAlias());
  143 + Set<String> existingEntityFields;
  144 + if (filterType.equals(EntityFilterType.RELATIONS_QUERY)) {
  145 + existingEntityFields = relationQueryEntityFieldsSet;
  146 + } else {
  147 + existingEntityFields = allowedEntityFieldMap.get(entityType);
  148 + if (existingEntityFields == null) {
  149 + existingEntityFields = commonEntityFieldsSet;
  150 + }
  151 + }
  152 + if (existingEntityFields.contains(entityKey.getKey())) {
  153 + String column = entityFieldColumnMap.get(entityKey.getKey());
  154 + return String.format("e.%s as %s", column, getValueAlias());
  155 + } else {
  156 + return String.format("'' as %s", getValueAlias());
  157 + }
98 158 } else if (entityKey.getType().equals(EntityKeyType.TIME_SERIES)) {
99 159 return buildTimeSeriesSelection();
100 160 } else {
... ... @@ -142,8 +202,8 @@ public class EntityKeyMapping {
142 202 }
143 203 }
144 204
145   - public static String buildSelections(List<EntityKeyMapping> mappings) {
146   - return mappings.stream().map(EntityKeyMapping::toSelection).collect(
  205 + public static String buildSelections(List<EntityKeyMapping> mappings, EntityFilterType filterType, EntityType entityType) {
  206 + return mappings.stream().map(mapping -> mapping.toSelection(filterType, entityType)).collect(
147 207 Collectors.joining(", "));
148 208 }
149 209
... ...