dataCaptor = ArgumentCaptor.forClass(String.class);
+ verify(ctx).transformMsg(msgCaptor.capture(), typeCaptor.capture(), originatorCaptor.capture(), metadataCaptor.capture(), dataCaptor.capture());
+
+ assertEquals("ALARM", typeCaptor.getValue());
+ assertEquals(alarmOriginator, originatorCaptor.getValue());
+ assertEquals("value", metadataCaptor.getValue().getValue("key"));
+ assertEquals(Boolean.TRUE.toString(), metadataCaptor.getValue().getValue(IS_CLEARED_ALARM));
+ assertNotSame(metaData, metadataCaptor.getValue());
+
+ Alarm actualAlarm = new ObjectMapper().readValue(dataCaptor.getValue().getBytes(), Alarm.class);
+ Alarm expectedAlarm = Alarm.builder()
+ .tenantId(tenantId)
+ .originator(originator)
+ .status(CLEARED_UNACK)
+ .severity(WARNING)
+ .propagate(false)
+ .type("SomeType")
+ .details(null)
+ .endTs(oldEndDate)
+ .build();
+ expectedAlarm.setId(id);
+
+ assertEquals(expectedAlarm, actualAlarm);
+ }
+
private void initWithCreateAlarmScript() {
try {
TbCreateAlarmNodeConfiguration config = new TbCreateAlarmNodeConfiguration();
diff --git a/tools/pom.xml b/tools/pom.xml
index 6cf3467015..91bf319b0e 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -20,7 +20,7 @@
4.0.0
org.thingsboard
- 2.5.3-SNAPSHOT
+ 2.5.5-SNAPSHOT
thingsboard
tools
diff --git a/transport/coap/pom.xml b/transport/coap/pom.xml
index f265d6e9cf..eeea5a378a 100644
--- a/transport/coap/pom.xml
+++ b/transport/coap/pom.xml
@@ -20,7 +20,7 @@
4.0.0
org.thingsboard
- 2.5.3-SNAPSHOT
+ 2.5.5-SNAPSHOT
transport
org.thingsboard.transport
diff --git a/transport/coap/src/main/resources/tb-coap-transport.yml b/transport/coap/src/main/resources/tb-coap-transport.yml
index c34dba7c90..3f57b32fab 100644
--- a/transport/coap/src/main/resources/tb-coap-transport.yml
+++ b/transport/coap/src/main/resources/tb-coap-transport.yml
@@ -69,13 +69,21 @@ queue:
linger.ms: "${TB_KAFKA_LINGER_MS:1}"
buffer.memory: "${TB_BUFFER_MEMORY:33554432}"
replication_factor: "${TB_QUEUE_KAFKA_REPLICATION_FACTOR:1}"
+ use_confluent_cloud: "${TB_QUEUE_KAFKA_USE_CONFLUENT_CLOUD:false}"
+ confluent:
+ ssl.algorithm: "${TB_QUEUE_KAFKA_CONFLUENT_SSL_ALGORITHM:https}"
+ sasl.mechanism: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_MECHANISM:PLAIN}"
+ sasl.config: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG:org.apache.kafka.common.security.plain.PlainLoginModule required username=\"CLUSTER_API_KEY\" password=\"CLUSTER_API_SECRET\";}"
+ security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}"
+ other:
topic-properties:
- rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}"
+ rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}"
aws_sqs:
+ use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}"
access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}"
secret_access_key: "${TB_QUEUE_AWS_SQS_SECRET_ACCESS_KEY:YOUR_SECRET}"
region: "${TB_QUEUE_AWS_SQS_REGION:YOUR_REGION}"
diff --git a/transport/http/pom.xml b/transport/http/pom.xml
index fddc86a8da..7540b78507 100644
--- a/transport/http/pom.xml
+++ b/transport/http/pom.xml
@@ -20,7 +20,7 @@
4.0.0
org.thingsboard
- 2.5.3-SNAPSHOT
+ 2.5.5-SNAPSHOT
transport
org.thingsboard.transport
diff --git a/transport/http/src/main/resources/tb-http-transport.yml b/transport/http/src/main/resources/tb-http-transport.yml
index 377c66e711..77d5f30fa7 100644
--- a/transport/http/src/main/resources/tb-http-transport.yml
+++ b/transport/http/src/main/resources/tb-http-transport.yml
@@ -62,13 +62,21 @@ queue:
linger.ms: "${TB_KAFKA_LINGER_MS:1}"
buffer.memory: "${TB_BUFFER_MEMORY:33554432}"
replication_factor: "${TB_QUEUE_KAFKA_REPLICATION_FACTOR:1}"
+ use_confluent_cloud: "${TB_QUEUE_KAFKA_USE_CONFLUENT_CLOUD:false}"
+ confluent:
+ ssl.algorithm: "${TB_QUEUE_KAFKA_CONFLUENT_SSL_ALGORITHM:https}"
+ sasl.mechanism: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_MECHANISM:PLAIN}"
+ sasl.config: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG:org.apache.kafka.common.security.plain.PlainLoginModule required username=\"CLUSTER_API_KEY\" password=\"CLUSTER_API_SECRET\";}"
+ security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}"
+ other:
topic-properties:
- rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}"
+ rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}"
aws_sqs:
+ use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}"
access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}"
secret_access_key: "${TB_QUEUE_AWS_SQS_SECRET_ACCESS_KEY:YOUR_SECRET}"
region: "${TB_QUEUE_AWS_SQS_REGION:YOUR_REGION}"
diff --git a/transport/mqtt/pom.xml b/transport/mqtt/pom.xml
index cb37b62a34..6f4edd87b1 100644
--- a/transport/mqtt/pom.xml
+++ b/transport/mqtt/pom.xml
@@ -20,7 +20,7 @@
4.0.0
org.thingsboard
- 2.5.3-SNAPSHOT
+ 2.5.5-SNAPSHOT
transport
org.thingsboard.transport
diff --git a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml
index bcc27d0755..bc18112c8e 100644
--- a/transport/mqtt/src/main/resources/tb-mqtt-transport.yml
+++ b/transport/mqtt/src/main/resources/tb-mqtt-transport.yml
@@ -90,13 +90,21 @@ queue:
linger.ms: "${TB_KAFKA_LINGER_MS:1}"
buffer.memory: "${TB_BUFFER_MEMORY:33554432}"
replication_factor: "${TB_QUEUE_KAFKA_REPLICATION_FACTOR:1}"
+ use_confluent_cloud: "${TB_QUEUE_KAFKA_USE_CONFLUENT_CLOUD:false}"
+ confluent:
+ ssl.algorithm: "${TB_QUEUE_KAFKA_CONFLUENT_SSL_ALGORITHM:https}"
+ sasl.mechanism: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_MECHANISM:PLAIN}"
+ sasl.config: "${TB_QUEUE_KAFKA_CONFLUENT_SASL_JAAS_CONFIG:org.apache.kafka.common.security.plain.PlainLoginModule required username=\"CLUSTER_API_KEY\" password=\"CLUSTER_API_SECRET\";}"
+ security.protocol: "${TB_QUEUE_KAFKA_CONFLUENT_SECURITY_PROTOCOL:SASL_SSL}"
+ other:
topic-properties:
- rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000}"
- js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600}"
+ rule-engine: "${TB_QUEUE_KAFKA_RE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ core: "${TB_QUEUE_KAFKA_CORE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ transport-api: "${TB_QUEUE_KAFKA_TA_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ notifications: "${TB_QUEUE_KAFKA_NOTIFICATIONS_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:1048576000;partitions:1}"
+ js-executor: "${TB_QUEUE_KAFKA_JE_TOPIC_PROPERTIES:retention.ms:604800000;segment.bytes:26214400;retention.bytes:104857600;partitions:100}"
aws_sqs:
+ use_default_credential_provider_chain: "${TB_QUEUE_AWS_SQS_USE_DEFAULT_CREDENTIAL_PROVIDER_CHAIN:false}"
access_key_id: "${TB_QUEUE_AWS_SQS_ACCESS_KEY_ID:YOUR_KEY}"
secret_access_key: "${TB_QUEUE_AWS_SQS_SECRET_ACCESS_KEY:YOUR_SECRET}"
region: "${TB_QUEUE_AWS_SQS_REGION:YOUR_REGION}"
diff --git a/transport/pom.xml b/transport/pom.xml
index 9f2d726073..59b5b2470b 100644
--- a/transport/pom.xml
+++ b/transport/pom.xml
@@ -20,7 +20,7 @@
4.0.0
org.thingsboard
- 2.5.3-SNAPSHOT
+ 2.5.5-SNAPSHOT
thingsboard
transport
diff --git a/ui/package.json b/ui/package.json
index c507bbe7e9..cbc4b8c6af 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -1,7 +1,7 @@
{
"name": "thingsboard",
"private": true,
- "version": "2.5.3",
+ "version": "2.5.5",
"description": "ThingsBoard UI",
"licenses": [
{
diff --git a/ui/pom.xml b/ui/pom.xml
index 00b8d3e87b..b27f492c97 100644
--- a/ui/pom.xml
+++ b/ui/pom.xml
@@ -20,7 +20,7 @@
4.0.0
org.thingsboard
- 2.5.3-SNAPSHOT
+ 2.5.5-SNAPSHOT
thingsboard
org.thingsboard
diff --git a/ui/src/app/admin/outgoing-mail-settings.tpl.html b/ui/src/app/admin/outgoing-mail-settings.tpl.html
index 596c9c4091..5f8668bc3d 100644
--- a/ui/src/app/admin/outgoing-mail-settings.tpl.html
+++ b/ui/src/app/admin/outgoing-mail-settings.tpl.html
@@ -123,16 +123,16 @@
-
+
-
+
-
+
{{'admin.send-test-mail' | translate}}
diff --git a/ui/src/app/api/attribute.service.js b/ui/src/app/api/attribute.service.js
index 54655d7e29..aa2286d938 100644
--- a/ui/src/app/api/attribute.service.js
+++ b/ui/src/app/api/attribute.service.js
@@ -228,7 +228,7 @@ function AttributeService($http, $q, $filter, types, telemetryWebsocketService)
}
var deleteEntityAttributesPromise;
if (deleteAttributes.length) {
- deleteEntityAttributesPromise = deleteEntityAttributes(entityType, entityId, attributeScope, deleteAttributes);
+ deleteEntityAttributesPromise = deleteEntityAttributes(entityType, entityId, attributeScope, deleteAttributes, config);
}
if (Object.keys(attributesData).length) {
var url = '/api/plugins/telemetry/' + entityType + '/' + entityId + '/' + attributeScope;
diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js
index 59f1111ab4..969042bbd4 100644
--- a/ui/src/app/common/types.constant.js
+++ b/ui/src/app/common/types.constant.js
@@ -223,6 +223,12 @@ export default angular.module('thingsboard.types', [])
"LOCKOUT": {
name: "audit-log.type-lockout"
},
+ "ASSIGNED_FROM_TENANT": {
+ name: "audit-log.type-assigned-from-tenant"
+ },
+ "ASSIGNED_TO_TENANT": {
+ name: "audit-log.type-assigned-to-tenant"
+ },
"ASSIGNED_TO_EDGE": {
name: "audit-log.type-assigned-to-edge"
},
diff --git a/ui/src/app/common/utils.service.js b/ui/src/app/common/utils.service.js
index 97a04bbcf2..d5e4852afd 100644
--- a/ui/src/app/common/utils.service.js
+++ b/ui/src/app/common/utils.service.js
@@ -150,7 +150,8 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t
customTranslation: customTranslation,
objToBase64: objToBase64,
base64toObj: base64toObj,
- loadImageAspect: loadImageAspect
+ loadImageAspect: loadImageAspect,
+ sortObjectKeys: sortObjectKeys
}
return service;
@@ -605,4 +606,14 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t
return deferred.promise;
}
+ function sortObjectKeys(obj) {
+ var sortedObj = {};
+ var keys = Object.keys(obj).sort();
+ for (var i = 0; i < keys.length; i++) {
+ var key = keys[i];
+ sortedObj[key] = obj[key];
+ }
+ return sortedObj;
+ }
+
}
diff --git a/ui/src/app/event/event-row.directive.js b/ui/src/app/event/event-row.directive.js
index 92da9c06b9..e1266323ed 100644
--- a/ui/src/app/event/event-row.directive.js
+++ b/ui/src/app/event/event-row.directive.js
@@ -27,7 +27,7 @@ import eventRowEdgeEventTemplate from './event-row-edge-event.tpl.html';
/*@ngInject*/
export default function EventRowDirective($compile, $templateCache, $mdDialog, $document, $translate,
- types, toast, entityService, ruleChainService) {
+ types, utils, toast, entityService, ruleChainService) {
var linker = function (scope, element, attrs) {
@@ -76,11 +76,18 @@ export default function EventRowDirective($compile, $templateCache, $mdDialog, $
if (!contentType) {
contentType = null;
}
+ var sortedContent;
+ try {
+ sortedContent = angular.toJson(utils.sortObjectKeys(angular.fromJson(content)));
+ }
+ catch(err) {
+ sortedContent = content;
+ }
$mdDialog.show({
controller: 'EventContentDialogController',
controllerAs: 'vm',
templateUrl: eventErrorDialogTemplate,
- locals: {content: content, title: title, contentType: contentType, showingCallback: onShowingCallback},
+ locals: {content: sortedContent, title: title, contentType: contentType, showingCallback: onShowingCallback},
parent: angular.element($document[0].body),
fullscreen: true,
targetEvent: $event,
diff --git a/ui/src/app/help/help-links.constant.js b/ui/src/app/help/help-links.constant.js
index 6981cb1619..4902ca4186 100644
--- a/ui/src/app/help/help-links.constant.js
+++ b/ui/src/app/help/help-links.constant.js
@@ -44,6 +44,7 @@ var ruleNodeClazzHelpLinkMap = {
'org.thingsboard.rule.engine.aws.sqs.TbSqsNode': 'ruleNodeAwsSqs',
'org.thingsboard.rule.engine.kafka.TbKafkaNode': 'ruleNodeKafka',
'org.thingsboard.rule.engine.mqtt.TbMqttNode': 'ruleNodeMqtt',
+ 'org.thingsboard.rule.engine.mqtt.azure.TbAzureIotHubNode': 'ruleNodeAzureIotHub',
'org.thingsboard.rule.engine.rabbitmq.TbRabbitMqNode': 'ruleNodeRabbitMq',
'org.thingsboard.rule.engine.rest.TbRestApiCallNode': 'ruleNodeRestApiCall',
'org.thingsboard.rule.engine.mail.TbSendEmailNode': 'ruleNodeSendEmail'
@@ -88,6 +89,7 @@ export default angular.module('thingsboard.help', [])
ruleNodeAwsSqs: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/external-nodes/#aws-sqs-node",
ruleNodeKafka: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/external-nodes/#kafka-node",
ruleNodeMqtt: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/external-nodes/#mqtt-node",
+ ruleNodeAzureIotHub: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/external-nodes/#azure-iot-hub-node",
ruleNodeRabbitMq: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/external-nodes/#rabbitmq-node",
ruleNodeRestApiCall: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/external-nodes/#rest-api-call-node",
ruleNodeSendEmail: helpBaseUrl + "/docs/user-guide/rule-engine-2-0/external-nodes/#send-email-node",
diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json
index a86d4b2ffd..80c09a7348 100644
--- a/ui/src/app/locale/locale.constant-en_US.json
+++ b/ui/src/app/locale/locale.constant-en_US.json
@@ -373,7 +373,9 @@
"action-data": "Action data",
"failure-details": "Failure details",
"search": "Search audit logs",
- "clear-search": "Clear search"
+ "clear-search": "Clear search",
+ "type-assigned-from-tenant": "Assigned from Tenant",
+ "type-assigned-to-tenant": "Assigned to Tenant"
},
"confirm-on-exit": {
"message": "You have unsaved changes. Are you sure you want to leave this page?",
diff --git a/ui/src/app/rulechain/script/node-script-test.service.js b/ui/src/app/rulechain/script/node-script-test.service.js
index ee6eea8378..ae1f0b0568 100644
--- a/ui/src/app/rulechain/script/node-script-test.service.js
+++ b/ui/src/app/rulechain/script/node-script-test.service.js
@@ -20,7 +20,7 @@ import nodeScriptTestTemplate from './node-script-test.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
/*@ngInject*/
-export default function NodeScriptTest($q, $mdDialog, $document, ruleChainService) {
+export default function NodeScriptTest($q, $mdDialog, $document, ruleChainService, utils) {
var service = {
testNodeScript: testNodeScript
@@ -89,6 +89,8 @@ export default function NodeScriptTest($q, $mdDialog, $document, ruleChainServic
deviceName: "Test Device",
ts: new Date().getTime() + ""
};
+ } else {
+ metadata = utils.sortObjectKeys(metadata);
}
if (!msgType) {
msgType = "POST_TELEMETRY_REQUEST";