From e78a891044cba9623c3a52fe3ed81d19c787c2b3 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 13 Jun 2022 13:47:45 +0300 Subject: [PATCH 1/2] Entity views export/import --- .../main/data/upgrade/3.3.4/schema_update.sql | 2 + .../DefaultEntitiesExportImportService.java | 2 +- .../impl/EntityViewImportService.java | 47 +++++++++++++++++++ .../server/common/data/EntityView.java | 5 +- .../server/common/data/sync/JsonTbEntity.java | 2 + .../server/dao/entityview/EntityViewDao.java | 3 +- .../model/sql/AbstractEntityViewEntity.java | 10 ++++ .../sql/entityview/EntityViewRepository.java | 3 +- .../dao/sql/entityview/JpaEntityViewDao.java | 16 ++++++- .../main/resources/sql/schema-entities.sql | 3 +- .../app/shared/models/entity-view.models.ts | 4 +- ui-ngx/src/app/shared/models/vc.models.ts | 1 + 12 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java diff --git a/application/src/main/data/upgrade/3.3.4/schema_update.sql b/application/src/main/data/upgrade/3.3.4/schema_update.sql index babb630e9e..124e3eb9bf 100644 --- a/application/src/main/data/upgrade/3.3.4/schema_update.sql +++ b/application/src/main/data/upgrade/3.3.4/schema_update.sql @@ -28,6 +28,8 @@ ALTER TABLE customer ADD COLUMN IF NOT EXISTS external_id UUID; ALTER TABLE widgets_bundle ADD COLUMN IF NOT EXISTS external_id UUID; +ALTER TABLE entity_view + ADD COLUMN IF NOT EXISTS external_id UUID; ALTER TABLE admin_settings ADD COLUMN IF NOT EXISTS tenant_id uuid NOT NULL DEFAULT '13814000-1dd2-11b2-8080-808080808080'; diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java index 4e9e737076..052e9b9279 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/DefaultEntitiesExportImportService.java @@ -57,7 +57,7 @@ public class DefaultEntitiesExportImportService implements EntitiesExportImportS protected static final List SUPPORTED_ENTITY_TYPES = List.of( EntityType.CUSTOMER, EntityType.ASSET, EntityType.RULE_CHAIN, EntityType.DASHBOARD, EntityType.DEVICE_PROFILE, EntityType.DEVICE, - EntityType.WIDGETS_BUNDLE + EntityType.ENTITY_VIEW, EntityType.WIDGETS_BUNDLE ); diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java new file mode 100644 index 0000000000..a7156a290b --- /dev/null +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java @@ -0,0 +1,47 @@ +package org.thingsboard.server.service.sync.ie.importing.impl; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.EntityView; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.EntityViewId; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.sync.ie.EntityExportData; +import org.thingsboard.server.common.data.sync.ie.EntityImportSettings; +import org.thingsboard.server.dao.entityview.EntityViewService; +import org.thingsboard.server.queue.util.TbCoreComponent; +import org.thingsboard.server.service.security.model.SecurityUser; + +@Service +@TbCoreComponent +@RequiredArgsConstructor +public class EntityViewImportService extends BaseEntityImportService> { + + private final EntityViewService entityViewService; + + @Override + protected void setOwner(TenantId tenantId, EntityView entityView, IdProvider idProvider) { + entityView.setTenantId(tenantId); + entityView.setCustomerId(idProvider.getInternalId(entityView.getCustomerId())); + } + + @Override + protected EntityView prepareAndSave(TenantId tenantId, EntityView entityView, EntityExportData exportData, IdProvider idProvider, EntityImportSettings importSettings) { + entityView.setEntityId(idProvider.getInternalId(entityView.getEntityId())); + return entityViewService.saveEntityView(entityView); + } + + @Override + protected void onEntitySaved(SecurityUser user, EntityView savedEntityView, EntityView oldEntityView) throws ThingsboardException { + entityNotificationService.notifyCreateOrUpdateEntity(user.getTenantId(), savedEntityView.getId(), savedEntityView, + null, oldEntityView == null ? ActionType.ADDED : ActionType.UPDATED, user); + } + + @Override + public EntityType getEntityType() { + return EntityType.ENTITY_VIEW; + } + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java b/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java index 1f238fd672..a7e21b8a25 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java @@ -36,7 +36,7 @@ import org.thingsboard.server.common.data.validation.NoXss; @AllArgsConstructor @EqualsAndHashCode(callSuper = true) public class EntityView extends SearchTextBasedWithAdditionalInfo - implements HasName, HasTenantId, HasCustomerId { + implements HasName, HasTenantId, HasCustomerId, ExportableEntity { private static final long serialVersionUID = 5582010124562018986L; @@ -59,6 +59,8 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo @ApiModelProperty(position = 10, value = "Represents the end time of the interval that is used to limit access to target device telemetry. Customer will not be able to see entity telemetry that is outside the specified interval;") private long endTimeMs; + private EntityViewId externalId; + public EntityView() { super(); } @@ -77,6 +79,7 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo this.keys = entityView.getKeys(); this.startTimeMs = entityView.getStartTimeMs(); this.endTimeMs = entityView.getEndTimeMs(); + this.externalId = entityView.getExternalId(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/sync/JsonTbEntity.java b/common/data/src/main/java/org/thingsboard/server/common/data/sync/JsonTbEntity.java index 4bb636c73b..0e2929bef8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/sync/JsonTbEntity.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/sync/JsonTbEntity.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.EntityView; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.widget.WidgetsBundle; @@ -43,6 +44,7 @@ import java.lang.annotation.Target; @Type(name = "ASSET", value = Asset.class), @Type(name = "DASHBOARD", value = Dashboard.class), @Type(name = "CUSTOMER", value = Customer.class), + @Type(name = "ENTITY_VIEW", value = EntityView.class), @Type(name = "WIDGETS_BUNDLE", value = WidgetsBundle.class) }) public @interface JsonTbEntity { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java index f44bafe937..49d1b94ecc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.Dao; +import org.thingsboard.server.dao.ExportableEntityDao; import java.util.List; import java.util.Optional; @@ -31,7 +32,7 @@ import java.util.UUID; /** * Created by Victor Basanets on 8/28/2017. */ -public interface EntityViewDao extends Dao { +public interface EntityViewDao extends Dao, ExportableEntityDao { /** * Find entity view info by id. diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractEntityViewEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractEntityViewEntity.java index a8a31cd892..cc68adb2a1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractEntityViewEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/AbstractEntityViewEntity.java @@ -89,6 +89,9 @@ public abstract class AbstractEntityViewEntity extends Bas @Column(name = ModelConstants.ENTITY_VIEW_ADDITIONAL_INFO_PROPERTY) private JsonNode additionalInfo; + @Column(name = ModelConstants.EXTERNAL_ID_PROPERTY) + private UUID externalId; + private static final ObjectMapper mapper = new ObjectMapper(); public AbstractEntityViewEntity() { @@ -121,6 +124,9 @@ public abstract class AbstractEntityViewEntity extends Bas this.endTs = entityView.getEndTimeMs(); this.searchText = entityView.getSearchText(); this.additionalInfo = entityView.getAdditionalInfo(); + if (entityView.getExternalId() != null) { + this.externalId = entityView.getExternalId().getId(); + } } public AbstractEntityViewEntity(EntityViewEntity entityViewEntity) { @@ -137,6 +143,7 @@ public abstract class AbstractEntityViewEntity extends Bas this.endTs = entityViewEntity.getEndTs(); this.searchText = entityViewEntity.getSearchText(); this.additionalInfo = entityViewEntity.getAdditionalInfo(); + this.externalId = entityViewEntity.getExternalId(); } @Override @@ -172,6 +179,9 @@ public abstract class AbstractEntityViewEntity extends Bas entityView.setStartTimeMs(startTs); entityView.setEndTimeMs(endTs); entityView.setAdditionalInfo(additionalInfo); + if (externalId != null) { + entityView.setExternalId(new EntityViewId(externalId)); + } return entityView; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java index 7a88aa3c5b..b8e7c1b90d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java @@ -20,6 +20,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.thingsboard.server.dao.ExportableEntityRepository; import org.thingsboard.server.dao.model.sql.EntityViewEntity; import org.thingsboard.server.dao.model.sql.EntityViewInfoEntity; @@ -29,7 +30,7 @@ import java.util.UUID; /** * Created by Victor Basanets on 8/31/2017. */ -public interface EntityViewRepository extends JpaRepository { +public interface EntityViewRepository extends JpaRepository, ExportableEntityRepository { @Query("SELECT new org.thingsboard.server.dao.model.sql.EntityViewInfoEntity(e, c.title, c.additionalInfo) " + "FROM EntityViewEntity e " + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java index f77db1d8cc..133eb2be2a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java @@ -201,9 +201,23 @@ public class JpaEntityViewDao extends JpaAbstractSearchTextDao findByTenantId(UUID tenantId, PageLink pageLink) { + return findEntityViewsByTenantId(tenantId, pageLink); + } + + @Override + public EntityView findByTenantIdAndName(UUID tenantId, String name) { + return findEntityViewByTenantIdAndName(tenantId, name).orElse(null); + } + @Override public EntityType getEntityType() { return EntityType.ENTITY_VIEW; } - } diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index e232e5deb2..09b5a2947c 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -440,7 +440,8 @@ CREATE TABLE IF NOT EXISTS entity_view ( start_ts bigint, end_ts bigint, search_text varchar(255), - additional_info varchar + additional_info varchar, + external_id uuid ); CREATE TABLE IF NOT EXISTS ts_kv_latest diff --git a/ui-ngx/src/app/shared/models/entity-view.models.ts b/ui-ngx/src/app/shared/models/entity-view.models.ts index 42b76de788..9605edfc85 100644 --- a/ui-ngx/src/app/shared/models/entity-view.models.ts +++ b/ui-ngx/src/app/shared/models/entity-view.models.ts @@ -14,7 +14,7 @@ /// limitations under the License. /// -import { BaseData } from '@shared/models/base-data'; +import { BaseData, ExportableEntity } from '@shared/models/base-data'; import { TenantId } from '@shared/models/id/tenant-id'; import { CustomerId } from '@shared/models/id/customer-id'; import { EntityViewId } from '@shared/models/id/entity-view-id'; @@ -32,7 +32,7 @@ export interface TelemetryEntityView { attributes: AttributesEntityView; } -export interface EntityView extends BaseData { +export interface EntityView extends BaseData, ExportableEntity { tenantId: TenantId; customerId: CustomerId; entityId: EntityId; diff --git a/ui-ngx/src/app/shared/models/vc.models.ts b/ui-ngx/src/app/shared/models/vc.models.ts index f22bc0ad67..b0485cc37e 100644 --- a/ui-ngx/src/app/shared/models/vc.models.ts +++ b/ui-ngx/src/app/shared/models/vc.models.ts @@ -28,6 +28,7 @@ export const exportableEntityTypes: Array = [ EntityType.CUSTOMER, EntityType.DEVICE_PROFILE, EntityType.RULE_CHAIN, + EntityType.ENTITY_VIEW, EntityType.WIDGETS_BUNDLE ]; From 67137e563dd0a52e003a8d963a1e737f5660e0d2 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 13 Jun 2022 14:38:34 +0300 Subject: [PATCH 2/2] License header for EntityViewImportService --- .../importing/impl/EntityViewImportService.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java index a7156a290b..9bbb57fb4f 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/ie/importing/impl/EntityViewImportService.java @@ -1,3 +1,18 @@ +/** + * 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.sync.ie.importing.impl; import lombok.RequiredArgsConstructor;