Commit e33709d830d25d8fa9b998e80f4898168db63b63

Authored by ShvaykaD
Committed by GitHub
1 parent 5e2c0670

fix/getAttributesRequest & fix/hsql-inserts-with-json (#3376)

* fix GetAttributeRequest & Hsql inserts

* added deleted keys to GetAttributeResponseMsg for gateway

* changed logic for handleGetAttributesRequest on deleted attributes

* removed unused classes and remove deleted keys in GetAttributeResponseMsg proto

* revert yml file

* removed getDeletedAttributeKeysCount method call in Coap transport
@@ -28,6 +28,7 @@ import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg; @@ -28,6 +28,7 @@ import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
28 import org.thingsboard.server.actors.ActorSystemContext; 28 import org.thingsboard.server.actors.ActorSystemContext;
29 import org.thingsboard.server.actors.TbActorCtx; 29 import org.thingsboard.server.actors.TbActorCtx;
30 import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor; 30 import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
  31 +import org.thingsboard.server.common.data.DataConstants;
31 import org.thingsboard.server.common.data.Device; 32 import org.thingsboard.server.common.data.Device;
32 import org.thingsboard.server.common.data.id.DeviceId; 33 import org.thingsboard.server.common.data.id.DeviceId;
33 import org.thingsboard.server.common.data.id.TenantId; 34 import org.thingsboard.server.common.data.id.TenantId;
@@ -79,8 +80,6 @@ import java.util.UUID; @@ -79,8 +80,6 @@ import java.util.UUID;
79 import java.util.function.Consumer; 80 import java.util.function.Consumer;
80 import java.util.stream.Collectors; 81 import java.util.stream.Collectors;
81 82
82 -import static org.thingsboard.server.common.data.DataConstants.CLIENT_SCOPE;  
83 -import static org.thingsboard.server.common.data.DataConstants.SHARED_SCOPE;  
84 83
85 /** 84 /**
86 * @author Andrew Shvayka 85 * @author Andrew Shvayka
@@ -279,17 +278,17 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -279,17 +278,17 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
279 ListenableFuture<List<AttributeKvEntry>> clientAttributesFuture; 278 ListenableFuture<List<AttributeKvEntry>> clientAttributesFuture;
280 ListenableFuture<List<AttributeKvEntry>> sharedAttributesFuture; 279 ListenableFuture<List<AttributeKvEntry>> sharedAttributesFuture;
281 if (CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) { 280 if (CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) {
282 - clientAttributesFuture = findAllAttributesByScope(CLIENT_SCOPE);  
283 - sharedAttributesFuture = findAllAttributesByScope(SHARED_SCOPE); 281 + clientAttributesFuture = findAllAttributesByScope(DataConstants.CLIENT_SCOPE);
  282 + sharedAttributesFuture = findAllAttributesByScope(DataConstants.SHARED_SCOPE);
284 } else if (!CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && !CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) { 283 } else if (!CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && !CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) {
285 - clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), CLIENT_SCOPE);  
286 - sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), SHARED_SCOPE); 284 + clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), DataConstants.CLIENT_SCOPE);
  285 + sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), DataConstants.SHARED_SCOPE);
287 } else if (CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && !CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) { 286 } else if (CollectionUtils.isEmpty(request.getClientAttributeNamesList()) && !CollectionUtils.isEmpty(request.getSharedAttributeNamesList())) {
288 clientAttributesFuture = Futures.immediateFuture(Collections.emptyList()); 287 clientAttributesFuture = Futures.immediateFuture(Collections.emptyList());
289 - sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), SHARED_SCOPE); 288 + sharedAttributesFuture = findAttributesByScope(toSet(request.getSharedAttributeNamesList()), DataConstants.SHARED_SCOPE);
290 } else { 289 } else {
291 sharedAttributesFuture = Futures.immediateFuture(Collections.emptyList()); 290 sharedAttributesFuture = Futures.immediateFuture(Collections.emptyList());
292 - clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), CLIENT_SCOPE); 291 + clientAttributesFuture = findAttributesByScope(toSet(request.getClientAttributeNamesList()), DataConstants.CLIENT_SCOPE);
293 } 292 }
294 return Futures.allAsList(Arrays.asList(clientAttributesFuture, sharedAttributesFuture)); 293 return Futures.allAsList(Arrays.asList(clientAttributesFuture, sharedAttributesFuture));
295 } 294 }
@@ -316,7 +315,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -316,7 +315,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
316 AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder(); 315 AttributeUpdateNotificationMsg.Builder notification = AttributeUpdateNotificationMsg.newBuilder();
317 if (msg.isDeleted()) { 316 if (msg.isDeleted()) {
318 List<String> sharedKeys = msg.getDeletedKeys().stream() 317 List<String> sharedKeys = msg.getDeletedKeys().stream()
319 - .filter(key -> SHARED_SCOPE.equals(key.getScope())) 318 + .filter(key -> DataConstants.SHARED_SCOPE.equals(key.getScope()))
320 .map(AttributeKey::getAttributeKey) 319 .map(AttributeKey::getAttributeKey)
321 .collect(Collectors.toList()); 320 .collect(Collectors.toList());
322 if (!sharedKeys.isEmpty()) { 321 if (!sharedKeys.isEmpty()) {
@@ -324,7 +323,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -324,7 +323,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
324 hasNotificationData = true; 323 hasNotificationData = true;
325 } 324 }
326 } else { 325 } else {
327 - if (SHARED_SCOPE.equals(msg.getScope())) { 326 + if (DataConstants.SHARED_SCOPE.equals(msg.getScope())) {
328 List<AttributeKvEntry> attributes = new ArrayList<>(msg.getValues()); 327 List<AttributeKvEntry> attributes = new ArrayList<>(msg.getValues());
329 if (attributes.size() > 0) { 328 if (attributes.size() > 0) {
330 List<TsKvProto> sharedUpdated = msg.getValues().stream().map(this::toTsKvProto) 329 List<TsKvProto> sharedUpdated = msg.getValues().stream().map(this::toTsKvProto)
@@ -334,7 +333,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { @@ -334,7 +333,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
334 hasNotificationData = true; 333 hasNotificationData = true;
335 } 334 }
336 } else { 335 } else {
337 - log.debug("[{}] No public server side attributes changed!", deviceId); 336 + log.debug("[{}] No public shared side attributes changed!", deviceId);
338 } 337 }
339 } 338 }
340 } 339 }
@@ -154,7 +154,7 @@ public class DefaultTransportApiService implements TransportApiService { @@ -154,7 +154,7 @@ public class DefaultTransportApiService implements TransportApiService {
154 return TransportApiResponseMsg.newBuilder() 154 return TransportApiResponseMsg.newBuilder()
155 .setGetOrCreateDeviceResponseMsg(GetOrCreateDeviceFromGatewayResponseMsg.newBuilder().setDeviceInfo(getDeviceInfoProto(device)).build()).build(); 155 .setGetOrCreateDeviceResponseMsg(GetOrCreateDeviceFromGatewayResponseMsg.newBuilder().setDeviceInfo(getDeviceInfoProto(device)).build()).build();
156 } catch (JsonProcessingException e) { 156 } catch (JsonProcessingException e) {
157 - log.warn("[{}] Failed to lookup device by gateway id and name", gatewayId, requestMsg.getDeviceName(), e); 157 + log.warn("[{}][{}] Failed to lookup device by gateway id and name", gatewayId, requestMsg.getDeviceName(), e);
158 throw new RuntimeException(e); 158 throw new RuntimeException(e);
159 } finally { 159 } finally {
160 deviceCreationLock.unlock(); 160 deviceCreationLock.unlock();
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.common.msg.kv;  
17 -  
18 -import java.io.Serializable;  
19 -import java.util.List;  
20 -  
21 -import org.thingsboard.server.common.data.kv.AttributeKey;  
22 -import org.thingsboard.server.common.data.kv.AttributeKvEntry;  
23 -  
24 -public interface AttributesKVMsg extends Serializable {  
25 -  
26 - List<AttributeKvEntry> getClientAttributes();  
27 - List<AttributeKvEntry> getSharedAttributes();  
28 - List<AttributeKey> getDeletedAttributes();  
29 -}  
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.common.msg.kv;  
17 -  
18 -import lombok.AccessLevel;  
19 -import lombok.Data;  
20 -import lombok.RequiredArgsConstructor;  
21 -import org.thingsboard.server.common.data.kv.AttributeKey;  
22 -import org.thingsboard.server.common.data.kv.AttributeKvEntry;  
23 -  
24 -import java.util.Collections;  
25 -import java.util.List;  
26 -  
27 -@Data  
28 -@RequiredArgsConstructor(access = AccessLevel.PRIVATE)  
29 -public class BasicAttributeKVMsg implements AttributesKVMsg {  
30 -  
31 - private static final long serialVersionUID = 1L;  
32 -  
33 - private final List<AttributeKvEntry> clientAttributes;  
34 - private final List<AttributeKvEntry> sharedAttributes;  
35 - private final List<AttributeKey> deletedAttributes;  
36 -  
37 - public static BasicAttributeKVMsg fromClient(List<AttributeKvEntry> attributes) {  
38 - return new BasicAttributeKVMsg(attributes, Collections.emptyList(), Collections.emptyList());  
39 - }  
40 -  
41 - public static BasicAttributeKVMsg fromShared(List<AttributeKvEntry> attributes) {  
42 - return new BasicAttributeKVMsg(Collections.emptyList(), attributes, Collections.emptyList());  
43 - }  
44 -  
45 - public static BasicAttributeKVMsg from(List<AttributeKvEntry> client, List<AttributeKvEntry> shared) {  
46 - return new BasicAttributeKVMsg(client, shared, Collections.emptyList());  
47 - }  
48 -  
49 - public static AttributesKVMsg fromDeleted(List<AttributeKey> shared) {  
50 - return new BasicAttributeKVMsg(Collections.emptyList(), Collections.emptyList(), shared);  
51 - }  
52 -}  
@@ -127,7 +127,6 @@ message GetAttributeResponseMsg { @@ -127,7 +127,6 @@ message GetAttributeResponseMsg {
127 int32 requestId = 1; 127 int32 requestId = 1;
128 repeated TsKvProto clientAttributeList = 2; 128 repeated TsKvProto clientAttributeList = 2;
129 repeated TsKvProto sharedAttributeList = 3; 129 repeated TsKvProto sharedAttributeList = 3;
130 - repeated string deletedAttributeKeys = 4;  
131 string error = 5; 130 string error = 5;
132 } 131 }
133 132
@@ -125,7 +125,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { @@ -125,7 +125,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
125 125
126 @Override 126 @Override
127 public Response convertToPublish(CoapTransportResource.CoapSessionListener session, TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException { 127 public Response convertToPublish(CoapTransportResource.CoapSessionListener session, TransportProtos.GetAttributeResponseMsg msg) throws AdaptorException {
128 - if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0 && msg.getDeletedAttributeKeysCount() == 0) { 128 + if (msg.getClientAttributeListCount() == 0 && msg.getSharedAttributeListCount() == 0) {
129 return new Response(CoAP.ResponseCode.NOT_FOUND); 129 return new Response(CoAP.ResponseCode.NOT_FOUND);
130 } else { 130 } else {
131 Response response = new Response(CoAP.ResponseCode.CONTENT); 131 Response response = new Response(CoAP.ResponseCode.CONTENT);
@@ -35,7 +35,6 @@ import org.thingsboard.server.common.data.kv.JsonDataEntry; @@ -35,7 +35,6 @@ import org.thingsboard.server.common.data.kv.JsonDataEntry;
35 import org.thingsboard.server.common.data.kv.KvEntry; 35 import org.thingsboard.server.common.data.kv.KvEntry;
36 import org.thingsboard.server.common.data.kv.LongDataEntry; 36 import org.thingsboard.server.common.data.kv.LongDataEntry;
37 import org.thingsboard.server.common.data.kv.StringDataEntry; 37 import org.thingsboard.server.common.data.kv.StringDataEntry;
38 -import org.thingsboard.server.common.msg.kv.AttributesKVMsg;  
39 import org.thingsboard.server.gen.transport.TransportProtos; 38 import org.thingsboard.server.gen.transport.TransportProtos;
40 import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; 39 import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
41 import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; 40 import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg;
@@ -269,11 +268,6 @@ public class JsonConverter { @@ -269,11 +268,6 @@ public class JsonConverter {
269 payload.getSharedAttributeListList().forEach(addToObjectFromProto(attrObject)); 268 payload.getSharedAttributeListList().forEach(addToObjectFromProto(attrObject));
270 result.add("shared", attrObject); 269 result.add("shared", attrObject);
271 } 270 }
272 - if (payload.getDeletedAttributeKeysCount() > 0) {  
273 - JsonArray attrObject = new JsonArray();  
274 - payload.getDeletedAttributeKeysList().forEach(attrObject::add);  
275 - result.add("deleted", attrObject);  
276 - }  
277 return result; 271 return result;
278 } 272 }
279 273
@@ -290,31 +284,6 @@ public class JsonConverter { @@ -290,31 +284,6 @@ public class JsonConverter {
290 return result; 284 return result;
291 } 285 }
292 286
293 - public static JsonObject toJson(AttributesKVMsg payload, boolean asMap) {  
294 - JsonObject result = new JsonObject();  
295 - if (asMap) {  
296 - if (!payload.getClientAttributes().isEmpty()) {  
297 - JsonObject attrObject = new JsonObject();  
298 - payload.getClientAttributes().forEach(addToObject(attrObject));  
299 - result.add("client", attrObject);  
300 - }  
301 - if (!payload.getSharedAttributes().isEmpty()) {  
302 - JsonObject attrObject = new JsonObject();  
303 - payload.getSharedAttributes().forEach(addToObject(attrObject));  
304 - result.add("shared", attrObject);  
305 - }  
306 - } else {  
307 - payload.getClientAttributes().forEach(addToObject(result));  
308 - payload.getSharedAttributes().forEach(addToObject(result));  
309 - }  
310 - if (!payload.getDeletedAttributes().isEmpty()) {  
311 - JsonArray attrObject = new JsonArray();  
312 - payload.getDeletedAttributes().forEach(addToObject(attrObject));  
313 - result.add("deleted", attrObject);  
314 - }  
315 - return result;  
316 - }  
317 -  
318 public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg responseMsg) { 287 public static JsonObject getJsonObjectForGateway(String deviceName, TransportProtos.GetAttributeResponseMsg responseMsg) {
319 JsonObject result = new JsonObject(); 288 JsonObject result = new JsonObject();
320 result.addProperty("id", responseMsg.getRequestId()); 289 result.addProperty("id", responseMsg.getRequestId());
@@ -370,10 +339,6 @@ public class JsonConverter { @@ -370,10 +339,6 @@ public class JsonConverter {
370 } 339 }
371 } 340 }
372 341
373 - private static Consumer<AttributeKey> addToObject(JsonArray result) {  
374 - return key -> result.add(key.getAttributeKey());  
375 - }  
376 -  
377 private static Consumer<TsKvProto> addToObjectFromProto(JsonObject result) { 342 private static Consumer<TsKvProto> addToObjectFromProto(JsonObject result) {
378 return de -> { 343 return de -> {
379 switch (de.getKv().getType()) { 344 switch (de.getKv().getType()) {
@@ -46,6 +46,7 @@ public class JpaHsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa @@ -46,6 +46,7 @@ public class JpaHsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa
46 entity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null)); 46 entity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null));
47 entity.setLongValue(tsKvEntry.getLongValue().orElse(null)); 47 entity.setLongValue(tsKvEntry.getLongValue().orElse(null));
48 entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null)); 48 entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null));
  49 + entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null));
49 log.trace("Saving entity: {}", entity); 50 log.trace("Saving entity: {}", entity);
50 return tsQueue.add(entity); 51 return tsQueue.add(entity);
51 } 52 }
@@ -41,8 +41,8 @@ public class HsqlLatestInsertTsRepository extends AbstractInsertRepository imple @@ -41,8 +41,8 @@ public class HsqlLatestInsertTsRepository extends AbstractInsertRepository imple
41 "ON (ts_kv_latest.entity_id=T.entity_id " + 41 "ON (ts_kv_latest.entity_id=T.entity_id " +
42 "AND ts_kv_latest.key=T.key) " + 42 "AND ts_kv_latest.key=T.key) " +
43 "WHEN MATCHED THEN UPDATE SET ts_kv_latest.ts = T.ts, ts_kv_latest.bool_v = T.bool_v, ts_kv_latest.str_v = T.str_v, ts_kv_latest.long_v = T.long_v, ts_kv_latest.dbl_v = T.dbl_v, ts_kv_latest.json_v = T.json_v " + 43 "WHEN MATCHED THEN UPDATE SET ts_kv_latest.ts = T.ts, ts_kv_latest.bool_v = T.bool_v, ts_kv_latest.str_v = T.str_v, ts_kv_latest.long_v = T.long_v, ts_kv_latest.dbl_v = T.dbl_v, ts_kv_latest.json_v = T.json_v " +
44 - "WHEN NOT MATCHED THEN INSERT (entity_id, key, ts, bool_v, str_v, long_v, dbl_v) " +  
45 - "VALUES (T.entity_id, T.key, T.ts, T.bool_v, T.str_v, T.long_v, T.dbl_v);"; 44 + "WHEN NOT MATCHED THEN INSERT (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) " +
  45 + "VALUES (T.entity_id, T.key, T.ts, T.bool_v, T.str_v, T.long_v, T.dbl_v, T.json_v);";
46 46
47 @Override 47 @Override
48 public void saveOrUpdate(List<TsKvLatestEntity> entities) { 48 public void saveOrUpdate(List<TsKvLatestEntity> entities) {
@@ -13,6 +13,7 @@ DROP TABLE IF EXISTS relation; @@ -13,6 +13,7 @@ DROP TABLE IF EXISTS relation;
13 DROP TABLE IF EXISTS tb_user; 13 DROP TABLE IF EXISTS tb_user;
14 DROP TABLE IF EXISTS tenant; 14 DROP TABLE IF EXISTS tenant;
15 DROP TABLE IF EXISTS ts_kv; 15 DROP TABLE IF EXISTS ts_kv;
  16 +DROP TABLE IF EXISTS ts_kv_dictionary;
16 DROP TABLE IF EXISTS ts_kv_latest; 17 DROP TABLE IF EXISTS ts_kv_latest;
17 DROP TABLE IF EXISTS user_credentials; 18 DROP TABLE IF EXISTS user_credentials;
18 DROP TABLE IF EXISTS widget_type; 19 DROP TABLE IF EXISTS widget_type;