From 344f6045a64dd2f3ff9aaeade9629868fd63754d Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 21 Mar 2018 17:34:07 +0200 Subject: [PATCH] Use ComponentDescriptors in RuleChain UI --- .../server/controller/BaseController.java | 10 ++ .../ComponentDescriptorController.java | 18 ++++ .../AnnotationComponentDiscoveryService.java | 9 ++ .../component/ComponentDiscoveryService.java | 3 + .../app/api/component-descriptor.service.js | 38 +++++++- ui/src/app/api/rule-chain.service.js | 92 ++++--------------- ui/src/app/common/types.constant.js | 11 +++ ui/src/app/locale/locale.constant.js | 4 +- .../app/rulechain/rulechain-fieldset.tpl.html | 5 + ui/src/app/rulechain/rulechain.controller.js | 70 +++++++------- ui/src/app/rulechain/rulechain.tpl.html | 2 +- .../app/rulechain/rulenode-fieldset.tpl.html | 11 ++- ui/src/app/rulechain/rulenode.directive.js | 2 +- ui/src/app/rulechain/rulenode.tpl.html | 2 +- 14 files changed, 161 insertions(+), 116 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 2a4ba719af..d1c282508b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -71,6 +71,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.UUID; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -480,6 +481,15 @@ public abstract class BaseController { } } + List checkComponentDescriptorsByTypes(Set types) throws ThingsboardException { + try { + log.debug("[{}] Lookup component descriptors", types); + return componentDescriptorService.getComponents(types); + } catch (Exception e) { + throw handleException(e, false); + } + } + List checkPluginActionsByPluginClazz(String pluginClazz) throws ThingsboardException { try { checkComponentDescriptorByClazz(pluginClazz); diff --git a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java index e63a443769..7a43cd35a2 100644 --- a/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java +++ b/application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java @@ -21,7 +21,9 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.exception.ThingsboardException; +import java.util.HashSet; import java.util.List; +import java.util.Set; @RestController @RequestMapping("/api") @@ -51,6 +53,22 @@ public class ComponentDescriptorController extends BaseController { } } + @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')") + @RequestMapping(value = "/components", params = {"componentTypes"}, method = RequestMethod.GET) + @ResponseBody + public List getComponentDescriptorsByTypes(@RequestParam("componentTypes") String[] strComponentTypes) throws ThingsboardException { + checkArrayParameter("componentTypes", strComponentTypes); + try { + Set componentTypes = new HashSet<>(); + for (String strComponentType : strComponentTypes) { + componentTypes.add(ComponentType.valueOf(strComponentType)); + } + return checkComponentDescriptorsByTypes(componentTypes); + } catch (Exception e) { + throw handleException(e); + } + } + @PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')") @RequestMapping(value = "/components/actions/{pluginClazz:.+}", method = RequestMethod.GET) @ResponseBody diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index 910b45954a..d9416d7226 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -203,6 +203,15 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe return Collections.unmodifiableList(componentsMap.get(type)); } + @Override + public List getComponents(Set types) { + List result = new ArrayList<>(); + for (ComponentType type : types) { + result.addAll(componentsMap.get(type)); + } + return Collections.unmodifiableList(result); + } + @Override public Optional getComponent(String clazz) { return Optional.ofNullable(components.get(clazz)); diff --git a/application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java index ea27e60646..7a15a1b253 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java @@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType; import java.util.List; import java.util.Optional; +import java.util.Set; /** * @author Andrew Shvayka @@ -30,6 +31,8 @@ public interface ComponentDiscoveryService { List getComponents(ComponentType type); + List getComponents(Set types); + Optional getComponent(String clazz); List getPluginActions(String pluginClazz); diff --git a/ui/src/app/api/component-descriptor.service.js b/ui/src/app/api/component-descriptor.service.js index 4478d71b95..cc3f710629 100644 --- a/ui/src/app/api/component-descriptor.service.js +++ b/ui/src/app/api/component-descriptor.service.js @@ -26,7 +26,8 @@ function ComponentDescriptorService($http, $q) { var service = { getComponentDescriptorsByType: getComponentDescriptorsByType, getComponentDescriptorByClazz: getComponentDescriptorByClazz, - getPluginActionsByPluginClazz: getPluginActionsByPluginClazz + getPluginActionsByPluginClazz: getPluginActionsByPluginClazz, + getComponentDescriptorsByTypes: getComponentDescriptorsByTypes } return service; @@ -52,6 +53,41 @@ function ComponentDescriptorService($http, $q) { return deferred.promise; } + function getComponentDescriptorsByTypes(componentTypes) { + var deferred = $q.defer(); + var result = []; + for (var i=componentTypes.length-1;i>=0;i--) { + var componentType = componentTypes[i]; + if (componentsByType[componentType]) { + result = result.concat(componentsByType[componentType]); + componentTypes.splice(i, 1); + } + } + if (!componentTypes.length) { + deferred.resolve(result); + } else { + var url = '/api/components?componentTypes=' + componentTypes.join(','); + $http.get(url, null).then(function success(response) { + var components = response.data; + for (var i = 0; i < components.length; i++) { + var component = components[i]; + var componentsList = componentsByType[component.type]; + if (!componentsList) { + componentsList = []; + componentsByType[component.type] = componentsList; + } + componentsList.push(component); + componentsByClazz[component.clazz] = component; + } + result = result.concat(components); + deferred.resolve(components); + }, function fail() { + deferred.reject(); + }); + } + return deferred.promise; + } + function getComponentDescriptorByClazz(componentDescriptorClazz) { var deferred = $q.defer(); if (componentsByClazz[componentDescriptorClazz]) { diff --git a/ui/src/app/api/rule-chain.service.js b/ui/src/app/api/rule-chain.service.js index be8e99db11..f17553545e 100644 --- a/ui/src/app/api/rule-chain.service.js +++ b/ui/src/app/api/rule-chain.service.js @@ -17,9 +17,9 @@ export default angular.module('thingsboard.api.ruleChain', []) .factory('ruleChainService', RuleChainService).name; /*@ngInject*/ -function RuleChainService($http, $q, $filter, types) { +function RuleChainService($http, $q, $filter, types, componentDescriptorService) { - var ruleNodeTypes = null; + var ruleNodeComponents = null; var service = { getSystemRuleChains: getSystemRuleChains, @@ -30,8 +30,8 @@ function RuleChainService($http, $q, $filter, types) { deleteRuleChain: deleteRuleChain, getRuleChainMetaData: getRuleChainMetaData, saveRuleChainMetaData: saveRuleChainMetaData, - getRuleNodeTypes: getRuleNodeTypes, - getRuleNodeComponentType: getRuleNodeComponentType, + getRuleNodeComponents: getRuleNodeComponents, + getRuleNodeComponentByClazz: getRuleNodeComponentByClazz, getRuleNodeSupportedLinks: getRuleNodeSupportedLinks, resolveTargetRuleChains: resolveTargetRuleChains }; @@ -165,21 +165,18 @@ function RuleChainService($http, $q, $filter, types) { return deferred.promise; } - function getRuleNodeTypes() { + function getRuleNodeComponents() { var deferred = $q.defer(); - if (ruleNodeTypes) { - deferred.resolve(ruleNodeTypes); + if (ruleNodeComponents) { + deferred.resolve(ruleNodeComponents); } else { - loadRuleNodeTypes().then( - (nodeTypes) => { - ruleNodeTypes = nodeTypes; - ruleNodeTypes.push( - { - nodeType: types.ruleNodeType.RULE_CHAIN.value, - type: 'Rule chain' - } + loadRuleNodeComponents().then( + (components) => { + ruleNodeComponents = components; + ruleNodeComponents.push( + types.ruleChainNodeComponent ); - deferred.resolve(ruleNodeTypes); + deferred.resolve(ruleNodeComponents); }, () => { deferred.reject(); @@ -189,10 +186,10 @@ function RuleChainService($http, $q, $filter, types) { return deferred.promise; } - function getRuleNodeComponentType(type) { - var res = $filter('filter')(ruleNodeTypes, {type: type}, true); + function getRuleNodeComponentByClazz(clazz) { + var res = $filter('filter')(ruleNodeComponents, {clazz: clazz}, true); if (res && res.length) { - return res[0].nodeType; + return res[0]; } return null; } @@ -222,61 +219,8 @@ function RuleChainService($http, $q, $filter, types) { return deferred.promise; } - function loadRuleNodeTypes() { - var deferred = $q.defer(); - deferred.resolve( - [ - { - nodeType: types.ruleNodeType.FILTER.value, - type: 'Filter' - }, - { - nodeType: types.ruleNodeType.FILTER.value, - type: 'Switch' - }, - { - nodeType: types.ruleNodeType.ENRICHMENT.value, - type: 'Self' - }, - { - nodeType: types.ruleNodeType.ENRICHMENT.value, - type: 'Tenant/Customer' - }, - { - nodeType: types.ruleNodeType.ENRICHMENT.value, - type: 'Related Entity' - }, - { - nodeType: types.ruleNodeType.ENRICHMENT.value, - type: 'Last Telemetry' - }, - { - nodeType: types.ruleNodeType.TRANSFORMATION.value, - type: 'Modify' - }, - { - nodeType: types.ruleNodeType.TRANSFORMATION.value, - type: 'New/Update' - }, - { - nodeType: types.ruleNodeType.ACTION.value, - type: 'Telemetry' - }, - { - nodeType: types.ruleNodeType.ACTION.value, - type: 'RPC call' - }, - { - nodeType: types.ruleNodeType.ACTION.value, - type: 'Send email' - }, - { - nodeType: types.ruleNodeType.ACTION.value, - type: 'Alarm' - } - ] - ); - return deferred.promise; + function loadRuleNodeComponents() { + return componentDescriptorService.getComponentDescriptorsByTypes(types.ruleNodeTypeComponentTypes); } diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index b134bf0575..2f8d152029 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -457,6 +457,17 @@ export default angular.module('thingsboard.types', []) clientSide: false } }, + ruleNodeTypeComponentTypes: ["FILTER", "ENRICHMENT", "TRANSFORMATION", "ACTION"], + ruleChainNodeComponent: { + type: 'RULE_CHAIN', + name: 'Rule chain', + clazz: 'tb.internal.RuleChain' + }, + inputNodeComponent: { + type: 'INPUT', + name: 'Input', + clazz: 'tb.internal.Input' + }, ruleNodeType: { FILTER: { value: "FILTER", diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js index 4c392ca84d..18c9330165 100644 --- a/ui/src/app/locale/locale.constant.js +++ b/ui/src/app/locale/locale.constant.js @@ -1167,7 +1167,8 @@ export default angular.module('thingsboard.locale', []) "select-rulechain": "Select rule chain", "no-rulechains-matching": "No rule chains matching '{{entity}}' were found.", "rulechain-required": "Rule chain is required", - "management": "Rules management" + "management": "Rules management", + "debug-mode": "Debug mode" }, "rulenode": { "add": "Add rule node", @@ -1177,6 +1178,7 @@ export default angular.module('thingsboard.locale', []) "description": "Description", "delete": "Delete rule node", "rulenode-details": "Rule node details", + "debug-mode": "Debug mode", "link-details": "Rule node link details", "add-link": "Add link", "link-label": "Link label", diff --git a/ui/src/app/rulechain/rulechain-fieldset.tpl.html b/ui/src/app/rulechain/rulechain-fieldset.tpl.html index a79ba35cf0..2189daaeee 100644 --- a/ui/src/app/rulechain/rulechain-fieldset.tpl.html +++ b/ui/src/app/rulechain/rulechain-fieldset.tpl.html @@ -41,6 +41,11 @@
rulechain.name-required
+ + {{ 'rulechain.debug-mode' | translate }} + + diff --git a/ui/src/app/rulechain/rulechain.controller.js b/ui/src/app/rulechain/rulechain.controller.js index c854cfa36d..31886b8a28 100644 --- a/ui/src/app/rulechain/rulechain.controller.js +++ b/ui/src/app/rulechain/rulechain.controller.js @@ -54,6 +54,7 @@ export function RuleChainController($stateParams, $scope, $q, $mdUtil, $mdExpans }; vm.ruleNodeTypesModel = {}; + vm.ruleChainLibraryLoaded = false; for (var type in types.ruleNodeType) { if (!types.ruleNodeType[type].special) { vm.ruleNodeTypesModel[type] = { @@ -141,8 +142,8 @@ export function RuleChainController($stateParams, $scope, $q, $mdUtil, $mdExpans vm.editCallbacks = { edgeDoubleClick: function (event, edge) { var sourceNode = vm.modelservice.nodes.getNodeByConnectorId(edge.source); - if (sourceNode.nodeType != types.ruleNodeType.INPUT.value) { - ruleChainService.getRuleNodeSupportedLinks(sourceNode.type).then( + if (sourceNode.component.type != types.ruleNodeType.INPUT.value) { + ruleChainService.getRuleNodeSupportedLinks(sourceNode.component.clazz).then( (labels) => { vm.isEditingRuleNode = false; vm.editingRuleNode = null; @@ -156,7 +157,7 @@ export function RuleChainController($stateParams, $scope, $q, $mdUtil, $mdExpans }, nodeCallbacks: { 'doubleClick': function (event, node) { - if (node.nodeType != types.ruleNodeType.INPUT.value) { + if (node.component.type != types.ruleNodeType.INPUT.value) { vm.isEditingRuleNodeLink = false; vm.editingRuleNodeLink = null; vm.isEditingRuleNode = true; @@ -171,9 +172,9 @@ export function RuleChainController($stateParams, $scope, $q, $mdUtil, $mdExpans createEdge: function (event, edge) { var deferred = $q.defer(); var sourceNode = vm.modelservice.nodes.getNodeByConnectorId(edge.source); - if (sourceNode.nodeType == types.ruleNodeType.INPUT.value) { + if (sourceNode.component.type == types.ruleNodeType.INPUT.value) { var destNode = vm.modelservice.nodes.getNodeByConnectorId(edge.destination); - if (destNode.nodeType == types.ruleNodeType.RULE_CHAIN.value) { + if (destNode.component.type == types.ruleNodeType.RULE_CHAIN.value) { deferred.reject(); } else { var res = $filter('filter')(vm.ruleChainModel.edges, {source: vm.inputConnectorId}); @@ -183,7 +184,7 @@ export function RuleChainController($stateParams, $scope, $q, $mdUtil, $mdExpans deferred.resolve(edge); } } else { - ruleChainService.getRuleNodeSupportedLinks(sourceNode.type).then( + ruleChainService.getRuleNodeSupportedLinks(sourceNode.component.clazz).then( (labels) => { addRuleNodeLink(event, edge, labels).then( (link) => { @@ -209,24 +210,23 @@ export function RuleChainController($stateParams, $scope, $q, $mdUtil, $mdExpans loadRuleChainLibrary(); function loadRuleChainLibrary() { - ruleChainService.getRuleNodeTypes().then( - (ruleNodeTypes) => { - for (var i=0;i { + for (var i=0;i
- +
{{vm.types.ruleNodeType[typeId].name}}
diff --git a/ui/src/app/rulechain/rulenode-fieldset.tpl.html b/ui/src/app/rulechain/rulenode-fieldset.tpl.html index 2b2faf8257..0d16e45405 100644 --- a/ui/src/app/rulechain/rulenode-fieldset.tpl.html +++ b/ui/src/app/rulechain/rulenode-fieldset.tpl.html @@ -23,9 +23,9 @@
- + -
+
@@ -33,12 +33,17 @@
rulenode.name-required
+ + {{ 'rulenode.debug-mode' | translate }} + + -
+
{{node.icon}}
- {{ node.type }} + {{ node.component.name }} {{ node.name }}