Entities export/import API refactoring: permission checks and entity lifecycle events
This commit is contained in:
		
							parent
							
								
									4062dc70fb
								
							
						
					
					
						commit
						849513541e
					
				@ -156,7 +156,7 @@ public class AssetController extends BaseController {
 | 
			
		||||
 | 
			
		||||
            Asset savedAsset = checkNotNull(assetService.saveAsset(asset));
 | 
			
		||||
 | 
			
		||||
            onAssetCreatedOrUpdated(savedAsset, asset.getId() != null, getCurrentUser());
 | 
			
		||||
            onEntityUpdatedOrCreated(getCurrentUser(), savedAsset, null, asset.getId() == null);
 | 
			
		||||
 | 
			
		||||
            return savedAsset;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -166,20 +166,6 @@ public class AssetController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void onAssetCreatedOrUpdated(Asset asset, boolean updated, SecurityUser user) {
 | 
			
		||||
        try {
 | 
			
		||||
            logEntityAction(user, asset.getId(), asset,
 | 
			
		||||
                    asset.getCustomerId(),
 | 
			
		||||
                    updated ? ActionType.UPDATED : ActionType.ADDED, null);
 | 
			
		||||
        } catch (ThingsboardException e) {
 | 
			
		||||
            log.error("Failed to log entity action", e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (updated) {
 | 
			
		||||
            sendEntityNotificationMsg(asset.getTenantId(), asset.getId(), EdgeEventActionType.UPDATED);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ApiOperation(value = "Delete asset (deleteAsset)",
 | 
			
		||||
            notes = "Deletes the asset and all the relations (from and to the asset). Referencing non-existing asset Id will cause an error." + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
 | 
			
		||||
    @PreAuthorize("hasAuthority('TENANT_ADMIN')")
 | 
			
		||||
@ -681,7 +667,7 @@ public class AssetController extends BaseController {
 | 
			
		||||
    public BulkImportResult<Asset> processAssetsBulkImport(@RequestBody BulkImportRequest request) throws Exception {
 | 
			
		||||
        SecurityUser user = getCurrentUser();
 | 
			
		||||
        return assetBulkImportService.processBulkImport(request, user, importedAssetInfo -> {
 | 
			
		||||
            onAssetCreatedOrUpdated(importedAssetInfo.getEntity(), importedAssetInfo.isUpdated(), user);
 | 
			
		||||
            onEntityUpdatedOrCreated(user, importedAssetInfo.getEntity(), importedAssetInfo.getOldEntity(), !importedAssetInfo.isUpdated());
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityView;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityViewInfo;
 | 
			
		||||
import org.thingsboard.server.common.data.HasCustomerId;
 | 
			
		||||
import org.thingsboard.server.common.data.HasName;
 | 
			
		||||
import org.thingsboard.server.common.data.HasTenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.OtaPackage;
 | 
			
		||||
@ -68,6 +69,7 @@ import org.thingsboard.server.common.data.id.EdgeId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityViewId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.OtaPackageId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.RpcId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.RuleChainId;
 | 
			
		||||
@ -83,6 +85,7 @@ import org.thingsboard.server.common.data.page.PageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.page.SortOrder;
 | 
			
		||||
import org.thingsboard.server.common.data.page.TimePageLink;
 | 
			
		||||
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
 | 
			
		||||
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
 | 
			
		||||
import org.thingsboard.server.common.data.plugin.ComponentType;
 | 
			
		||||
import org.thingsboard.server.common.data.relation.EntityRelation;
 | 
			
		||||
import org.thingsboard.server.common.data.rpc.Rpc;
 | 
			
		||||
@ -141,6 +144,7 @@ import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
@ -919,4 +923,62 @@ public abstract class BaseController {
 | 
			
		||||
            return MediaType.APPLICATION_OCTET_STREAM;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public <E extends HasName & HasId<I> & HasTenantId, I extends EntityId> void onEntityUpdatedOrCreated(User user, E savedEntity, E oldEntity, boolean isNewEntity) {
 | 
			
		||||
        boolean notifyEdge = false;
 | 
			
		||||
 | 
			
		||||
        EntityType entityType = savedEntity.getId().getEntityType();
 | 
			
		||||
        switch (entityType) {
 | 
			
		||||
            case DEVICE:
 | 
			
		||||
                tbClusterService.onDeviceUpdated((Device) savedEntity, (Device) oldEntity);
 | 
			
		||||
                break;
 | 
			
		||||
            case DEVICE_PROFILE:
 | 
			
		||||
                DeviceProfile deviceProfile = (DeviceProfile) savedEntity;
 | 
			
		||||
                DeviceProfile oldDeviceProfile = (DeviceProfile) oldEntity;
 | 
			
		||||
                boolean isFirmwareChanged = false;
 | 
			
		||||
                boolean isSoftwareChanged = false;
 | 
			
		||||
                if (!isNewEntity) {
 | 
			
		||||
                    if (!Objects.equals(deviceProfile.getFirmwareId(), oldDeviceProfile.getFirmwareId())) {
 | 
			
		||||
                        isFirmwareChanged = true;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!Objects.equals(deviceProfile.getSoftwareId(), oldDeviceProfile.getSoftwareId())) {
 | 
			
		||||
                        isSoftwareChanged = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                tbClusterService.onDeviceProfileChange(deviceProfile, null);
 | 
			
		||||
                tbClusterService.broadcastEntityStateChangeEvent(deviceProfile.getTenantId(), deviceProfile.getId(),
 | 
			
		||||
                        isNewEntity ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
 | 
			
		||||
                otaPackageStateService.update(deviceProfile, isFirmwareChanged, isSoftwareChanged);
 | 
			
		||||
                notifyEdge = true;
 | 
			
		||||
                break;
 | 
			
		||||
            case RULE_CHAIN: // FIXME: events for rule chain metadata
 | 
			
		||||
                RuleChainType ruleChainType = ((RuleChain) savedEntity).getType();
 | 
			
		||||
                if (RuleChainType.CORE.equals(ruleChainType)) {
 | 
			
		||||
                    tbClusterService.broadcastEntityStateChangeEvent(savedEntity.getTenantId(), savedEntity.getId(),
 | 
			
		||||
                            isNewEntity ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
 | 
			
		||||
                }
 | 
			
		||||
                if (RuleChainType.EDGE.equals(ruleChainType)) {
 | 
			
		||||
                    if (!isNewEntity) {
 | 
			
		||||
                        notifyEdge = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case ASSET:
 | 
			
		||||
            case CUSTOMER:
 | 
			
		||||
            case DASHBOARD:
 | 
			
		||||
                if (!isNewEntity) {
 | 
			
		||||
                    notifyEdge = true;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new UnsupportedOperationException();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        entityActionService.logEntityAction(user, savedEntity.getId(), savedEntity, savedEntity instanceof HasCustomerId ? ((HasCustomerId) savedEntity).getCustomerId() : null,
 | 
			
		||||
                isNewEntity ? ActionType.ADDED : ActionType.UPDATED, null);
 | 
			
		||||
        if (notifyEdge) {
 | 
			
		||||
            sendEntityNotificationMsg(savedEntity.getTenantId(), savedEntity.getId(), isNewEntity ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -33,7 +33,6 @@ import org.springframework.web.bind.annotation.RestController;
 | 
			
		||||
import org.thingsboard.server.common.data.Customer;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.audit.ActionType;
 | 
			
		||||
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
			
		||||
import org.thingsboard.server.common.data.id.CustomerId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EdgeId;
 | 
			
		||||
@ -151,14 +150,7 @@ public class CustomerController extends BaseController {
 | 
			
		||||
            checkEntity(customer.getId(), customer, Resource.CUSTOMER);
 | 
			
		||||
 | 
			
		||||
            Customer savedCustomer = checkNotNull(customerService.saveCustomer(customer));
 | 
			
		||||
 | 
			
		||||
            logEntityAction(savedCustomer.getId(), savedCustomer,
 | 
			
		||||
                    savedCustomer.getId(),
 | 
			
		||||
                    customer.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
 | 
			
		||||
 | 
			
		||||
            if (customer.getId() != null) {
 | 
			
		||||
                sendEntityNotificationMsg(savedCustomer.getTenantId(), savedCustomer.getId(), EdgeEventActionType.UPDATED);
 | 
			
		||||
            }
 | 
			
		||||
            onEntityUpdatedOrCreated(getCurrentUser(), savedCustomer, null, customer.getId() == null);
 | 
			
		||||
 | 
			
		||||
            return savedCustomer;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
 | 
			
		||||
@ -187,13 +187,7 @@ public class DashboardController extends BaseController {
 | 
			
		||||
 | 
			
		||||
            Dashboard savedDashboard = checkNotNull(dashboardService.saveDashboard(dashboard));
 | 
			
		||||
 | 
			
		||||
            logEntityAction(savedDashboard.getId(), savedDashboard,
 | 
			
		||||
                    null,
 | 
			
		||||
                    dashboard.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
 | 
			
		||||
 | 
			
		||||
            if (dashboard.getId() != null) {
 | 
			
		||||
                sendEntityNotificationMsg(savedDashboard.getTenantId(), savedDashboard.getId(), EdgeEventActionType.UPDATED);
 | 
			
		||||
            }
 | 
			
		||||
            onEntityUpdatedOrCreated(getCurrentUser(), savedDashboard, null, dashboard.getId() == null);
 | 
			
		||||
 | 
			
		||||
            return savedDashboard;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
 | 
			
		||||
@ -195,7 +195,7 @@ public class DeviceController extends BaseController {
 | 
			
		||||
 | 
			
		||||
            Device savedDevice = checkNotNull(deviceService.saveDeviceWithAccessToken(device, accessToken));
 | 
			
		||||
 | 
			
		||||
            onDeviceCreatedOrUpdated(savedDevice, oldDevice, !created, getCurrentUser());
 | 
			
		||||
            onEntityUpdatedOrCreated(getCurrentUser(), savedDevice, oldDevice, created);
 | 
			
		||||
 | 
			
		||||
            return savedDevice;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -224,10 +224,8 @@ public class DeviceController extends BaseController {
 | 
			
		||||
            checkEntity(device.getId(), device, Resource.DEVICE);
 | 
			
		||||
            Device savedDevice = deviceService.saveDeviceWithCredentials(device, credentials);
 | 
			
		||||
            checkNotNull(savedDevice);
 | 
			
		||||
            tbClusterService.onDeviceUpdated(savedDevice, device);
 | 
			
		||||
            logEntityAction(savedDevice.getId(), savedDevice,
 | 
			
		||||
                    savedDevice.getCustomerId(),
 | 
			
		||||
                    device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
 | 
			
		||||
 | 
			
		||||
            onEntityUpdatedOrCreated(getCurrentUser(), savedDevice, device, device.getId() == null);
 | 
			
		||||
 | 
			
		||||
            return savedDevice;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -237,18 +235,6 @@ public class DeviceController extends BaseController {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void onDeviceCreatedOrUpdated(Device savedDevice, Device oldDevice, boolean updated, SecurityUser user) {
 | 
			
		||||
        tbClusterService.onDeviceUpdated(savedDevice, oldDevice);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            logEntityAction(user, savedDevice.getId(), savedDevice,
 | 
			
		||||
                    savedDevice.getCustomerId(),
 | 
			
		||||
                    updated ? ActionType.UPDATED : ActionType.ADDED, null);
 | 
			
		||||
        } catch (ThingsboardException e) {
 | 
			
		||||
            log.error("Failed to log entity action", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ApiOperation(value = "Delete device (deleteDevice)",
 | 
			
		||||
            notes = "Deletes the device, it's credentials and all the relations (from and to the device). Referencing non-existing device Id will cause an error." + TENANT_AUTHORITY_PARAGRAPH)
 | 
			
		||||
    @PreAuthorize("hasAuthority('TENANT_ADMIN')")
 | 
			
		||||
@ -1015,7 +1001,7 @@ public class DeviceController extends BaseController {
 | 
			
		||||
    public BulkImportResult<Device> processDevicesBulkImport(@RequestBody BulkImportRequest request) throws Exception {
 | 
			
		||||
        SecurityUser user = getCurrentUser();
 | 
			
		||||
        return deviceBulkImportService.processBulkImport(request, user, importedDeviceInfo -> {
 | 
			
		||||
            onDeviceCreatedOrUpdated(importedDeviceInfo.getEntity(), importedDeviceInfo.getOldEntity(), importedDeviceInfo.isUpdated(), user);
 | 
			
		||||
            onEntityUpdatedOrCreated(user, importedDeviceInfo.getEntity(), importedDeviceInfo.getOldEntity(), !importedDeviceInfo.isUpdated());
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,6 @@ import org.thingsboard.server.service.security.permission.Operation;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.Resource;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.server.controller.ControllerConstants.DEVICE_PROFILE_DATA;
 | 
			
		||||
@ -207,32 +206,14 @@ public class DeviceProfileController extends BaseController {
 | 
			
		||||
 | 
			
		||||
            checkEntity(deviceProfile.getId(), deviceProfile, Resource.DEVICE_PROFILE);
 | 
			
		||||
 | 
			
		||||
            boolean isFirmwareChanged = false;
 | 
			
		||||
            boolean isSoftwareChanged = false;
 | 
			
		||||
 | 
			
		||||
            DeviceProfile oldDeviceProfile = null;
 | 
			
		||||
            if (!created) {
 | 
			
		||||
                DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(getTenantId(), deviceProfile.getId());
 | 
			
		||||
                if (!Objects.equals(deviceProfile.getFirmwareId(), oldDeviceProfile.getFirmwareId())) {
 | 
			
		||||
                    isFirmwareChanged = true;
 | 
			
		||||
                }
 | 
			
		||||
                if (!Objects.equals(deviceProfile.getSoftwareId(), oldDeviceProfile.getSoftwareId())) {
 | 
			
		||||
                    isSoftwareChanged = true;
 | 
			
		||||
                }
 | 
			
		||||
                oldDeviceProfile = deviceProfileService.findDeviceProfileById(getTenantId(), deviceProfile.getId());
 | 
			
		||||
            }
 | 
			
		||||
            DeviceProfile savedDeviceProfile = checkNotNull(deviceProfileService.saveDeviceProfile(deviceProfile));
 | 
			
		||||
 | 
			
		||||
            tbClusterService.onDeviceProfileChange(savedDeviceProfile, null);
 | 
			
		||||
            tbClusterService.broadcastEntityStateChangeEvent(deviceProfile.getTenantId(), savedDeviceProfile.getId(),
 | 
			
		||||
                    created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
 | 
			
		||||
            onEntityUpdatedOrCreated(getCurrentUser(), deviceProfile, oldDeviceProfile, created);
 | 
			
		||||
 | 
			
		||||
            logEntityAction(savedDeviceProfile.getId(), savedDeviceProfile,
 | 
			
		||||
                    null,
 | 
			
		||||
                    created ? ActionType.ADDED : ActionType.UPDATED, null);
 | 
			
		||||
 | 
			
		||||
            otaPackageStateService.update(savedDeviceProfile, isFirmwareChanged, isSoftwareChanged);
 | 
			
		||||
 | 
			
		||||
            sendEntityNotificationMsg(getTenantId(), savedDeviceProfile.getId(),
 | 
			
		||||
                    deviceProfile.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED);
 | 
			
		||||
            return savedDeviceProfile;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            logEntityAction(emptyId(EntityType.DEVICE_PROFILE), deviceProfile,
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.thingsboard.server.controller;
 | 
			
		||||
 | 
			
		||||
import io.swagger.annotations.ApiParam;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import org.springframework.security.access.prepost.PreAuthorize;
 | 
			
		||||
import org.springframework.web.bind.annotation.PathVariable;
 | 
			
		||||
@ -23,21 +24,20 @@ import org.springframework.web.bind.annotation.RequestBody;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.RestController;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.HasName;
 | 
			
		||||
import org.thingsboard.server.common.data.HasTenantId;
 | 
			
		||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
 | 
			
		||||
import org.thingsboard.server.common.data.export.EntitiesExportRequest;
 | 
			
		||||
import org.thingsboard.server.common.data.export.EntitiesExportResponse;
 | 
			
		||||
import org.thingsboard.server.common.data.export.EntityExportData;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityIdFactory;
 | 
			
		||||
import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.expimp.EntitiesExportImportService;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
import org.thingsboard.server.service.security.model.SecurityUser;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.Operation;
 | 
			
		||||
import org.thingsboard.server.service.security.permission.Resource;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
@RestController
 | 
			
		||||
@ -51,49 +51,69 @@ public class EntitiesExportImportController extends BaseController {
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/export/{entityType}/{entityId}")
 | 
			
		||||
    @PreAuthorize("hasAuthority('TENANT_ADMIN')")
 | 
			
		||||
    public EntityExportData<?> exportEntity(@PathVariable EntityType entityType,
 | 
			
		||||
    public EntityExportData<?> exportEntity(@ApiParam(allowableValues = "DEVICE, DEVICE_PROFILE, ASSET, RULE_CHAIN, DASHBOARD, CUSTOMER") @PathVariable EntityType entityType,
 | 
			
		||||
                                            @PathVariable("entityId") UUID entityUuid) throws ThingsboardException {
 | 
			
		||||
        EntityId entityId = EntityIdFactory.getByTypeAndUuid(entityType, entityUuid);
 | 
			
		||||
        try {
 | 
			
		||||
            return exportImportService.exportEntity(getTenantId(), entityId);
 | 
			
		||||
            return exportEntity(getCurrentUser(), entityId);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw handleException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/export/batch")
 | 
			
		||||
    @PreAuthorize("hasAuthority('TENANT_ADMIN')")
 | 
			
		||||
    public EntitiesExportResponse exportEntities(@RequestBody EntitiesExportRequest exportRequest) throws ThingsboardException {
 | 
			
		||||
        TenantId tenantId = getTenantId();
 | 
			
		||||
 | 
			
		||||
        EntitiesExportResponse exportResponse = new EntitiesExportResponse();
 | 
			
		||||
 | 
			
		||||
        Map<EntityType, List<EntityExportData<HasId<EntityId>>>> result = new HashMap<>();
 | 
			
		||||
        exportRequest.getEntities().forEach((entityType, entityIds) -> {
 | 
			
		||||
            List<EntityExportData<HasId<EntityId>>> exportDataForEntityType = new LinkedList<>();
 | 
			
		||||
            entityIds.forEach(entityId -> {
 | 
			
		||||
                EntityExportData<HasId<EntityId>> exportData = exportImportService.exportEntity(tenantId, entityId);
 | 
			
		||||
                exportDataForEntityType.add(exportData);
 | 
			
		||||
            });
 | 
			
		||||
            result.put(entityType, exportDataForEntityType);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        exportResponse.setExportData(result);
 | 
			
		||||
        return exportResponse;
 | 
			
		||||
    }
 | 
			
		||||
//    @PostMapping("/export/batch")
 | 
			
		||||
//    @PreAuthorize("hasAuthority('TENANT_ADMIN')")
 | 
			
		||||
//    public EntitiesExportResponse exportEntities(@RequestBody EntitiesExportRequest exportRequest) throws ThingsboardException {
 | 
			
		||||
//        TenantId tenantId = getTenantId();
 | 
			
		||||
//
 | 
			
		||||
//        EntitiesExportResponse exportResponse = new EntitiesExportResponse();
 | 
			
		||||
//
 | 
			
		||||
//        Map<EntityType, List<EntityExportData<HasId<EntityId>>>> result = new HashMap<>();
 | 
			
		||||
//        exportRequest.getEntities().forEach((entityType, entityIds) -> {
 | 
			
		||||
//            List<EntityExportData<HasId<EntityId>>> exportDataForEntityType = new LinkedList<>();
 | 
			
		||||
//            entityIds.forEach(entityId -> {
 | 
			
		||||
//                EntityExportData<HasId<EntityId>> exportData = exportImportService.exportEntity(tenantId, entityId);
 | 
			
		||||
//                exportDataForEntityType.add(exportData);
 | 
			
		||||
//            });
 | 
			
		||||
//            result.put(entityType, exportDataForEntityType);
 | 
			
		||||
//        });
 | 
			
		||||
//
 | 
			
		||||
//        exportResponse.setExportData(result);
 | 
			
		||||
//        return exportResponse;
 | 
			
		||||
//    }
 | 
			
		||||
    // TODO: export and import of batches
 | 
			
		||||
    // TODO: api to export and import whole customer, whole tenant
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/import")
 | 
			
		||||
    @PreAuthorize("hasAuthority('TENANT_ADMIN')")
 | 
			
		||||
    public <E extends HasId<I>, I extends EntityId, D extends EntityExportData<E>> E importEntity(@RequestBody D exportData) throws ThingsboardException {
 | 
			
		||||
    public <E extends HasId<I> & HasName & HasTenantId, I extends EntityId, D extends EntityExportData<E>> EntityImportResult<E> importEntity(@RequestBody D exportData) throws ThingsboardException {
 | 
			
		||||
        try {
 | 
			
		||||
            return exportImportService.importEntity(getTenantId(), exportData);
 | 
			
		||||
            return importEntity(getCurrentUser(), exportData);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            throw handleException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    public void importEntities(@RequestBody )
 | 
			
		||||
 | 
			
		||||
    private <E extends HasId<I>, I extends EntityId> EntityExportData<HasId<EntityId>> exportEntity(SecurityUser user, I entityId) throws ThingsboardException {
 | 
			
		||||
        checkEntityId(entityId, Operation.READ);
 | 
			
		||||
        return exportImportService.exportEntity(getTenantId(), entityId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <E extends HasId<I> & HasName & HasTenantId, I extends EntityId, D extends EntityExportData<E>> EntityImportResult<E> importEntity(SecurityUser user, D exportData) throws ThingsboardException {
 | 
			
		||||
        E existingEntity = exportImportService.findEntityByExternalId(user.getTenantId(), exportData.getMainEntity().getId());
 | 
			
		||||
        if (existingEntity != null) {
 | 
			
		||||
            checkEntityId(existingEntity.getId(), Operation.WRITE); // todo maybe need to extract permission check to BaseController and put there permission checks from other controllers
 | 
			
		||||
        } else {
 | 
			
		||||
            checkEntity(null, exportData.getMainEntity(), Resource.of(exportData.getEntityType()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        EntityImportResult<E> importResult = exportImportService.importEntity(getTenantId(), exportData);
 | 
			
		||||
        onEntityUpdatedOrCreated(user, importResult.getSavedEntity(), importResult.getOldEntity(), importResult.getOldEntity() == null);
 | 
			
		||||
 | 
			
		||||
        return importResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -78,11 +78,9 @@ import org.thingsboard.server.service.security.permission.Resource;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.TreeSet;
 | 
			
		||||
import java.util.concurrent.ConcurrentMap;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
@ -254,20 +252,7 @@ public class RuleChainController extends BaseController {
 | 
			
		||||
 | 
			
		||||
            RuleChain savedRuleChain = checkNotNull(ruleChainService.saveRuleChain(ruleChain));
 | 
			
		||||
 | 
			
		||||
            if (RuleChainType.CORE.equals(savedRuleChain.getType())) {
 | 
			
		||||
                tbClusterService.broadcastEntityStateChangeEvent(ruleChain.getTenantId(), savedRuleChain.getId(),
 | 
			
		||||
                        created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            logEntityAction(savedRuleChain.getId(), savedRuleChain,
 | 
			
		||||
                    null,
 | 
			
		||||
                    created ? ActionType.ADDED : ActionType.UPDATED, null);
 | 
			
		||||
 | 
			
		||||
            if (RuleChainType.EDGE.equals(savedRuleChain.getType())) {
 | 
			
		||||
                if (!created) {
 | 
			
		||||
                    sendEntityNotificationMsg(savedRuleChain.getTenantId(), savedRuleChain.getId(), EdgeEventActionType.UPDATED);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            onEntityUpdatedOrCreated(getCurrentUser(), savedRuleChain, null, created);
 | 
			
		||||
 | 
			
		||||
            return savedRuleChain;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
@ -294,6 +279,7 @@ public class RuleChainController extends BaseController {
 | 
			
		||||
 | 
			
		||||
            RuleChain savedRuleChain = installScripts.createDefaultRuleChain(getCurrentUser().getTenantId(), request.getName());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            tbClusterService.broadcastEntityStateChangeEvent(savedRuleChain.getTenantId(), savedRuleChain.getId(), ComponentLifecycleEvent.CREATED);
 | 
			
		||||
 | 
			
		||||
            logEntityAction(savedRuleChain.getId(), savedRuleChain, null, ActionType.ADDED, null);
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,9 @@ import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.expimp.exp.EntityExportService;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportService;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.impl.AbstractEntityImportService;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.EnumMap;
 | 
			
		||||
@ -51,16 +53,21 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // FIXME: somehow validate export data
 | 
			
		||||
    // FIXME: validate permissions for create or update
 | 
			
		||||
    // FIXME: send entity lifecycle event
 | 
			
		||||
    @Override
 | 
			
		||||
    public <E extends HasId<I>, I extends EntityId, D extends EntityExportData<E>> E importEntity(TenantId tenantId, D exportData) {
 | 
			
		||||
    public <E extends HasId<I>, I extends EntityId, D extends EntityExportData<E>> EntityImportResult<E> importEntity(TenantId tenantId, D exportData) {
 | 
			
		||||
        EntityType entityType = exportData.getEntityType();
 | 
			
		||||
        EntityImportService<I, E, D> importService = getImportService(entityType);
 | 
			
		||||
 | 
			
		||||
        return importService.importEntity(tenantId, exportData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    public <E extends HasId<I>, I extends EntityId> E findEntityByExternalId(TenantId tenantId, I externalId) {
 | 
			
		||||
        return (E) importServices.values().stream().filter(entityImportService -> entityImportService instanceof AbstractEntityImportService)
 | 
			
		||||
                .findFirst().map(entityImportService -> (AbstractEntityImportService) importServices).get()
 | 
			
		||||
                .findByExternalOrInternalId(tenantId, externalId); // FIXME !!!
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("unchecked")
 | 
			
		||||
    private <I extends EntityId, E extends HasId<I>> EntityExportService<I, E> getExportService(EntityType entityType) {
 | 
			
		||||
 | 
			
		||||
@ -19,11 +19,14 @@ import org.thingsboard.server.common.data.export.EntityExportData;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
 | 
			
		||||
public interface EntitiesExportImportService {
 | 
			
		||||
 | 
			
		||||
    <E extends HasId<I>, I extends EntityId> EntityExportData<E> exportEntity(TenantId tenantId, I entityId);
 | 
			
		||||
 | 
			
		||||
    <E extends HasId<I>, I extends EntityId, D extends EntityExportData<E>> E importEntity(TenantId tenantId, D exportData);
 | 
			
		||||
    <E extends HasId<I>, I extends EntityId, D extends EntityExportData<E>> EntityImportResult<E> importEntity(TenantId tenantId, D exportData);
 | 
			
		||||
 | 
			
		||||
    <E extends HasId<I>, I extends EntityId> E findEntityByExternalId(TenantId tenantId, I externalId);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,26 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 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.service.expimp.imp;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import org.thingsboard.server.common.data.id.EntityId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
public class EntityImportResult<E extends HasId<? extends EntityId>> {
 | 
			
		||||
    private E savedEntity;
 | 
			
		||||
    private E oldEntity;
 | 
			
		||||
}
 | 
			
		||||
@ -23,7 +23,8 @@ import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
 | 
			
		||||
public interface EntityImportService<I extends EntityId, E extends HasId<I>, D extends EntityExportData<E>> {
 | 
			
		||||
 | 
			
		||||
    E importEntity(TenantId tenantId, D exportData);
 | 
			
		||||
    // FIXME: get rid of boilerplate for import result creation and everything else
 | 
			
		||||
    EntityImportResult<E> importEntity(TenantId tenantId, D exportData);
 | 
			
		||||
 | 
			
		||||
    EntityType getEntityType();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,6 @@ public abstract class AbstractEntityImportService<I extends EntityId, E extends
 | 
			
		||||
        return findByExternalOrInternalId(tenantId, externalId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected final <ID extends EntityId> ID getInternalId(TenantId tenantId, ID externalId) {
 | 
			
		||||
        if (externalId == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
@ -50,7 +49,7 @@ public abstract class AbstractEntityImportService<I extends EntityId, E extends
 | 
			
		||||
        return entity.getId();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private <T extends HasId<ID>, ID extends EntityId> T findByExternalOrInternalId(TenantId tenantId, ID externalOrInternalId) {
 | 
			
		||||
    public final <T extends HasId<ID>, ID extends EntityId> T findByExternalOrInternalId(TenantId tenantId, ID externalOrInternalId) {
 | 
			
		||||
        ExportableEntityDao<T> dao = getDao(externalOrInternalId.getEntityType());
 | 
			
		||||
        return Optional.ofNullable(dao.findByTenantIdAndExternalId(tenantId.getId(), externalOrInternalId.getId()))
 | 
			
		||||
                .orElseGet(() -> dao.findByTenantIdAndId(tenantId.getId(), externalOrInternalId.getId()));
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.id.AssetId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.dao.asset.AssetService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@ -34,7 +35,7 @@ public class AssetImportService extends AbstractEntityImportService<AssetId, Ass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Asset importEntity(TenantId tenantId, AssetExportData exportData) {
 | 
			
		||||
    public EntityImportResult<Asset> importEntity(TenantId tenantId, AssetExportData exportData) {
 | 
			
		||||
        Asset asset = exportData.getAsset();
 | 
			
		||||
        Asset existingAsset = findByExternalId(tenantId, asset.getId()); // TODO: extract boiler plate to abstract class ...
 | 
			
		||||
 | 
			
		||||
@ -51,7 +52,10 @@ public class AssetImportService extends AbstractEntityImportService<AssetId, Ass
 | 
			
		||||
 | 
			
		||||
        Asset savedAsset = assetService.saveAsset(asset);
 | 
			
		||||
 | 
			
		||||
        return savedAsset;
 | 
			
		||||
        EntityImportResult<Asset> importResult = new EntityImportResult<>();
 | 
			
		||||
        importResult.setSavedEntity(savedAsset);
 | 
			
		||||
        importResult.setOldEntity(existingAsset);
 | 
			
		||||
        return importResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.id.CustomerId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.dao.customer.CustomerService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@ -34,7 +35,7 @@ public class CustomerImportService extends AbstractEntityImportService<CustomerI
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Customer importEntity(TenantId tenantId, CustomerExportData exportData) {
 | 
			
		||||
    public EntityImportResult<Customer> importEntity(TenantId tenantId, CustomerExportData exportData) {
 | 
			
		||||
        Customer customer = exportData.getCustomer();
 | 
			
		||||
        Customer existingCustomer = findByExternalId(tenantId, customer.getId());
 | 
			
		||||
 | 
			
		||||
@ -49,7 +50,10 @@ public class CustomerImportService extends AbstractEntityImportService<CustomerI
 | 
			
		||||
 | 
			
		||||
        Customer savedCustomer = customerService.saveCustomer(customer);
 | 
			
		||||
 | 
			
		||||
        return savedCustomer;
 | 
			
		||||
        EntityImportResult<Customer> importResult = new EntityImportResult<>();
 | 
			
		||||
        importResult.setSavedEntity(savedCustomer);
 | 
			
		||||
        importResult.setOldEntity(existingCustomer);
 | 
			
		||||
        return importResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.id.DashboardId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.dao.dashboard.DashboardService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@ -34,7 +35,7 @@ public class DashboardImportService extends AbstractEntityImportService<Dashboar
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Dashboard importEntity(TenantId tenantId, DashboardExportData exportData) {
 | 
			
		||||
    public EntityImportResult<Dashboard> importEntity(TenantId tenantId, DashboardExportData exportData) {
 | 
			
		||||
        Dashboard dashboard = exportData.getDashboard();
 | 
			
		||||
        Dashboard existingDashboard = findByExternalId(tenantId, dashboard.getId());
 | 
			
		||||
 | 
			
		||||
@ -51,7 +52,10 @@ public class DashboardImportService extends AbstractEntityImportService<Dashboar
 | 
			
		||||
 | 
			
		||||
        Dashboard savedDashboard = dashboardService.saveDashboard(dashboard);
 | 
			
		||||
 | 
			
		||||
        return savedDashboard;
 | 
			
		||||
        EntityImportResult<Dashboard> importResult = new EntityImportResult<>();
 | 
			
		||||
        importResult.setSavedEntity(savedDashboard);
 | 
			
		||||
        importResult.setOldEntity(existingDashboard);
 | 
			
		||||
        return importResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,6 @@ package org.thingsboard.server.service.expimp.imp.impl;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.thingsboard.server.cluster.TbClusterService;
 | 
			
		||||
import org.thingsboard.server.common.data.Device;
 | 
			
		||||
import org.thingsboard.server.common.data.EntityType;
 | 
			
		||||
import org.thingsboard.server.common.data.export.impl.DeviceExportData;
 | 
			
		||||
@ -26,7 +25,7 @@ import org.thingsboard.server.common.data.id.DeviceId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.dao.device.DeviceService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.action.EntityActionService;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@ -38,7 +37,7 @@ public class DeviceImportService extends AbstractEntityImportService<DeviceId, D
 | 
			
		||||
 | 
			
		||||
    @Transactional
 | 
			
		||||
    @Override
 | 
			
		||||
    public Device importEntity(TenantId tenantId, DeviceExportData exportData) {
 | 
			
		||||
    public EntityImportResult<Device> importEntity(TenantId tenantId, DeviceExportData exportData) {
 | 
			
		||||
        Device device = exportData.getDevice();
 | 
			
		||||
        Device existingDevice = findByExternalId(tenantId, device.getId()); // FIXME: !!!
 | 
			
		||||
        // what if exporting and importing back already exported entity ? (save version and then load it back)
 | 
			
		||||
@ -70,7 +69,10 @@ public class DeviceImportService extends AbstractEntityImportService<DeviceId, D
 | 
			
		||||
 | 
			
		||||
        Device savedDevice = deviceService.saveDeviceWithCredentials(device, exportData.getCredentials());
 | 
			
		||||
 | 
			
		||||
        return savedDevice;
 | 
			
		||||
        EntityImportResult<Device> importResult = new EntityImportResult<>();
 | 
			
		||||
        importResult.setSavedEntity(savedDevice);
 | 
			
		||||
        importResult.setOldEntity(existingDevice);
 | 
			
		||||
        return importResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,7 @@ import org.thingsboard.server.common.data.id.DeviceProfileId;
 | 
			
		||||
import org.thingsboard.server.common.data.id.TenantId;
 | 
			
		||||
import org.thingsboard.server.dao.device.DeviceProfileService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@ -34,7 +35,7 @@ public class DeviceProfileImportService extends AbstractEntityImportService<Devi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DeviceProfile importEntity(TenantId tenantId, DeviceProfileExportData exportData) {
 | 
			
		||||
    public EntityImportResult<DeviceProfile> importEntity(TenantId tenantId, DeviceProfileExportData exportData) {
 | 
			
		||||
        DeviceProfile deviceProfile = exportData.getDeviceProfile();
 | 
			
		||||
        DeviceProfile existingDeviceProfile = findByExternalId(tenantId, deviceProfile.getId());
 | 
			
		||||
 | 
			
		||||
@ -54,7 +55,10 @@ public class DeviceProfileImportService extends AbstractEntityImportService<Devi
 | 
			
		||||
 | 
			
		||||
        DeviceProfile savedDeviceProfile = deviceProfileService.saveDeviceProfile(deviceProfile);
 | 
			
		||||
 | 
			
		||||
        return savedDeviceProfile;
 | 
			
		||||
        EntityImportResult<DeviceProfile> importResult = new EntityImportResult<>();
 | 
			
		||||
        importResult.setSavedEntity(savedDeviceProfile);
 | 
			
		||||
        importResult.setOldEntity(existingDeviceProfile);
 | 
			
		||||
        return importResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.rule.RuleChain;
 | 
			
		||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
 | 
			
		||||
import org.thingsboard.server.dao.rule.RuleChainService;
 | 
			
		||||
import org.thingsboard.server.queue.util.TbCoreComponent;
 | 
			
		||||
import org.thingsboard.server.service.expimp.imp.EntityImportResult;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@TbCoreComponent
 | 
			
		||||
@ -37,7 +38,7 @@ public class RuleChainImportService extends AbstractEntityImportService<RuleChai
 | 
			
		||||
 | 
			
		||||
    @Transactional
 | 
			
		||||
    @Override
 | 
			
		||||
    public RuleChain importEntity(TenantId tenantId, RuleChainExportData exportData) {
 | 
			
		||||
    public EntityImportResult<RuleChain> importEntity(TenantId tenantId, RuleChainExportData exportData) {
 | 
			
		||||
        RuleChain ruleChain = exportData.getRuleChain();
 | 
			
		||||
        RuleChain existingRuleChain = findByExternalId(tenantId, ruleChain.getId());
 | 
			
		||||
 | 
			
		||||
@ -69,7 +70,10 @@ public class RuleChainImportService extends AbstractEntityImportService<RuleChai
 | 
			
		||||
        });
 | 
			
		||||
        ruleChainService.saveRuleChainMetaData(tenantId, metaData);
 | 
			
		||||
 | 
			
		||||
        return savedRuleChain;
 | 
			
		||||
        EntityImportResult<RuleChain> importResult = new EntityImportResult<>();
 | 
			
		||||
        importResult.setSavedEntity(savedRuleChain);
 | 
			
		||||
        importResult.setOldEntity(existingRuleChain);
 | 
			
		||||
        return importResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -43,6 +43,9 @@ import org.thingsboard.server.common.data.id.HasId;
 | 
			
		||||
public interface EntityExportData<E extends HasId<? extends EntityId>> {
 | 
			
		||||
 | 
			
		||||
    @JsonIgnore
 | 
			
		||||
    EntityType getEntityType(); // fixme: maybe remove if not needed, as well as generic
 | 
			
		||||
    E getMainEntity();
 | 
			
		||||
 | 
			
		||||
    @JsonIgnore
 | 
			
		||||
    EntityType getEntityType(); // fixme: maybe remove if not needed
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,11 @@ public class AssetExportData implements EntityExportData<Asset> {
 | 
			
		||||
 | 
			
		||||
    private Asset asset;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Asset getMainEntity() {
 | 
			
		||||
        return asset;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public EntityType getEntityType() {
 | 
			
		||||
        return EntityType.ASSET;
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,11 @@ public class CustomerExportData implements EntityExportData<Customer> {
 | 
			
		||||
 | 
			
		||||
    private Customer customer;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Customer getMainEntity() {
 | 
			
		||||
        return customer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public EntityType getEntityType() {
 | 
			
		||||
        return EntityType.CUSTOMER;
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,11 @@ public class DashboardExportData implements EntityExportData<Dashboard> {
 | 
			
		||||
 | 
			
		||||
    private Dashboard dashboard;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Dashboard getMainEntity() {
 | 
			
		||||
        return dashboard;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public EntityType getEntityType() {
 | 
			
		||||
        return EntityType.DASHBOARD;
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,11 @@ public class DeviceExportData implements EntityExportData<Device> {
 | 
			
		||||
    private Device device;
 | 
			
		||||
    private DeviceCredentials credentials;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Device getMainEntity() {
 | 
			
		||||
        return device;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public EntityType getEntityType() {
 | 
			
		||||
        return EntityType.DEVICE;
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,11 @@ public class DeviceProfileExportData implements EntityExportData<DeviceProfile>
 | 
			
		||||
 | 
			
		||||
    private DeviceProfile deviceProfile;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public DeviceProfile getMainEntity() {
 | 
			
		||||
        return deviceProfile;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public EntityType getEntityType() {
 | 
			
		||||
        return EntityType.DEVICE_PROFILE;
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,11 @@ public class RuleChainExportData implements EntityExportData<RuleChain> {
 | 
			
		||||
    private RuleChain ruleChain;
 | 
			
		||||
    private RuleChainMetaData metaData;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public RuleChain getMainEntity() {
 | 
			
		||||
        return ruleChain;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public EntityType getEntityType() {
 | 
			
		||||
        return EntityType.RULE_CHAIN;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user