Commit 16f088ecf96a43d6c1533fe0a8f7367314673d64

Authored by Igor Kulikov
2 parents f39d6638 fe27cb1a

Merge with master

Showing 20 changed files with 116 additions and 149 deletions

Too many changes to show.

To preserve performance only 20 of 35 files are displayed.

@@ -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 }
@@ -163,7 +163,7 @@ public class DefaultTransportApiService implements TransportApiService { @@ -163,7 +163,7 @@ public class DefaultTransportApiService implements TransportApiService {
163 return TransportApiResponseMsg.newBuilder() 163 return TransportApiResponseMsg.newBuilder()
164 .setGetOrCreateDeviceResponseMsg(GetOrCreateDeviceFromGatewayResponseMsg.newBuilder().setDeviceInfo(getDeviceInfoProto(device)).build()).build(); 164 .setGetOrCreateDeviceResponseMsg(GetOrCreateDeviceFromGatewayResponseMsg.newBuilder().setDeviceInfo(getDeviceInfoProto(device)).build()).build();
165 } catch (JsonProcessingException e) { 165 } catch (JsonProcessingException e) {
166 - log.warn("[{}] Failed to lookup device by gateway id and name", gatewayId, requestMsg.getDeviceName(), e); 166 + log.warn("[{}][{}] Failed to lookup device by gateway id and name", gatewayId, requestMsg.getDeviceName(), e);
167 throw new RuntimeException(e); 167 throw new RuntimeException(e);
168 } finally { 168 } finally {
169 deviceCreationLock.unlock(); 169 deviceCreationLock.unlock();
@@ -522,7 +522,7 @@ js: @@ -522,7 +522,7 @@ js:
522 # Specify thread pool size for JavaScript sandbox resource monitor 522 # Specify thread pool size for JavaScript sandbox resource monitor
523 monitor_thread_pool_size: "${LOCAL_JS_SANDBOX_MONITOR_THREAD_POOL_SIZE:4}" 523 monitor_thread_pool_size: "${LOCAL_JS_SANDBOX_MONITOR_THREAD_POOL_SIZE:4}"
524 # Maximum CPU time in milliseconds allowed for script execution 524 # Maximum CPU time in milliseconds allowed for script execution
525 - max_cpu_time: "${LOCAL_JS_SANDBOX_MAX_CPU_TIME:10000}" 525 + max_cpu_time: "${LOCAL_JS_SANDBOX_MAX_CPU_TIME:8000}"
526 # Maximum allowed JavaScript execution errors before JavaScript will be blacklisted 526 # Maximum allowed JavaScript execution errors before JavaScript will be blacklisted
527 max_errors: "${LOCAL_JS_SANDBOX_MAX_ERRORS:3}" 527 max_errors: "${LOCAL_JS_SANDBOX_MAX_ERRORS:3}"
528 # JS Eval max request timeout. 0 - no timeout 528 # JS Eval max request timeout. 0 - no timeout
@@ -106,6 +106,25 @@ @@ -106,6 +106,25 @@
106 106
107 <build> 107 <build>
108 <plugins> 108 <plugins>
  109 + <plugin>
  110 + <groupId>org.apache.maven.plugins</groupId>
  111 + <artifactId>maven-source-plugin</artifactId>
  112 + <executions>
  113 + <execution>
  114 + <id>attach-sources</id>
  115 + <goals>
  116 + <goal>jar</goal>
  117 + </goals>
  118 + </execution>
  119 + </executions>
  120 + </plugin>
  121 + <plugin>
  122 + <groupId>org.apache.maven.plugins</groupId>
  123 + <artifactId>maven-deploy-plugin</artifactId>
  124 + <configuration>
  125 + <skip>false</skip>
  126 + </configuration>
  127 + </plugin>
109 </plugins> 128 </plugins>
110 </build> 129 </build>
111 130
@@ -75,6 +75,25 @@ @@ -75,6 +75,25 @@
75 75
76 <build> 76 <build>
77 <plugins> 77 <plugins>
  78 + <plugin>
  79 + <groupId>org.apache.maven.plugins</groupId>
  80 + <artifactId>maven-source-plugin</artifactId>
  81 + <executions>
  82 + <execution>
  83 + <id>attach-sources</id>
  84 + <goals>
  85 + <goal>jar</goal>
  86 + </goals>
  87 + </execution>
  88 + </executions>
  89 + </plugin>
  90 + <plugin>
  91 + <groupId>org.apache.maven.plugins</groupId>
  92 + <artifactId>maven-deploy-plugin</artifactId>
  93 + <configuration>
  94 + <skip>false</skip>
  95 + </configuration>
  96 + </plugin>
78 </plugins> 97 </plugins>
79 </build> 98 </build>
80 99
@@ -87,6 +87,25 @@ @@ -87,6 +87,25 @@
87 <groupId>org.xolstice.maven.plugins</groupId> 87 <groupId>org.xolstice.maven.plugins</groupId>
88 <artifactId>protobuf-maven-plugin</artifactId> 88 <artifactId>protobuf-maven-plugin</artifactId>
89 </plugin> 89 </plugin>
  90 + <plugin>
  91 + <groupId>org.apache.maven.plugins</groupId>
  92 + <artifactId>maven-source-plugin</artifactId>
  93 + <executions>
  94 + <execution>
  95 + <id>attach-sources</id>
  96 + <goals>
  97 + <goal>jar</goal>
  98 + </goals>
  99 + </execution>
  100 + </executions>
  101 + </plugin>
  102 + <plugin>
  103 + <groupId>org.apache.maven.plugins</groupId>
  104 + <artifactId>maven-deploy-plugin</artifactId>
  105 + <configuration>
  106 + <skip>false</skip>
  107 + </configuration>
  108 + </plugin>
90 </plugins> 109 </plugins>
91 </build> 110 </build>
92 111
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 -}  
@@ -23,16 +23,29 @@ import java.util.Collections; @@ -23,16 +23,29 @@ import java.util.Collections;
23 import java.util.List; 23 import java.util.List;
24 import java.util.concurrent.BlockingQueue; 24 import java.util.concurrent.BlockingQueue;
25 import java.util.concurrent.ConcurrentHashMap; 25 import java.util.concurrent.ConcurrentHashMap;
  26 +import java.util.concurrent.Executors;
26 import java.util.concurrent.LinkedBlockingQueue; 27 import java.util.concurrent.LinkedBlockingQueue;
  28 +import java.util.concurrent.ScheduledExecutorService;
27 import java.util.concurrent.TimeUnit; 29 import java.util.concurrent.TimeUnit;
28 30
29 @Slf4j 31 @Slf4j
30 public final class InMemoryStorage { 32 public final class InMemoryStorage {
31 private static InMemoryStorage instance; 33 private static InMemoryStorage instance;
32 private final ConcurrentHashMap<String, BlockingQueue<TbQueueMsg>> storage; 34 private final ConcurrentHashMap<String, BlockingQueue<TbQueueMsg>> storage;
  35 + private static ScheduledExecutorService statExecutor;
33 36
34 private InMemoryStorage() { 37 private InMemoryStorage() {
35 storage = new ConcurrentHashMap<>(); 38 storage = new ConcurrentHashMap<>();
  39 + statExecutor = Executors.newSingleThreadScheduledExecutor();
  40 + statExecutor.scheduleAtFixedRate(this::printStats, 60, 60, TimeUnit.SECONDS);
  41 + }
  42 +
  43 + private void printStats() {
  44 + storage.forEach((topic, queue) -> {
  45 + if (queue.size() > 0) {
  46 + log.debug("Topic: [{}], Queue size: [{}]", topic, queue.size());
  47 + }
  48 + });
36 } 49 }
37 50
38 public static InMemoryStorage getInstance() { 51 public static InMemoryStorage getInstance() {
@@ -77,4 +90,9 @@ public final class InMemoryStorage { @@ -77,4 +90,9 @@ public final class InMemoryStorage {
77 storage.clear(); 90 storage.clear();
78 } 91 }
79 92
  93 + public void destroy() {
  94 + if (statExecutor != null) {
  95 + statExecutor.shutdownNow();
  96 + }
  97 + }
80 } 98 }
@@ -53,6 +53,6 @@ public class InMemoryTbQueueProducer<T extends TbQueueMsg> implements TbQueuePro @@ -53,6 +53,6 @@ public class InMemoryTbQueueProducer<T extends TbQueueMsg> implements TbQueuePro
53 53
54 @Override 54 @Override
55 public void stop() { 55 public void stop() {
56 - 56 + storage.destroy();
57 } 57 }
58 } 58 }
@@ -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()) {
@@ -25,6 +25,7 @@ import org.thingsboard.server.dao.model.sql.AlarmEntity; @@ -25,6 +25,7 @@ import org.thingsboard.server.dao.model.sql.AlarmEntity;
25 import org.thingsboard.server.dao.model.sql.AlarmInfoEntity; 25 import org.thingsboard.server.dao.model.sql.AlarmInfoEntity;
26 26
27 import java.util.List; 27 import java.util.List;
  28 +import java.util.Set;
28 import java.util.UUID; 29 import java.util.UUID;
29 30
30 /** 31 /**
@@ -70,7 +71,7 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> { @@ -70,7 +71,7 @@ public interface AlarmRepository extends CrudRepository<AlarmEntity, UUID> {
70 @Param("affectedEntityType") String affectedEntityType, 71 @Param("affectedEntityType") String affectedEntityType,
71 @Param("startTime") Long startTime, 72 @Param("startTime") Long startTime,
72 @Param("endTime") Long endTime, 73 @Param("endTime") Long endTime,
73 - @Param("alarmStatuses") List<AlarmStatus> alarmStatuses, 74 + @Param("alarmStatuses") Set<AlarmStatus> alarmStatuses,
74 @Param("searchText") String searchText, 75 @Param("searchText") String searchText,
75 Pageable pageable); 76 Pageable pageable);
76 77
@@ -24,14 +24,12 @@ import org.springframework.stereotype.Component; @@ -24,14 +24,12 @@ import org.springframework.stereotype.Component;
24 import org.thingsboard.server.common.data.alarm.Alarm; 24 import org.thingsboard.server.common.data.alarm.Alarm;
25 import org.thingsboard.server.common.data.alarm.AlarmInfo; 25 import org.thingsboard.server.common.data.alarm.AlarmInfo;
26 import org.thingsboard.server.common.data.alarm.AlarmQuery; 26 import org.thingsboard.server.common.data.alarm.AlarmQuery;
27 -import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;  
28 import org.thingsboard.server.common.data.alarm.AlarmStatus; 27 import org.thingsboard.server.common.data.alarm.AlarmStatus;
29 import org.thingsboard.server.common.data.id.CustomerId; 28 import org.thingsboard.server.common.data.id.CustomerId;
30 import org.thingsboard.server.common.data.id.EntityId; 29 import org.thingsboard.server.common.data.id.EntityId;
31 import org.thingsboard.server.common.data.id.TenantId; 30 import org.thingsboard.server.common.data.id.TenantId;
32 import org.thingsboard.server.common.data.page.PageData; 31 import org.thingsboard.server.common.data.page.PageData;
33 import org.thingsboard.server.common.data.query.AlarmData; 32 import org.thingsboard.server.common.data.query.AlarmData;
34 -import org.thingsboard.server.common.data.query.AlarmDataPageLink;  
35 import org.thingsboard.server.common.data.query.AlarmDataQuery; 33 import org.thingsboard.server.common.data.query.AlarmDataQuery;
36 import org.thingsboard.server.dao.DaoUtil; 34 import org.thingsboard.server.dao.DaoUtil;
37 import org.thingsboard.server.dao.alarm.AlarmDao; 35 import org.thingsboard.server.dao.alarm.AlarmDao;
@@ -40,7 +38,6 @@ import org.thingsboard.server.dao.relation.RelationDao; @@ -40,7 +38,6 @@ import org.thingsboard.server.dao.relation.RelationDao;
40 import org.thingsboard.server.dao.sql.JpaAbstractDao; 38 import org.thingsboard.server.dao.sql.JpaAbstractDao;
41 import org.thingsboard.server.dao.sql.query.AlarmQueryRepository; 39 import org.thingsboard.server.dao.sql.query.AlarmQueryRepository;
42 40
43 -import java.util.ArrayList;  
44 import java.util.Collection; 41 import java.util.Collection;
45 import java.util.Collections; 42 import java.util.Collections;
46 import java.util.List; 43 import java.util.List;
@@ -102,7 +99,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A @@ -102,7 +99,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
102 Set<AlarmStatus> statusSet = null; 99 Set<AlarmStatus> statusSet = null;
103 if (query.getSearchStatus() != null) { 100 if (query.getSearchStatus() != null) {
104 statusSet = query.getSearchStatus().getStatuses(); 101 statusSet = query.getSearchStatus().getStatuses();
105 - } else if (query.getStatus() != null){ 102 + } else if (query.getStatus() != null) {
106 statusSet = Collections.singleton(query.getStatus()); 103 statusSet = Collections.singleton(query.getStatus());
107 } 104 }
108 return DaoUtil.toPageData( 105 return DaoUtil.toPageData(
@@ -112,7 +109,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A @@ -112,7 +109,7 @@ public class JpaAlarmDao extends JpaAbstractDao<AlarmEntity, Alarm> implements A
112 affectedEntity.getEntityType().name(), 109 affectedEntity.getEntityType().name(),
113 query.getPageLink().getStartTime(), 110 query.getPageLink().getStartTime(),
114 query.getPageLink().getEndTime(), 111 query.getPageLink().getEndTime(),
115 - new ArrayList<>(statusSet), 112 + statusSet,
116 Objects.toString(query.getPageLink().getTextSearch(), ""), 113 Objects.toString(query.getPageLink().getTextSearch(), ""),
117 DaoUtil.toPageable(query.getPageLink()) 114 DaoUtil.toPageable(query.getPageLink())
118 ) 115 )
@@ -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) {
@@ -31,6 +31,7 @@ import org.thingsboard.server.dao.nosql.CassandraAbstractAsyncDao; @@ -31,6 +31,7 @@ import org.thingsboard.server.dao.nosql.CassandraAbstractAsyncDao;
31 31
32 import java.util.ArrayList; 32 import java.util.ArrayList;
33 import java.util.List; 33 import java.util.List;
  34 +import java.util.Optional;
34 35
35 @Slf4j 36 @Slf4j
36 public abstract class AbstractCassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao { 37 public abstract class AbstractCassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao {
@@ -85,4 +86,22 @@ public abstract class AbstractCassandraBaseTimeseriesDao extends CassandraAbstra @@ -85,4 +86,22 @@ public abstract class AbstractCassandraBaseTimeseriesDao extends CassandraAbstra
85 return new BasicTsKvEntry(ts, toKvEntry(row, key)); 86 return new BasicTsKvEntry(ts, toKvEntry(row, key));
86 } 87 }
87 88
  89 + protected TsKvEntry convertResultToTsKvEntry(String key, Row row) {
  90 + if (row != null) {
  91 + Optional<String> foundKeyOpt = getKey(row);
  92 + long ts = row.getLong(ModelConstants.TS_COLUMN);
  93 + return new BasicTsKvEntry(ts, toKvEntry(row, foundKeyOpt.orElse(key)));
  94 + } else {
  95 + return new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(key, null));
  96 + }
  97 + }
  98 +
  99 + private Optional<String> getKey(Row row){
  100 + try{
  101 + return Optional.ofNullable(row.getString(ModelConstants.KEY_COLUMN));
  102 + } catch (IllegalArgumentException e){
  103 + return Optional.empty();
  104 + }
  105 + }
  106 +
88 } 107 }
@@ -186,15 +186,6 @@ public class CassandraBaseTimeseriesLatestDao extends AbstractCassandraBaseTimes @@ -186,15 +186,6 @@ public class CassandraBaseTimeseriesLatestDao extends AbstractCassandraBaseTimes
186 rows -> this.convertResultToTsKvEntryList(rows), readResultsProcessingExecutor); 186 rows -> this.convertResultToTsKvEntryList(rows), readResultsProcessingExecutor);
187 } 187 }
188 188
189 - private TsKvEntry convertResultToTsKvEntry(String key, Row row) {  
190 - if (row != null) {  
191 - long ts = row.getLong(ModelConstants.TS_COLUMN);  
192 - return new BasicTsKvEntry(ts, toKvEntry(row, key));  
193 - } else {  
194 - return new BasicTsKvEntry(System.currentTimeMillis(), new StringDataEntry(key, null));  
195 - }  
196 - }  
197 -  
198 private PreparedStatement getLatestStmt() { 189 private PreparedStatement getLatestStmt() {
199 if (latestInsertStmt == null) { 190 if (latestInsertStmt == null) {
200 latestInsertStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_LATEST_CF + 191 latestInsertStmt = prepare(INSERT_INTO + ModelConstants.TS_KV_LATEST_CF +
@@ -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;