From b0eb57bba24ddf2056fa876ddf1554dc334d2779 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 14 Mar 2018 12:42:12 +0200 Subject: [PATCH] Add Rule Chain Controller --- .../server/controller/BaseController.java | 30 ++++ .../controller/RuleChainController.java | 161 ++++++++++++++++++ .../src/main/resources/thingsboard.yml | 1 + .../server/dao/rule/RuleChainService.java | 2 - 4 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/controller/RuleChainController.java 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 3264af40b7..83b304fb8b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.PluginMetaData; +import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleMetaData; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.widget.WidgetType; @@ -54,6 +55,7 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.dao.plugin.PluginService; import org.thingsboard.server.dao.relation.RelationService; +import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.rule.RuleService; import org.thingsboard.server.dao.user.UserService; import org.thingsboard.server.dao.widget.WidgetTypeService; @@ -118,6 +120,9 @@ public abstract class BaseController { @Autowired protected PluginService pluginService; + @Autowired + protected RuleChainService ruleChainService; + @Autowired protected ActorService actorService; @@ -295,6 +300,9 @@ public abstract class BaseController { case RULE: checkRule(new RuleId(entityId.getId())); return; + case RULE_CHAIN: + checkRuleChain(new RuleChainId(entityId.getId())); + return; case ASSET: checkAsset(assetService.findAssetById(new AssetId(entityId.getId()))); return; @@ -526,6 +534,28 @@ public abstract class BaseController { return rule; } + protected RuleChain checkRuleChain(RuleChainId ruleChainId) throws ThingsboardException { + checkNotNull(ruleChainId); + return checkRuleChain(ruleChainService.findRuleChainById(ruleChainId)); + } + + protected RuleChain checkRuleChain(RuleChain ruleChain) throws ThingsboardException { + checkNotNull(ruleChain); + SecurityUser authUser = getCurrentUser(); + TenantId tenantId = ruleChain.getTenantId(); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + if (authUser.getAuthority() != Authority.SYS_ADMIN) { + if (authUser.getTenantId() == null || + !tenantId.getId().equals(ModelConstants.NULL_UUID) && !authUser.getTenantId().equals(tenantId)) { + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, + ThingsboardErrorCode.PERMISSION_DENIED); + + } + } + return ruleChain; + } + + protected String constructBaseUrl(HttpServletRequest request) { String scheme = request.getScheme(); if (request.getHeader("x-forwarded-proto") != null) { diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java new file mode 100644 index 0000000000..012e0770b3 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -0,0 +1,161 @@ +/** + * Copyright © 2016-2018 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.id.PluginId; +import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.page.TextPageData; +import org.thingsboard.server.common.data.page.TextPageLink; +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import org.thingsboard.server.common.data.plugin.PluginMetaData; +import org.thingsboard.server.common.data.rule.RuleChain; +import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.exception.ThingsboardException; + +import java.util.List; + +@RestController +@RequestMapping("/api") +public class RuleChainController extends BaseController { + + public static final String RULE_CHAIN_ID = "ruleChainId"; + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(value = "/ruleChain/{ruleChainId}", method = RequestMethod.GET) + @ResponseBody + public RuleChain getRuleChainById(@PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { + checkParameter(RULE_CHAIN_ID, strRuleChainId); + try { + RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); + return checkRuleChain(ruleChainId); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(value = "/ruleChain", method = RequestMethod.POST) + @ResponseBody + public RuleChain saveRuleChain(@RequestBody RuleChain ruleChain) throws ThingsboardException { + try { + boolean created = ruleChain.getId() == null; + ruleChain.setTenantId(getCurrentUser().getTenantId()); + RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); + + logEntityAction(savedRuleChain.getId(), savedRuleChain, + null, + created ? ActionType.ADDED : ActionType.UPDATED, null); + + return savedRuleChain; + } catch (Exception e) { + + logEntityAction(emptyId(EntityType.RULE_CHAIN), ruleChain, + null, ruleChain.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e); + + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(value = "/ruleChains", params = {"limit"}, method = RequestMethod.GET) + @ResponseBody + public TextPageData getRuleChains( + @RequestParam int limit, + @RequestParam(required = false) String textSearch, + @RequestParam(required = false) String idOffset, + @RequestParam(required = false) String textOffset) throws ThingsboardException { + try { + TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); + if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) { + return checkNotNull(ruleChainService.findSystemRuleChains(pageLink)); + } else { + TenantId tenantId = getCurrentUser().getTenantId(); + TextPageData ruleChainsData = checkNotNull(ruleChainService.findAllTenantRuleChainsByTenantIdAndPageLink(tenantId, pageLink)); + List ruleChains = ruleChainsData.getData(); + ruleChains.stream() + .filter(ruleChain -> ruleChain.getTenantId().getId().equals(ModelConstants.NULL_UUID)) + .forEach(ruleChain -> ruleChain.setConfiguration(null)); + return ruleChainsData; + } + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAuthority('SYS_ADMIN')") + @RequestMapping(value = "/system/ruleChains", params = {"limit"}, method = RequestMethod.GET) + @ResponseBody + public TextPageData getSystemRuleChains( + @RequestParam int limit, + @RequestParam(required = false) String textSearch, + @RequestParam(required = false) String idOffset, + @RequestParam(required = false) String textOffset) throws ThingsboardException { + try { + TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); + return checkNotNull(ruleChainService.findSystemRuleChains(pageLink)); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/tenant/ruleChains", params = {"limit"}, method = RequestMethod.GET) + @ResponseBody + public TextPageData getTenantRuleChains( + @RequestParam int limit, + @RequestParam(required = false) String textSearch, + @RequestParam(required = false) String idOffset, + @RequestParam(required = false) String textOffset) throws ThingsboardException { + try { + TenantId tenantId = getCurrentUser().getTenantId(); + TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); + return checkNotNull(ruleChainService.findTenantRuleChains(tenantId, pageLink)); + } catch (Exception e) { + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") + @RequestMapping(value = "/ruleChain/{ruleChainId}", method = RequestMethod.DELETE) + @ResponseStatus(value = HttpStatus.OK) + public void deleteRuleChain(@PathVariable(RULE_CHAIN_ID) String strRuleChainId) throws ThingsboardException { + checkParameter(RULE_CHAIN_ID, strRuleChainId); + try { + RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); + RuleChain ruleChain = checkRuleChain(ruleChainId); + ruleChainService.deleteRuleChainById(ruleChainId); + + logEntityAction(ruleChainId, ruleChain, + null, + ActionType.DELETED, null, strRuleChainId); + + } catch (Exception e) { + logEntityAction(emptyId(EntityType.RULE_CHAIN), + null, + null, + ActionType.DELETED, e, strRuleChainId); + throw handleException(e); + } + } + +} diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 2369d01dc7..1c842c8a1b 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -327,6 +327,7 @@ audit_log: "user": "${AUDIT_LOG_MASK_USER:W}" "rule": "${AUDIT_LOG_MASK_RULE:W}" "plugin": "${AUDIT_LOG_MASK_PLUGIN:W}" + "rule_chain": "${AUDIT_LOG_MASK_RULE_CHAIN:W}" sink: # Type of external sink. possible options: none, elasticsearch type: "${AUDIT_LOG_SINK_TYPE:none}" diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java index c6a2941938..6c44090564 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/RuleChainService.java @@ -16,13 +16,11 @@ package org.thingsboard.server.dao.rule; -import org.thingsboard.server.common.data.id.PluginId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.TextPageData; import org.thingsboard.server.common.data.page.TextPageLink; -import org.thingsboard.server.common.data.plugin.PluginMetaData; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChainMetaData;