diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 2c171e8ca6..5003aac526 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -145,7 +145,7 @@ public class AlarmController extends BaseController { public Boolean deleteAlarm(@ApiParam(value = ALARM_ID_PARAM_DESCRIPTION) @PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { checkParameter(ALARM_ID, strAlarmId); AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); - Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); + Alarm alarm = checkAlarmId(alarmId, Operation.DELETE); return tbAlarmService.delete(alarm, getCurrentUser()); } diff --git a/application/src/main/java/org/thingsboard/server/controller/AutoCommitController.java b/application/src/main/java/org/thingsboard/server/controller/AutoCommitController.java new file mode 100644 index 0000000000..1a097e6817 --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/controller/AutoCommitController.java @@ -0,0 +1,42 @@ +/** + * Copyright © 2016-2022 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 com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import org.springframework.beans.factory.annotation.Autowired; +import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.service.sync.vc.EntitiesVersionControlService; + +import java.util.UUID; + +public class AutoCommitController extends BaseController { + + @Autowired + private EntitiesVersionControlService vcService; + + protected ListenableFuture autoCommit(User user, EntityId entityId) throws Exception { + if (vcService != null) { + return vcService.autoCommit(user, entityId); + } else { + // We do not support auto-commit for rule engine + return Futures.immediateFailedFuture(new RuntimeException("Operation not supported!")); + } + } + + +} diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java index f7aeeb08b1..7d5de91890 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java @@ -139,7 +139,7 @@ public class EntityViewController extends BaseController { @ResponseBody public EntityView saveEntityView( @ApiParam(value = "A JSON object representing the entity view.") - @RequestBody EntityView entityView) throws ThingsboardException { + @RequestBody EntityView entityView) throws Exception { entityView.setTenantId(getCurrentUser().getTenantId()); EntityView existingEntityView = null; if (entityView.getId() == null) { diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java index 35791ea762..71ea889c03 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java @@ -36,6 +36,7 @@ import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.widget.WidgetType; import org.thingsboard.server.common.data.widget.WidgetTypeDetails; import org.thingsboard.server.common.data.widget.WidgetTypeInfo; +import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.permission.Operation; @@ -52,7 +53,7 @@ import static org.thingsboard.server.controller.ControllerConstants.WIDGET_TYPE_ @RestController @TbCoreComponent @RequestMapping("/api") -public class WidgetTypeController extends BaseController { +public class WidgetTypeController extends AutoCommitController { private static final String WIDGET_TYPE_DESCRIPTION = "Widget Type represents the template for widget creation. Widget Type and Widget are similar to class and object in OOP theory."; private static final String WIDGET_TYPE_DETAILS_DESCRIPTION = "Widget Type Details extend Widget Type and add image and description properties. " + @@ -93,15 +94,23 @@ public class WidgetTypeController extends BaseController { @ApiParam(value = "A JSON value representing the Widget Type Details.", required = true) @RequestBody WidgetTypeDetails widgetTypeDetails) throws ThingsboardException { try { - if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { + var currentUser = getCurrentUser(); + if (Authority.SYS_ADMIN.equals(currentUser.getAuthority())) { widgetTypeDetails.setTenantId(TenantId.SYS_TENANT_ID); } else { - widgetTypeDetails.setTenantId(getCurrentUser().getTenantId()); + widgetTypeDetails.setTenantId(currentUser.getTenantId()); } checkEntity(widgetTypeDetails.getId(), widgetTypeDetails, Resource.WIDGET_TYPE); WidgetTypeDetails savedWidgetTypeDetails = widgetTypeService.saveWidgetType(widgetTypeDetails); + if (!Authority.SYS_ADMIN.equals(currentUser.getAuthority())) { + WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(widgetTypeDetails.getTenantId(), widgetTypeDetails.getBundleAlias()); + if (widgetsBundle != null) { + autoCommit(currentUser, widgetsBundle.getId()); + } + } + sendEntityNotificationMsg(getTenantId(), savedWidgetTypeDetails.getId(), widgetTypeDetails.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); @@ -121,9 +130,17 @@ public class WidgetTypeController extends BaseController { @PathVariable("widgetTypeId") String strWidgetTypeId) throws ThingsboardException { checkParameter("widgetTypeId", strWidgetTypeId); try { + var currentUser = getCurrentUser(); WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); - checkWidgetTypeId(widgetTypeId, Operation.DELETE); - widgetTypeService.deleteWidgetType(getCurrentUser().getTenantId(), widgetTypeId); + WidgetTypeDetails wtd = checkWidgetTypeId(widgetTypeId, Operation.DELETE); + widgetTypeService.deleteWidgetType(currentUser.getTenantId(), widgetTypeId); + + if (wtd != null && !Authority.SYS_ADMIN.equals(currentUser.getAuthority())) { + WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(wtd.getTenantId(), wtd.getBundleAlias()); + if (widgetsBundle != null) { + autoCommit(currentUser, widgetsBundle.getId()); + } + } sendEntityNotificationMsg(getTenantId(), widgetTypeId, EdgeEventActionType.DELETED); diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java index 68a9b489f7..2d51c3dee8 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java @@ -96,16 +96,17 @@ public class WidgetsBundleController extends BaseController { @ResponseBody public WidgetsBundle saveWidgetsBundle( @ApiParam(value = "A JSON value representing the Widget Bundle.", required = true) - @RequestBody WidgetsBundle widgetsBundle) throws ThingsboardException { - if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { + @RequestBody WidgetsBundle widgetsBundle) throws Exception { + var currentUser = getCurrentUser(); + if (Authority.SYS_ADMIN.equals(currentUser.getAuthority())) { widgetsBundle.setTenantId(TenantId.SYS_TENANT_ID); } else { - widgetsBundle.setTenantId(getCurrentUser().getTenantId()); + widgetsBundle.setTenantId(currentUser.getTenantId()); } checkEntity(widgetsBundle.getId(), widgetsBundle, Resource.WIDGETS_BUNDLE); - return tbWidgetsBundleService.save(widgetsBundle); + return tbWidgetsBundleService.save(widgetsBundle, currentUser); } @ApiOperation(value = "Delete widgets bundle (deleteWidgetsBundle)", diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java index 22bf93cd2c..0e66e365da 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/AbstractTbEntityService.java @@ -141,4 +141,13 @@ public abstract class AbstractTbEntityService { return Futures.immediateFailedFuture(new RuntimeException("Operation not supported!")); } } + + protected ListenableFuture autoCommit(User user, EntityType entityType, List entityIds) throws Exception { + if (vcService != null) { + return vcService.autoCommit(user, entityType, entityIds); + } else { + // We do not support auto-commit for rule engine + return Futures.immediateFailedFuture(new RuntimeException("Operation not supported!")); + } + } } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java index 2848a4e97b..e098d6b605 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/DefaultTbEntityViewService.java @@ -74,12 +74,13 @@ public class DefaultTbEntityViewService extends AbstractTbEntityService implemen final Map>> localCache = new ConcurrentHashMap<>(); @Override - public EntityView save(EntityView entityView, EntityView existingEntityView, User user) throws ThingsboardException { + public EntityView save(EntityView entityView, EntityView existingEntityView, User user) throws Exception { ActionType actionType = entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED; TenantId tenantId = entityView.getTenantId(); try { EntityView savedEntityView = checkNotNull(entityViewService.saveEntityView(entityView)); this.updateEntityViewAttributes(tenantId, savedEntityView, existingEntityView, user); + autoCommit(user, savedEntityView.getId()); notificationEntityService.notifyCreateOrUpdateEntity(savedEntityView.getTenantId(), savedEntityView.getId(), savedEntityView, null, actionType, user); localCache.computeIfAbsent(savedEntityView.getTenantId(), (k) -> new ConcurrentReferenceHashMap<>()).clear(); diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/TbEntityViewService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/TbEntityViewService.java index 28ead13853..c4dbedd2eb 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/TbEntityViewService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/entityview/TbEntityViewService.java @@ -31,7 +31,7 @@ import java.util.List; public interface TbEntityViewService extends ComponentLifecycleListener { - EntityView save(EntityView entityView, EntityView existingEntityView, User user) throws ThingsboardException; + EntityView save(EntityView entityView, EntityView existingEntityView, User user) throws Exception; void updateEntityViewAttributes(TenantId tenantId, EntityView savedEntityView, EntityView oldEntityView, User user) throws ThingsboardException; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java index 496150d000..1706598b9c 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.entitiy.widgets.bundle; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.widget.WidgetsBundle; @@ -32,8 +33,9 @@ public class DefaultWidgetsBundleService extends AbstractTbEntityService impleme private final WidgetsBundleService widgetsBundleService; @Override - public WidgetsBundle save(WidgetsBundle widgetsBundle) throws ThingsboardException { + public WidgetsBundle save(WidgetsBundle widgetsBundle, User user) throws Exception { WidgetsBundle savedWidgetsBundle = checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); + autoCommit(user, savedWidgetsBundle.getId()); notificationEntityService.notifySendMsgToEdgeService(widgetsBundle.getTenantId(), savedWidgetsBundle.getId(), widgetsBundle.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); return savedWidgetsBundle; diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/TbWidgetsBundleService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/TbWidgetsBundleService.java index 89022ad7a5..2820934aa3 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/TbWidgetsBundleService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/TbWidgetsBundleService.java @@ -15,11 +15,13 @@ */ package org.thingsboard.server.service.entitiy.widgets.bundle; +import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.widget.WidgetsBundle; public interface TbWidgetsBundleService { - WidgetsBundle save(WidgetsBundle entity) throws ThingsboardException; + + WidgetsBundle save(WidgetsBundle entity, User currentUser) throws Exception; void delete(WidgetsBundle entity) throws ThingsboardException; } diff --git a/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java b/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java index 90083e3089..5bf7d7415c 100644 --- a/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java +++ b/application/src/main/java/org/thingsboard/server/service/rule/DefaultTbRuleChainService.java @@ -176,7 +176,7 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement ActionType actionType = ruleChain.getId() == null ? ActionType.ADDED : ActionType.UPDATED; try { RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain)); - vcService.autoCommit(user, savedRuleChain.getId()); + autoCommit(user, savedRuleChain.getId()); if (RuleChainType.CORE.equals(savedRuleChain.getType())) { tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedRuleChain.getId(), @@ -229,7 +229,7 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement public RuleChain saveDefaultByName(TenantId tenantId, DefaultRuleChainCreateRequest request, User user) throws Exception { try { RuleChain savedRuleChain = installScripts.createDefaultRuleChain(tenantId, request.getName()); - vcService.autoCommit(user, savedRuleChain.getId()); + autoCommit(user, savedRuleChain.getId()); tbClusterService.broadcastEntityStateChangeEvent(tenantId, savedRuleChain.getId(), ComponentLifecycleEvent.CREATED); notificationEntityService.logEntityAction(tenantId, savedRuleChain.getId(), savedRuleChain, ActionType.ADDED, user); return savedRuleChain; @@ -288,12 +288,12 @@ public class DefaultTbRuleChainService extends AbstractTbEntityService implement } if (updatedRuleChains.isEmpty()) { - vcService.autoCommit(user, ruleChainMetaData.getRuleChainId()); + autoCommit(user, ruleChainMetaData.getRuleChainId()); } else { List uuids = new ArrayList<>(updatedRuleChains.size() + 1); uuids.add(ruleChainMetaData.getRuleChainId().getId()); updatedRuleChains.forEach(rc -> uuids.add(rc.getId().getId())); - vcService.autoCommit(user, EntityType.RULE_CHAIN, uuids); + autoCommit(user, EntityType.RULE_CHAIN, uuids); } RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.loadRuleChainMetaData(tenantId, ruleChainMetaDataId));