Showing
11 changed files
with
65 additions
and
18 deletions
... | ... | @@ -326,7 +326,19 @@ public final class PluginProcessingContext implements PluginContext { |
326 | 326 | callback.onSuccess(this, Boolean.FALSE); |
327 | 327 | } else { |
328 | 328 | ListenableFuture<RuleMetaData> ruleFuture = pluginCtx.ruleService.findRuleByIdAsync(new RuleId(entityId.getId())); |
329 | - Futures.addCallback(ruleFuture, getCallback(callback, rule -> rule != null && rule.getTenantId().equals(ctx.getTenantId()))); | |
329 | + Futures.addCallback(ruleFuture, getCallback(callback, rule -> { | |
330 | + if (rule == null) { | |
331 | + return Boolean.FALSE; | |
332 | + } else { | |
333 | + if (ctx.isTenantAdmin() && !rule.getTenantId().equals(ctx.getTenantId())) { | |
334 | + return Boolean.FALSE; | |
335 | + } else if (ctx.isSystemAdmin() && !rule.getTenantId().isNullUid()) { | |
336 | + return Boolean.FALSE; | |
337 | + } else { | |
338 | + return Boolean.TRUE; | |
339 | + } | |
340 | + } | |
341 | + })); | |
330 | 342 | } |
331 | 343 | return; |
332 | 344 | case PLUGIN: |
... | ... | @@ -334,7 +346,19 @@ public final class PluginProcessingContext implements PluginContext { |
334 | 346 | callback.onSuccess(this, Boolean.FALSE); |
335 | 347 | } else { |
336 | 348 | ListenableFuture<PluginMetaData> pluginFuture = pluginCtx.pluginService.findPluginByIdAsync(new PluginId(entityId.getId())); |
337 | - Futures.addCallback(pluginFuture, getCallback(callback, plugin -> plugin != null && plugin.getTenantId().equals(ctx.getTenantId()))); | |
349 | + Futures.addCallback(pluginFuture, getCallback(callback, plugin -> { | |
350 | + if (plugin == null) { | |
351 | + return Boolean.FALSE; | |
352 | + } else { | |
353 | + if (ctx.isTenantAdmin() && !plugin.getTenantId().equals(ctx.getTenantId())) { | |
354 | + return Boolean.FALSE; | |
355 | + } else if (ctx.isSystemAdmin() && !plugin.getTenantId().isNullUid()) { | |
356 | + return Boolean.FALSE; | |
357 | + } else { | |
358 | + return Boolean.TRUE; | |
359 | + } | |
360 | + } | |
361 | + })); | |
338 | 362 | } |
339 | 363 | return; |
340 | 364 | case CUSTOMER: | ... | ... |
... | ... | @@ -91,4 +91,13 @@ public class DeviceAttributes { |
91 | 91 | } |
92 | 92 | return map; |
93 | 93 | } |
94 | + | |
95 | + @Override | |
96 | + public String toString() { | |
97 | + return "DeviceAttributes{" + | |
98 | + "clientSideAttributesMap=" + clientSideAttributesMap + | |
99 | + ", serverPrivateAttributesMap=" + serverPrivateAttributesMap + | |
100 | + ", serverPublicAttributesMap=" + serverPublicAttributesMap + | |
101 | + '}'; | |
102 | + } | |
94 | 103 | } | ... | ... |
... | ... | @@ -15,6 +15,7 @@ |
15 | 15 | */ |
16 | 16 | package org.thingsboard.server.extensions.core.action.template; |
17 | 17 | |
18 | +import lombok.extern.slf4j.Slf4j; | |
18 | 19 | import org.apache.velocity.Template; |
19 | 20 | import org.apache.velocity.VelocityContext; |
20 | 21 | import org.apache.velocity.runtime.parser.ParseException; |
... | ... | @@ -35,6 +36,7 @@ import java.util.Optional; |
35 | 36 | /** |
36 | 37 | * @author Andrew Shvayka |
37 | 38 | */ |
39 | +@Slf4j | |
38 | 40 | public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfiguration> extends SimpleRuleLifecycleComponent implements PluginAction<T> { |
39 | 41 | protected T configuration; |
40 | 42 | protected Template template; |
... | ... | @@ -69,6 +71,7 @@ public abstract class AbstractTemplatePluginAction<T extends TemplateActionConfi |
69 | 71 | } |
70 | 72 | |
71 | 73 | protected String getMsgBody(RuleContext ctx, ToDeviceActorMsg msg) { |
74 | + log.trace("Creating context for: {} and payload {}", ctx.getDeviceAttributes(), msg.getPayload()); | |
72 | 75 | VelocityContext context = VelocityUtils.createContext(ctx.getDeviceAttributes(), msg.getPayload()); |
73 | 76 | return VelocityUtils.merge(template, context); |
74 | 77 | } | ... | ... |
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | package org.thingsboard.server.extensions.kafka.plugin; |
17 | 17 | |
18 | 18 | import lombok.RequiredArgsConstructor; |
19 | +import lombok.extern.slf4j.Slf4j; | |
19 | 20 | import org.apache.kafka.clients.producer.Producer; |
20 | 21 | import org.apache.kafka.clients.producer.ProducerRecord; |
21 | 22 | import org.thingsboard.server.common.data.id.RuleId; |
... | ... | @@ -30,6 +31,7 @@ import org.thingsboard.server.extensions.kafka.action.KafkaActionMsg; |
30 | 31 | import org.thingsboard.server.extensions.kafka.action.KafkaActionPayload; |
31 | 32 | |
32 | 33 | @RequiredArgsConstructor |
34 | +@Slf4j | |
33 | 35 | public class KafkaMsgHandler implements RuleMsgHandler { |
34 | 36 | |
35 | 37 | private final Producer<?, String> producer; |
... | ... | @@ -40,7 +42,7 @@ public class KafkaMsgHandler implements RuleMsgHandler { |
40 | 42 | throw new RuleException("Unsupported message type " + msg.getClass().getName() + "!"); |
41 | 43 | } |
42 | 44 | KafkaActionPayload payload = ((KafkaActionMsg) msg).getPayload(); |
43 | - | |
45 | + log.debug("Processing kafka payload: {}", payload); | |
44 | 46 | try { |
45 | 47 | producer.send(new ProducerRecord<>(payload.getTopic(), payload.getMsgBody()), |
46 | 48 | (metadata, e) -> { | ... | ... |
... | ... | @@ -78,6 +78,7 @@ public class GatewaySessionCtx { |
78 | 78 | Device newDevice = new Device(); |
79 | 79 | newDevice.setTenantId(gateway.getTenantId()); |
80 | 80 | newDevice.setName(deviceName); |
81 | + newDevice.setType("default"); | |
81 | 82 | return deviceService.saveDevice(newDevice); |
82 | 83 | }); |
83 | 84 | GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device); | ... | ... |
... | ... | @@ -51,7 +51,6 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS |
51 | 51 | scope.types = types; |
52 | 52 | |
53 | 53 | scope.entityType = attrs.entityType; |
54 | - scope.attributeScope = getAttributeScopeByValue(attrs.defaultAttributeScope); | |
55 | 54 | |
56 | 55 | if (scope.entityType === types.entityType.device) { |
57 | 56 | scope.attributeScopes = types.attributesScope; |
... | ... | @@ -60,8 +59,13 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS |
60 | 59 | scope.attributeScopes = {}; |
61 | 60 | scope.attributeScopes.server = types.attributesScope.server; |
62 | 61 | scope.attributeScopeSelectionReadonly = true; |
62 | + } | |
63 | + | |
64 | + scope.attributeScope = getAttributeScopeByValue(attrs.defaultAttributeScope); | |
65 | + | |
66 | + if (scope.entityType != types.entityType.device) { | |
63 | 67 | if (scope.attributeScope != types.latestTelemetry) { |
64 | - scope.attributeScope = scope.attributeScopes.server.value; | |
68 | + scope.attributeScope = scope.attributeScopes.server; | |
65 | 69 | } |
66 | 70 | } |
67 | 71 | |
... | ... | @@ -81,8 +85,8 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS |
81 | 85 | search: null |
82 | 86 | }; |
83 | 87 | |
84 | - scope.$watch("entityId", function(newVal, prevVal) { | |
85 | - if (newVal && !angular.equals(newVal, prevVal)) { | |
88 | + scope.$watch("entityId", function(newVal) { | |
89 | + if (newVal) { | |
86 | 90 | scope.resetFilter(); |
87 | 91 | scope.getEntityAttributes(false, true); |
88 | 92 | } | ... | ... |
... | ... | @@ -190,7 +190,7 @@ export default angular.module('thingsboard.locale', []) |
190 | 190 | "attribute": { |
191 | 191 | "attributes": "Attributes", |
192 | 192 | "latest-telemetry": "Latest telemetry", |
193 | - "attributes-scope": "Device attributes scope", | |
193 | + "attributes-scope": "Entity attributes scope", | |
194 | 194 | "scope-latest-telemetry": "Latest telemetry", |
195 | 195 | "scope-client": "Client attributes", |
196 | 196 | "scope-server": "Server attributes", | ... | ... |
... | ... | @@ -138,6 +138,8 @@ export default function PluginController(pluginService, userService, importExpor |
138 | 138 | vm.pluginGridConfig.topIndex = $stateParams.topIndex; |
139 | 139 | } |
140 | 140 | |
141 | + vm.isPluginEditable = isPluginEditable; | |
142 | + | |
141 | 143 | vm.activatePlugin = activatePlugin; |
142 | 144 | vm.suspendPlugin = suspendPlugin; |
143 | 145 | vm.exportPlugin = exportPlugin; | ... | ... |
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | <details-buttons tb-help="vm.helpLinkIdForPlugin()" help-container-id="help-container"> |
20 | 20 | <div id="help-container"></div> |
21 | 21 | </details-buttons> |
22 | - <md-tabs ng-class="{'tb-headless': vm.grid.detailsConfig.isDetailsEditMode}" | |
22 | + <md-tabs ng-class="{'tb-headless': (vm.grid.detailsConfig.isDetailsEditMode || !vm.isPluginEditable(vm.grid.operatingItem()))}" | |
23 | 23 | id="tabs" md-border-bottom flex class="tb-absolute-fill"> |
24 | 24 | <md-tab label="{{ 'plugin.details' | translate }}"> |
25 | 25 | <tb-plugin plugin="vm.grid.operatingItem()" |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | on-export-plugin="vm.exportPlugin(event, vm.grid.detailsConfig.currentItem)" |
32 | 32 | on-delete-plugin="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-plugin> |
33 | 33 | </md-tab> |
34 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.attributes' | translate }}"> | |
34 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'attribute.attributes' | translate }}"> | |
35 | 35 | <tb-attribute-table flex |
36 | 36 | entity-id="vm.grid.operatingItem().id.id" |
37 | 37 | entity-type="{{vm.types.entityType.plugin}}" |
... | ... | @@ -39,7 +39,7 @@ |
39 | 39 | default-attribute-scope="{{vm.types.attributesScope.server.value}}"> |
40 | 40 | </tb-attribute-table> |
41 | 41 | </md-tab> |
42 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.latest-telemetry' | translate }}"> | |
42 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'attribute.latest-telemetry' | translate }}"> | |
43 | 43 | <tb-attribute-table flex |
44 | 44 | entity-id="vm.grid.operatingItem().id.id" |
45 | 45 | entity-type="{{vm.types.entityType.plugin}}" |
... | ... | @@ -48,7 +48,7 @@ |
48 | 48 | disable-attribute-scope-selection="true"> |
49 | 49 | </tb-attribute-table> |
50 | 50 | </md-tab> |
51 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'plugin.events' | translate }}"> | |
51 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'plugin.events' | translate }}"> | |
52 | 52 | <tb-event-table flex entity-type="vm.types.entityType.plugin" |
53 | 53 | entity-id="vm.grid.operatingItem().id.id" |
54 | 54 | tenant-id="vm.grid.operatingItem().tenantId.id" |
... | ... | @@ -56,7 +56,7 @@ |
56 | 56 | disabled-event-types="{{vm.types.eventType.alarm.value}}"> |
57 | 57 | </tb-event-table> |
58 | 58 | </md-tab> |
59 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> | |
59 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isPluginEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}"> | |
60 | 60 | <tb-relation-table flex |
61 | 61 | entity-id="vm.grid.operatingItem().id.id" |
62 | 62 | entity-type="{{vm.types.entityType.plugin}}"> | ... | ... |
... | ... | @@ -134,6 +134,8 @@ export default function RuleController(ruleService, userService, importExport, $ |
134 | 134 | vm.ruleGridConfig.topIndex = $stateParams.topIndex; |
135 | 135 | } |
136 | 136 | |
137 | + vm.isRuleEditable = isRuleEditable; | |
138 | + | |
137 | 139 | vm.activateRule = activateRule; |
138 | 140 | vm.suspendRule = suspendRule; |
139 | 141 | vm.exportRule = exportRule; | ... | ... |
... | ... | @@ -19,7 +19,7 @@ |
19 | 19 | <details-buttons tb-help="'rules'" help-container-id="help-container"> |
20 | 20 | <div id="help-container"></div> |
21 | 21 | </details-buttons> |
22 | - <md-tabs ng-class="{'tb-headless': vm.grid.detailsConfig.isDetailsEditMode}" | |
22 | + <md-tabs ng-class="{'tb-headless': (vm.grid.detailsConfig.isDetailsEditMode || !vm.isRuleEditable(vm.grid.operatingItem()))}" | |
23 | 23 | id="tabs" md-border-bottom flex class="tb-absolute-fill"> |
24 | 24 | <md-tab label="{{ 'rule.details' | translate }}"> |
25 | 25 | <tb-rule rule="vm.grid.operatingItem()" |
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 | on-export-rule="vm.exportRule(event, vm.grid.detailsConfig.currentItem)" |
32 | 32 | on-delete-rule="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-rule> |
33 | 33 | </md-tab> |
34 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.attributes' | translate }}"> | |
34 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'attribute.attributes' | translate }}"> | |
35 | 35 | <tb-attribute-table flex |
36 | 36 | entity-id="vm.grid.operatingItem().id.id" |
37 | 37 | entity-type="{{vm.types.entityType.rule}}" |
... | ... | @@ -39,7 +39,7 @@ |
39 | 39 | default-attribute-scope="{{vm.types.attributesScope.server.value}}"> |
40 | 40 | </tb-attribute-table> |
41 | 41 | </md-tab> |
42 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'attribute.latest-telemetry' | translate }}"> | |
42 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'attribute.latest-telemetry' | translate }}"> | |
43 | 43 | <tb-attribute-table flex |
44 | 44 | entity-id="vm.grid.operatingItem().id.id" |
45 | 45 | entity-type="{{vm.types.entityType.rule}}" |
... | ... | @@ -48,7 +48,7 @@ |
48 | 48 | disable-attribute-scope-selection="true"> |
49 | 49 | </tb-attribute-table> |
50 | 50 | </md-tab> |
51 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'rule.events' | translate }}"> | |
51 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'rule.events' | translate }}"> | |
52 | 52 | <tb-event-table flex entity-type="vm.types.entityType.rule" |
53 | 53 | entity-id="vm.grid.operatingItem().id.id" |
54 | 54 | tenant-id="vm.grid.operatingItem().tenantId.id" |
... | ... | @@ -56,7 +56,7 @@ |
56 | 56 | disabled-event-types="{{vm.types.eventType.alarm.value}}"> |
57 | 57 | </tb-event-table> |
58 | 58 | </md-tab> |
59 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> | |
59 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.isRuleEditable(vm.grid.operatingItem())" label="{{ 'relation.relations' | translate }}"> | |
60 | 60 | <tb-relation-table flex |
61 | 61 | entity-id="vm.grid.operatingItem().id.id" |
62 | 62 | entity-type="{{vm.types.entityType.rule}}"> | ... | ... |