thingsboard-memoizeit
Changes
application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java 28(+26 -2)
extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/plugin/KafkaMsgHandler.java 4(+3 -1)
extensions-api/src/main/java/org/thingsboard/server/extensions/api/device/DeviceAttributes.java 9(+9 -0)
extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java 3(+3 -0)
transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java 1(+1 -0)
ui/src/app/locale/locale.constant.js 2(+1 -1)
ui/src/app/plugin/plugins.tpl.html 10(+5 -5)
ui/src/app/rule/rule.controller.js 2(+2 -0)
ui/src/app/rule/rules.tpl.html 10(+5 -5)
Details
diff --git a/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java b/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java
index 5dbc5f4..57a838f 100644
--- a/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java
+++ b/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java
@@ -326,7 +326,19 @@ public final class PluginProcessingContext implements PluginContext {
callback.onSuccess(this, Boolean.FALSE);
} else {
ListenableFuture<RuleMetaData> ruleFuture = pluginCtx.ruleService.findRuleByIdAsync(new RuleId(entityId.getId()));
- Futures.addCallback(ruleFuture, getCallback(callback, rule -> rule != null && rule.getTenantId().equals(ctx.getTenantId())));
+ Futures.addCallback(ruleFuture, getCallback(callback, rule -> {
+ if (rule == null) {
+ return Boolean.FALSE;
+ } else {
+ if (ctx.isTenantAdmin() && !rule.getTenantId().equals(ctx.getTenantId())) {
+ return Boolean.FALSE;
+ } else if (ctx.isSystemAdmin() && !rule.getTenantId().isNullUid()) {
+ return Boolean.FALSE;
+ } else {
+ return Boolean.TRUE;
+ }
+ }
+ }));
}
return;
case PLUGIN:
@@ -334,7 +346,19 @@ public final class PluginProcessingContext implements PluginContext {
callback.onSuccess(this, Boolean.FALSE);
} else {
ListenableFuture<PluginMetaData> pluginFuture = pluginCtx.pluginService.findPluginByIdAsync(new PluginId(entityId.getId()));
- Futures.addCallback(pluginFuture, getCallback(callback, plugin -> plugin != null && plugin.getTenantId().equals(ctx.getTenantId())));
+ Futures.addCallback(pluginFuture, getCallback(callback, plugin -> {
+ if (plugin == null) {
+ return Boolean.FALSE;
+ } else {
+ if (ctx.isTenantAdmin() && !plugin.getTenantId().equals(ctx.getTenantId())) {
+ return Boolean.FALSE;
+ } else if (ctx.isSystemAdmin() && !plugin.getTenantId().isNullUid()) {
+ return Boolean.FALSE;
+ } else {
+ return Boolean.TRUE;
+ }
+ }
+ }));
}
return;
case CUSTOMER:
diff --git a/extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/plugin/KafkaMsgHandler.java b/extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/plugin/KafkaMsgHandler.java
index bde0a6f..87f890a 100644
--- a/extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/plugin/KafkaMsgHandler.java
+++ b/extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/plugin/KafkaMsgHandler.java
@@ -16,6 +16,7 @@
package org.thingsboard.server.extensions.kafka.plugin;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.thingsboard.server.common.data.id.RuleId;
@@ -30,6 +31,7 @@ import org.thingsboard.server.extensions.kafka.action.KafkaActionMsg;
import org.thingsboard.server.extensions.kafka.action.KafkaActionPayload;
@RequiredArgsConstructor
+@Slf4j
public class KafkaMsgHandler implements RuleMsgHandler {
private final Producer<?, String> producer;
@@ -40,7 +42,7 @@ public class KafkaMsgHandler implements RuleMsgHandler {
throw new RuleException("Unsupported message type " + msg.getClass().getName() + "!");
}
KafkaActionPayload payload = ((KafkaActionMsg) msg).getPayload();
-
+ log.debug("Processing kafka payload: {}", payload);
try {
producer.send(new ProducerRecord<>(payload.getTopic(), payload.getMsgBody()),
(metadata, e) -> {
diff --git a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/device/DeviceAttributes.java b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/device/DeviceAttributes.java
index 8628d0c..2cfeefb 100644
--- a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/device/DeviceAttributes.java
+++ b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/device/DeviceAttributes.java
@@ -91,4 +91,13 @@ public class DeviceAttributes {
}
return map;
}
+
+ @Override
+ public String toString() {
+ return "DeviceAttributes{" +
+ "clientSideAttributesMap=" + clientSideAttributesMap +
+ ", serverPrivateAttributesMap=" + serverPrivateAttributesMap +
+ ", serverPublicAttributesMap=" + serverPublicAttributesMap +
+ '}';
+ }
}
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java
index 9360af1..12958f5 100644
--- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java
@@ -15,6 +15,7 @@
*/
package org.thingsboard.server.extensions.core.action.template;
+import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.runtime.parser.ParseException;
@@ -35,6 +36,7 @@ import java.util.Optional;
/**
* @author Andrew Shvayka
*/
+@Slf4j
public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfiguration> extends SimpleRuleLifecycleComponent implements PluginAction<T> {
protected T configuration;
protected Template template;
@@ -69,6 +71,7 @@ public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfi
}
protected String getMsgBody(RuleContext ctx, ToDeviceActorMsg msg) {
+ log.trace("Creating context for: {} and payload {}", ctx.getDeviceAttributes(), msg.getPayload());
VelocityContext context = VelocityUtils.createContext(ctx.getDeviceAttributes(), msg.getPayload());
return VelocityUtils.merge(template, context);
}
diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java
index a78319a..d6a953a 100644
--- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java
+++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java
@@ -78,6 +78,7 @@ public class GatewaySessionCtx {
Device newDevice = new Device();
newDevice.setTenantId(gateway.getTenantId());
newDevice.setName(deviceName);
+ newDevice.setType("default");
return deviceService.saveDevice(newDevice);
});
GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device);
diff --git a/ui/src/app/entity/attribute/attribute-table.directive.js b/ui/src/app/entity/attribute/attribute-table.directive.js
index e05fcb6..da7697d 100644
--- a/ui/src/app/entity/attribute/attribute-table.directive.js
+++ b/ui/src/app/entity/attribute/attribute-table.directive.js
@@ -51,7 +51,6 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS
scope.types = types;
scope.entityType = attrs.entityType;
- scope.attributeScope = getAttributeScopeByValue(attrs.defaultAttributeScope);
if (scope.entityType === types.entityType.device) {
scope.attributeScopes = types.attributesScope;
@@ -60,8 +59,13 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS
scope.attributeScopes = {};
scope.attributeScopes.server = types.attributesScope.server;
scope.attributeScopeSelectionReadonly = true;
+ }
+
+ scope.attributeScope = getAttributeScopeByValue(attrs.defaultAttributeScope);
+
+ if (scope.entityType != types.entityType.device) {
if (scope.attributeScope != types.latestTelemetry) {
- scope.attributeScope = scope.attributeScopes.server.value;
+ scope.attributeScope = scope.attributeScopes.server;
}
}
@@ -81,8 +85,8 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS
search: null
};
- scope.$watch("entityId", function(newVal, prevVal) {
- if (newVal && !angular.equals(newVal, prevVal)) {
+ scope.$watch("entityId", function(newVal) {
+ if (newVal) {
scope.resetFilter();
scope.getEntityAttributes(false, true);
}
ui/src/app/locale/locale.constant.js 2(+1 -1)
diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js
index a23845e..84c7097 100644
--- a/ui/src/app/locale/locale.constant.js
+++ b/ui/src/app/locale/locale.constant.js
@@ -190,7 +190,7 @@ export default angular.module('thingsboard.locale', [])
"attribute": {
"attributes": "Attributes",
"latest-telemetry": "Latest telemetry",
- "attributes-scope": "Device attributes scope",
+ "attributes-scope": "Entity attributes scope",
"scope-latest-telemetry": "Latest telemetry",
"scope-client": "Client attributes",
"scope-server": "Server attributes",
diff --git a/ui/src/app/plugin/plugin.controller.js b/ui/src/app/plugin/plugin.controller.js
index b250f61..c83dc38 100644
--- a/ui/src/app/plugin/plugin.controller.js
+++ b/ui/src/app/plugin/plugin.controller.js
@@ -138,6 +138,8 @@ export default function PluginController(pluginService, userService, importExpor
vm.pluginGridConfig.topIndex = $stateParams.topIndex;
}
+ vm.isPluginEditable = isPluginEditable;
+
vm.activatePlugin = activatePlugin;
vm.suspendPlugin = suspendPlugin;
vm.exportPlugin = exportPlugin;
ui/src/app/plugin/plugins.tpl.html 10(+5 -5)
diff --git a/ui/src/app/plugin/plugins.tpl.html b/ui/src/app/plugin/plugins.tpl.html
index d04ebcb..5b03506 100644
--- a/ui/src/app/plugin/plugins.tpl.html
+++ b/ui/src/app/plugin/plugins.tpl.html
@@ -19,7 +19,7 @@
<details-buttons tb-help="vm.helpLinkIdForPlugin()" help-container-id="help-container">
<div id="help-container"></div>
</details-buttons>
- <md-tabs ng-class="{'tb-headless': vm.grid.detailsConfig.isDetailsEditMode}"
+ <md-tabs ng-class="{'tb-headless': (vm.grid.detailsConfig.isDetailsEditMode || !vm.isPluginEditable(vm.grid.operatingItem()))}"
id="tabs" md-border-bottom flex class="tb-absolute-fill">
<md-tab label="{{ 'plugin.details' | translate }}">
<tb-plugin plugin="vm.grid.operatingItem()"
@@ -31,7 +31,7 @@
on-export-plugin="vm.exportPlugin(event, vm.grid.detailsConfig.currentItem)"
on-delete-plugin="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-plugin>
</md-tab>
- <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.attributes' | translate }}">
+ <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'attribute.attributes' | translate }}">
<tb-attribute-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.plugin}}"
@@ -39,7 +39,7 @@
default-attribute-scope="{{vm.types.attributesScope.server.value}}">
</tb-attribute-table>
</md-tab>
- <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.latest-telemetry' | translate }}">
+ <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'attribute.latest-telemetry' | translate }}">
<tb-attribute-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.plugin}}"
@@ -48,7 +48,7 @@
disable-attribute-scope-selection="true">
</tb-attribute-table>
</md-tab>
- <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'plugin.events' | translate }}">
+ <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'plugin.events' | translate }}">
<tb-event-table flex entity-type="vm.types.entityType.plugin"
entity-id="vm.grid.operatingItem().id.id"
tenant-id="vm.grid.operatingItem().tenantId.id"
@@ -56,7 +56,7 @@
disabled-event-types="{{vm.types.eventType.alarm.value}}">
</tb-event-table>
</md-tab>
- <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}">
+ <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}">
<tb-relation-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.plugin}}">
ui/src/app/rule/rule.controller.js 2(+2 -0)
diff --git a/ui/src/app/rule/rule.controller.js b/ui/src/app/rule/rule.controller.js
index 3cff981..9cc90cf 100644
--- a/ui/src/app/rule/rule.controller.js
+++ b/ui/src/app/rule/rule.controller.js
@@ -134,6 +134,8 @@ export default function RuleController(ruleService, userService, importExport, $
vm.ruleGridConfig.topIndex = $stateParams.topIndex;
}
+ vm.isRuleEditable = isRuleEditable;
+
vm.activateRule = activateRule;
vm.suspendRule = suspendRule;
vm.exportRule = exportRule;
ui/src/app/rule/rules.tpl.html 10(+5 -5)
diff --git a/ui/src/app/rule/rules.tpl.html b/ui/src/app/rule/rules.tpl.html
index 16097cc..098bbee 100644
--- a/ui/src/app/rule/rules.tpl.html
+++ b/ui/src/app/rule/rules.tpl.html
@@ -19,7 +19,7 @@
<details-buttons tb-help="'rules'" help-container-id="help-container">
<div id="help-container"></div>
</details-buttons>
- <md-tabs ng-class="{'tb-headless': vm.grid.detailsConfig.isDetailsEditMode}"
+ <md-tabs ng-class="{'tb-headless': (vm.grid.detailsConfig.isDetailsEditMode || !vm.isRuleEditable(vm.grid.operatingItem()))}"
id="tabs" md-border-bottom flex class="tb-absolute-fill">
<md-tab label="{{ 'rule.details' | translate }}">
<tb-rule rule="vm.grid.operatingItem()"
@@ -31,7 +31,7 @@
on-export-rule="vm.exportRule(event, vm.grid.detailsConfig.currentItem)"
on-delete-rule="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-rule>
</md-tab>
- <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.attributes' | translate }}">
+ <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'attribute.attributes' | translate }}">
<tb-attribute-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.rule}}"
@@ -39,7 +39,7 @@
default-attribute-scope="{{vm.types.attributesScope.server.value}}">
</tb-attribute-table>
</md-tab>
- <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.latest-telemetry' | translate }}">
+ <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'attribute.latest-telemetry' | translate }}">
<tb-attribute-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.rule}}"
@@ -48,7 +48,7 @@
disable-attribute-scope-selection="true">
</tb-attribute-table>
</md-tab>
- <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'rule.events' | translate }}">
+ <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'rule.events' | translate }}">
<tb-event-table flex entity-type="vm.types.entityType.rule"
entity-id="vm.grid.operatingItem().id.id"
tenant-id="vm.grid.operatingItem().tenantId.id"
@@ -56,7 +56,7 @@
disabled-event-types="{{vm.types.eventType.alarm.value}}">
</tb-event-table>
</md-tab>
- <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}">
+ <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}">
<tb-relation-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.rule}}">