Browse Source

Removed edgeId. Code clean up and refactoring

pull/2436/head
Volodymyr Babak 6 years ago
parent
commit
134148c49f
  1. 46
      application/src/main/java/org/thingsboard/server/controller/AssetController.java
  2. 40
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  3. 40
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  4. 2
      application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java
  5. 20
      application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultInitEdgeService.java
  6. 12
      application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java
  7. 9
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  8. 8
      common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java
  9. 11
      common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java
  10. 10
      common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java
  11. 13
      common/data/src/main/java/org/thingsboard/server/common/data/Device.java
  12. 2
      common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java
  13. 15
      common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java
  14. 16
      dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
  15. 16
      dao/src/main/java/org/thingsboard/server/dao/asset/AssetDao.java
  16. 65
      dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
  17. 44
      dao/src/main/java/org/thingsboard/server/dao/asset/CassandraAssetDao.java
  18. 10
      dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java
  19. 42
      dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java
  20. 14
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java
  21. 64
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  22. 78
      dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java
  23. 12
      dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java
  24. 44
      dao/src/main/java/org/thingsboard/server/dao/entityview/CassandraEntityViewDao.java
  25. 23
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java
  26. 75
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
  27. 3
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  28. 22
      dao/src/main/java/org/thingsboard/server/dao/model/nosql/AssetEntity.java
  29. 29
      dao/src/main/java/org/thingsboard/server/dao/model/nosql/DeviceEntity.java
  30. 12
      dao/src/main/java/org/thingsboard/server/dao/model/nosql/EntityViewEntity.java
  31. 13
      dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java
  32. 10
      dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java
  33. 10
      dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityViewEntity.java
  34. 13
      dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java
  35. 2
      dao/src/main/java/org/thingsboard/server/dao/rule/CassandraRuleChainDao.java
  36. 22
      dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java
  37. 44
      dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java
  38. 22
      dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java
  39. 45
      dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java
  40. 22
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java
  41. 48
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java
  42. 3
      dao/src/main/resources/sql/schema-entities-hsql.sql
  43. 3
      dao/src/main/resources/sql/schema-entities.sql
  44. 24
      ui/src/app/api/asset.service.js
  45. 25
      ui/src/app/api/device.service.js
  46. 24
      ui/src/app/api/entity-view.service.js
  47. 12
      ui/src/app/asset/asset.controller.js
  48. 12
      ui/src/app/device/device.controller.js
  49. 19
      ui/src/app/entity-view/entity-view.controller.js
  50. 17
      ui/src/app/locale/locale.constant-en_US.json

46
application/src/main/java/org/thingsboard/server/controller/AssetController.java

@ -40,6 +40,8 @@ import org.thingsboard.server.common.data.id.EdgeId;
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.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbCoreComponent;
@ -51,6 +53,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
@RestController
@TbCoreComponent
@RequestMapping("/api")
@ -336,9 +340,9 @@ public class AssetController extends BaseController {
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.POST)
@ResponseBody
public Asset assignAssetToEdge(@PathVariable("edgeId") String strEdgeId,
public Asset assignAssetToEdge(@PathVariable(EDGE_ID) String strEdgeId,
@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
checkParameter("edgeId", strEdgeId);
checkParameter(EDGE_ID, strEdgeId);
checkParameter(ASSET_ID, strAssetId);
try {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
@ -365,20 +369,20 @@ public class AssetController extends BaseController {
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/asset/{assetId}", method = RequestMethod.DELETE)
@RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.DELETE)
@ResponseBody
public Asset unassignAssetFromEdge(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
public Asset unassignAssetFromEdge(@PathVariable(EDGE_ID) String strEdgeId,
@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
checkParameter(EDGE_ID, strEdgeId);
checkParameter(ASSET_ID, strAssetId);
try {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
Edge edge = checkEdgeId(edgeId, Operation.READ);
AssetId assetId = new AssetId(toUUID(strAssetId));
Asset asset = checkAssetId(assetId, Operation.UNASSIGN_FROM_EDGE);
if (asset.getEdgeId() == null || asset.getEdgeId().getId().equals(ModelConstants.NULL_UUID)) {
throw new IncorrectParameterException("Asset isn't assigned to any edge!");
}
Edge edge = checkEdgeId(asset.getEdgeId(), Operation.READ);
Asset savedAsset = checkNotNull(assetService.unassignAssetFromEdge(getTenantId(), assetId));
Asset savedAsset = checkNotNull(assetService.unassignAssetFromEdge(getTenantId(), assetId, edgeId));
logEntityAction(assetId, asset,
asset.getCustomerId(),
@ -398,24 +402,20 @@ public class AssetController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/{edgeId}/assets", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<Asset> getEdgeAssets(
@PathVariable("edgeId") String strEdgeId,
public TimePageData<Asset> getEdgeAssets(
@PathVariable(EDGE_ID) String strEdgeId,
@RequestParam int limit,
@RequestParam(required = false) String type,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
checkParameter("edgeId", strEdgeId);
@RequestParam(required = false) Long startTime,
@RequestParam(required = false) Long endTime,
@RequestParam(required = false, defaultValue = "false") boolean ascOrder,
@RequestParam(required = false) String offset) throws ThingsboardException {
checkParameter(EDGE_ID, strEdgeId);
try {
TenantId tenantId = getCurrentUser().getTenantId();
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
checkEdgeId(edgeId, Operation.READ);
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
if (type != null && type.trim().length()>0) {
return checkNotNull(assetService.findAssetsByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink));
} else {
return checkNotNull(assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink));
}
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
return checkNotNull(assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink).get());
} catch (Exception e) {
throw handleException(e);
}

40
application/src/main/java/org/thingsboard/server/controller/DeviceController.java

@ -49,6 +49,9 @@ import org.thingsboard.server.common.data.id.EdgeId;
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.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.dao.device.claim.ClaimResponse;
import org.thingsboard.server.dao.device.claim.ClaimResult;
@ -519,19 +522,20 @@ public class DeviceController extends BaseController {
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/device/{deviceId}", method = RequestMethod.DELETE)
@RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.DELETE)
@ResponseBody
public Device unassignDeviceFromEdge(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
public Device unassignDeviceFromEdge(@PathVariable(EDGE_ID) String strEdgeId,
@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
checkParameter(EDGE_ID, strEdgeId);
checkParameter(DEVICE_ID, strDeviceId);
try {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
Edge edge = checkEdgeId(edgeId, Operation.READ);
DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
Device device = checkDeviceId(deviceId, Operation.UNASSIGN_FROM_EDGE);
if (device.getEdgeId() == null || device.getEdgeId().getId().equals(ModelConstants.NULL_UUID)) {
throw new IncorrectParameterException("Device isn't assigned to any edge!");
}
Edge edge = checkEdgeId(device.getEdgeId(), Operation.READ);
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(getCurrentUser().getTenantId(), deviceId));
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(getCurrentUser().getTenantId(), deviceId, edgeId));
logEntityAction(deviceId, device,
device.getCustomerId(),
@ -549,24 +553,20 @@ public class DeviceController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/{edgeId}/devices", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<Device> getEdgeDevices(
@PathVariable("edgeId") String strEdgeId,
public TimePageData<Device> getEdgeDevices(
@PathVariable(EDGE_ID) String strEdgeId,
@RequestParam int limit,
@RequestParam(required = false) String type,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
checkParameter("edgeId", strEdgeId);
@RequestParam(required = false) Long startTime,
@RequestParam(required = false) Long endTime,
@RequestParam(required = false, defaultValue = "false") boolean ascOrder,
@RequestParam(required = false) String offset) throws ThingsboardException {
checkParameter(EDGE_ID, strEdgeId);
try {
TenantId tenantId = getCurrentUser().getTenantId();
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
checkEdgeId(edgeId, Operation.READ);
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
if (type != null && type.trim().length()>0) {
return checkNotNull(deviceService.findDevicesByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink));
} else {
return checkNotNull(deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edgeId, pageLink));
}
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
return checkNotNull(deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edgeId, pageLink).get());
} catch (Exception e) {
throw handleException(e);
}

40
application/src/main/java/org/thingsboard/server/controller/EntityViewController.java

@ -48,6 +48,8 @@ import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.queue.util.TbCoreComponent;
@ -400,18 +402,20 @@ public class EntityViewController extends BaseController {
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/entityView/{entityViewId}", method = RequestMethod.DELETE)
@RequestMapping(value = "/edge/{edgeId}/entityView/{entityViewId}", method = RequestMethod.DELETE)
@ResponseBody
public EntityView unassignEntityViewFromEdge(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException {
public EntityView unassignEntityViewFromEdge(@PathVariable(EDGE_ID) String strEdgeId,
@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException {
checkParameter(EDGE_ID, strEdgeId);
checkParameter(ENTITY_VIEW_ID, strEntityViewId);
try {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
Edge edge = checkEdgeId(edgeId, Operation.READ);
EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
EntityView entityView = checkEntityViewId(entityViewId, Operation.UNASSIGN_FROM_EDGE);
if (entityView.getEdgeId() == null || entityView.getEdgeId().getId().equals(ModelConstants.NULL_UUID)) {
throw new IncorrectParameterException("Entity View isn't assigned to any edge!");
}
Edge edge = checkEdgeId(entityView.getEdgeId(), Operation.READ);
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromEdge(getTenantId(), entityViewId));
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromEdge(getTenantId(), entityViewId, edgeId));
logEntityAction(entityViewId, entityView,
entityView.getCustomerId(),
ActionType.UNASSIGNED_FROM_EDGE, null, strEntityViewId, edge.getId().toString(), edge.getName());
@ -428,24 +432,20 @@ public class EntityViewController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge/{edgeId}/entityViews", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<EntityView> getEdgeEntityViews(
@PathVariable("edgeId") String strEdgeId,
public TimePageData<EntityView> getEdgeEntityViews(
@PathVariable(EDGE_ID) String strEdgeId,
@RequestParam int limit,
@RequestParam(required = false) String type,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
checkParameter("edgeId", strEdgeId);
@RequestParam(required = false) Long startTime,
@RequestParam(required = false) Long endTime,
@RequestParam(required = false, defaultValue = "false") boolean ascOrder,
@RequestParam(required = false) String offset) throws ThingsboardException {
checkParameter(EDGE_ID, strEdgeId);
try {
TenantId tenantId = getCurrentUser().getTenantId();
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
checkEdgeId(edgeId, Operation.READ);
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
if (type != null && type.trim().length()>0) {
return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink));
} else {
return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edgeId, pageLink));
}
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edgeId, pageLink).get());
} catch (Exception e) {
throw handleException(e);
}

2
application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcSession.java

@ -554,7 +554,7 @@ public final class EdgeGrpcSession implements Closeable {
case ENTITY_DELETED_RPC_MESSAGE:
Device device = ctx.getDeviceService().findDeviceByTenantIdAndName(edge.getTenantId(), deviceName);
if (device != null) {
ctx.getDeviceService().unassignDeviceFromEdge(edge.getTenantId(), device.getId());
ctx.getDeviceService().unassignDeviceFromEdge(edge.getTenantId(), device.getId(), edge.getId());
}
break;
}

20
application/src/main/java/org/thingsboard/server/service/edge/rpc/init/DefaultInitEdgeService.java

@ -15,6 +15,7 @@
*/
package org.thingsboard.server.service.edge.rpc.init;
import com.google.common.util.concurrent.Futures;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -54,6 +55,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgCo
import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor;
import java.util.UUID;
import java.util.concurrent.Future;
@Service
@Slf4j
@ -100,10 +102,10 @@ public class DefaultInitEdgeService implements InitEdgeService {
private void initDevices(Edge edge, StreamObserver<ResponseMsg> outputStream) {
try {
TextPageLink pageLink = new TextPageLink(100);
TextPageData<Device> pageData;
TimePageLink pageLink = new TimePageLink(100);
TimePageData<Device> pageData;
do {
pageData = deviceService.findDevicesByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
pageData = deviceService.findDevicesByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink).get();
if (!pageData.getData().isEmpty()) {
log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
for (Device device : pageData.getData()) {
@ -130,10 +132,10 @@ public class DefaultInitEdgeService implements InitEdgeService {
private void initAssets(Edge edge, StreamObserver<ResponseMsg> outputStream) {
try {
TextPageLink pageLink = new TextPageLink(100);
TextPageData<Asset> pageData;
TimePageLink pageLink = new TimePageLink(100);
TimePageData<Asset> pageData;
do {
pageData = assetService.findAssetsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
pageData = assetService.findAssetsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink).get();
if (!pageData.getData().isEmpty()) {
log.trace("[{}] [{}] asset(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
for (Asset asset : pageData.getData()) {
@ -160,10 +162,10 @@ public class DefaultInitEdgeService implements InitEdgeService {
private void initEntityViews(Edge edge, StreamObserver<ResponseMsg> outputStream) {
try {
TextPageLink pageLink = new TextPageLink(100);
TextPageData<EntityView> pageData;
TimePageLink pageLink = new TimePageLink(100);
TimePageData<EntityView> pageData;
do {
pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink);
pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink).get();
if (!pageData.getData().isEmpty()) {
log.trace("[{}] [{}] entity view(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
for (EntityView entityView : pageData.getData()) {

12
application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java

@ -311,18 +311,6 @@ public class CassandraDatabaseUpgradeService extends AbstractCassandraDatabaseUp
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.6.0", SCHEMA_UPDATE_CQL);
loadCql(schemaUpdateFile);
try {
cluster.getSession().execute("alter table asset add edge_id text");
Thread.sleep(2500);
} catch (InvalidQueryException e) {}
try {
cluster.getSession().execute("alter table device add edge_id text");
Thread.sleep(2500);
} catch (InvalidQueryException e) {}
try {
cluster.getSession().execute("alter table entity_view add edge_id text");
Thread.sleep(2500);
} catch (InvalidQueryException e) {}
try {
cluster.getSession().execute("alter table rule_chain add type text");
Thread.sleep(2500);

9
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -238,15 +238,6 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
log.info("Updating schema ...");
schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.6.0", SCHEMA_UPDATE_SQL);
loadSql(schemaUpdateFile, conn);
try {
conn.createStatement().execute("ALTER TABLE asset ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
} catch (Exception e) {}
try {
conn.createStatement().execute("ALTER TABLE device ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
} catch (Exception e) {}
try {
conn.createStatement().execute("ALTER TABLE entity_view ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
} catch (Exception e) {}
try {
conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'SYSTEM'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
} catch (Exception e) {}

8
common/dao-api/src/main/java/org/thingsboard/server/dao/asset/AssetService.java

@ -25,6 +25,8 @@ import org.thingsboard.server.common.data.id.EdgeId;
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.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import java.util.List;
import java.util.Optional;
@ -67,9 +69,7 @@ public interface AssetService {
Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId);
Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId);
Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId);
TextPageData<Asset> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink);
TextPageData<Asset> findAssetsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink);
ListenableFuture<TimePageData<Asset>> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
}

11
common/dao-api/src/main/java/org/thingsboard/server/dao/device/DeviceService.java

@ -25,11 +25,13 @@ import org.thingsboard.server.common.data.id.EdgeId;
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.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import java.util.List;
public interface DeviceService {
Device findDeviceById(TenantId tenantId, DeviceId deviceId);
ListenableFuture<Device> findDeviceByIdAsync(TenantId tenantId, DeviceId deviceId);
@ -68,10 +70,7 @@ public interface DeviceService {
Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId);
Device unassignDeviceFromEdge(TenantId tenantId, DeviceId deviceId);
TextPageData<Device> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink);
TextPageData<Device> findDevicesByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink);
Device unassignDeviceFromEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId);
ListenableFuture<TimePageData<Device>> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
}

10
common/dao-api/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java

@ -26,6 +26,8 @@ import org.thingsboard.server.common.data.id.EntityViewId;
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.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import java.util.List;
@ -68,11 +70,7 @@ public interface EntityViewService {
EntityView assignEntityViewToEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId);
EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId);
TextPageData<EntityView> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink);
TextPageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink);
EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId);
ListenableFuture<TimePageData<EntityView>> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
}

13
common/data/src/main/java/org/thingsboard/server/common/data/Device.java

@ -18,7 +18,6 @@ package org.thingsboard.server.common.data;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
@EqualsAndHashCode(callSuper = true)
@ -28,7 +27,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
private TenantId tenantId;
private CustomerId customerId;
private EdgeId edgeId;
private String name;
private String type;
private String label;
@ -48,7 +46,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
this.name = device.getName();
this.type = device.getType();
this.label = device.getLabel();
this.edgeId = device.getEdgeId();
}
public TenantId getTenantId() {
@ -67,14 +64,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
this.customerId = customerId;
}
public EdgeId getEdgeId() {
return edgeId;
}
public void setEdgeId(EdgeId edgeId) {
this.edgeId = edgeId;
}
@Override
public String getName() {
return name;
@ -112,8 +101,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
builder.append(tenantId);
builder.append(", customerId=");
builder.append(customerId);
builder.append(", edgeId=");
builder.append(edgeId);
builder.append(", name=");
builder.append(name);
builder.append(", type=");

2
common/data/src/main/java/org/thingsboard/server/common/data/EntityView.java

@ -19,7 +19,6 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
@ -40,7 +39,6 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo<EntityViewId>
private EntityId entityId;
private TenantId tenantId;
private CustomerId customerId;
private EdgeId edgeId;
private String name;
private String type;
private TelemetryEntityView keys;

15
common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java

@ -15,13 +15,10 @@
*/
package org.thingsboard.server.common.data.asset;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.*;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
@EqualsAndHashCode(callSuper = true)
@ -34,7 +31,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
private String name;
private String type;
private String label;
private EdgeId edgeId;
public Asset() {
super();
@ -51,7 +47,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
this.name = asset.getName();
this.type = asset.getType();
this.label = asset.getLabel();
this.edgeId = asset.getEdgeId();
}
public TenantId getTenantId() {
@ -70,14 +65,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
this.customerId = customerId;
}
public EdgeId getEdgeId() {
return edgeId;
}
public void setEdgeId(EdgeId edgeId) {
this.edgeId = edgeId;
}
@Override
public String getName() {
return name;
@ -115,8 +102,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
builder.append(tenantId);
builder.append(", customerId=");
builder.append(customerId);
builder.append(", edgeId=");
builder.append(edgeId);
builder.append(", name=");
builder.append(name);
builder.append(", type=");

16
dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java

@ -341,16 +341,6 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
}
}
private void deleteRelation(TenantId tenantId, EntityRelation alarmRelation) {
log.debug("Deleting Alarm relation: {}", alarmRelation);
relationService.deleteRelation(tenantId, alarmRelation);
}
private void createRelation(TenantId tenantId, EntityRelation alarmRelation) {
log.debug("Creating Alarm relation: {}", alarmRelation);
relationService.saveRelation(tenantId, alarmRelation);
}
private Alarm merge(Alarm existing, Alarm alarm) {
if (alarm.getStartTs() > existing.getEndTs()) {
existing.setEndTs(alarm.getStartTs());
@ -395,7 +385,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
}
}
private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status, boolean createAnyRelation) {
private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status, boolean createAnyRelation) throws ExecutionException, InterruptedException {
if (createAnyRelation) {
createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + AlarmSearchStatus.ANY.name(), RelationTypeGroup.ALARM));
}
@ -404,13 +394,13 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM));
}
private void deleteAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status) {
private void deleteAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status) throws ExecutionException, InterruptedException {
deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.name(), RelationTypeGroup.ALARM));
deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getClearSearchStatus().name(), RelationTypeGroup.ALARM));
deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM));
}
private void updateAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus oldStatus, AlarmStatus newStatus) {
private void updateAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus oldStatus, AlarmStatus newStatus) throws ExecutionException, InterruptedException {
deleteAlarmRelation(tenantId, entityId, alarmId, oldStatus);
createAlarmRelation(tenantId, entityId, alarmId, newStatus, false);
}

16
dao/src/main/java/org/thingsboard/server/dao/asset/AssetDao.java

@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.Dao;
import java.util.List;
@ -116,23 +117,12 @@ public interface AssetDao extends Dao<Asset> {
ListenableFuture<List<EntitySubtype>> findTenantAssetTypesAsync(UUID tenantId);
/**
* Find assets by tenantId, customerId and page link.
* Find assets by tenantId, edgeId and page link.
*
* @param tenantId the tenantId
* @param edgeId the edgeId
* @param pageLink the page link
* @return the list of asset objects
*/
List<Asset> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink);
/**
* Find assets by tenantId, customerId, type and page link.
*
* @param tenantId the tenantId
* @param edgeId the edgeId
* @param type the type
* @param pageLink the page link
* @return the list of asset objects
*/
List<Asset> findAssetsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink);
ListenableFuture<List<Asset>> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink);
}

65
dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java

@ -16,6 +16,7 @@
package org.thingsboard.server.dao.asset;
import com.google.common.base.Function;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
@ -29,12 +30,14 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetSearchQuery;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
@ -42,9 +45,13 @@ import org.thingsboard.server.common.data.id.EntityId;
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.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.customer.CustomerDao;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.exception.DataValidationException;
@ -52,6 +59,7 @@ import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.tenant.TenantDao;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -89,6 +97,9 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
@Autowired
private EntityViewService entityViewService;
@Autowired
private EdgeService edgeService;
@Autowired
private CacheManager cacheManager;
@ -285,36 +296,52 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
@Override
public Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId) {
Asset asset = findAssetById(tenantId, assetId);
asset.setEdgeId(edgeId);
return saveAsset(asset);
Edge edge = edgeService.findEdgeById(tenantId, edgeId);
if (edge == null) {
throw new DataValidationException("Can't assign asset to non-existent edge!");
}
if (!edge.getTenantId().getId().equals(asset.getTenantId().getId())) {
throw new DataValidationException("Can't assign asset to edge from different tenant!");
}
try {
createRelation(tenantId, new EntityRelation(edgeId, assetId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
} catch (ExecutionException | InterruptedException e) {
log.warn("[{}] Failed to create asset relation. Edge Id: [{}]", assetId, edgeId);
throw new RuntimeException(e);
}
return asset;
}
@Override
public Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId) {
public Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId) {
Asset asset = findAssetById(tenantId, assetId);
asset.setEdgeId(null);
return saveAsset(asset);
Edge edge = edgeService.findEdgeById(tenantId, edgeId);
if (edge == null) {
throw new DataValidationException("Can't unassign asset from non-existent edge!");
}
try {
deleteRelation(tenantId, new EntityRelation(edgeId, assetId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
} catch (ExecutionException | InterruptedException e) {
log.warn("[{}] Failed to delete asset relation. Edge Id: [{}]", assetId, edgeId);
throw new RuntimeException(e);
}
return asset;
}
@Override
public TextPageData<Asset> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink) {
public ListenableFuture<TimePageData<Asset>> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
log.trace("Executing findAssetsByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<Asset> assets = assetDao.findAssetsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
return new TextPageData<>(assets, pageLink);
}
@Override
public TextPageData<Asset> findAssetsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink) {
log.trace("Executing findAssetsByTenantIdAndEdgeIdAndType, tenantId [{}], edgeId [{}], type [{}], pageLink [{}]", tenantId, edgeId, type, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
validateString(type, "Incorrect type " + type);
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<Asset> assets = assetDao.findAssetsByTenantIdAndEdgeIdAndType(tenantId.getId(), edgeId.getId(), type, pageLink);
return new TextPageData<>(assets, pageLink);
ListenableFuture<List<Asset>> assets = assetDao.findAssetsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
return Futures.transform(assets, new Function<List<Asset>, TimePageData<Asset>>() {
@Nullable
@Override
public TimePageData<Asset> apply(@Nullable List<Asset> assets) {
return new TimePageData<>(assets, pageLink);
}
}, MoreExecutors.directExecutor());
}
private DataValidator<Asset> assetValidator =

44
dao/src/main/java/org/thingsboard/server/dao/asset/CassandraAssetDao.java

@ -25,16 +25,23 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.EntitySubtypeEntity;
import org.thingsboard.server.dao.model.nosql.AssetEntity;
import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.util.NoSqlDao;
import javax.annotation.Nullable;
@ -68,6 +75,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
@NoSqlDao
public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao {
@Autowired
private RelationDao relationDao;
@Override
protected Class<AssetEntity> getColumnFamilyClass() {
return AssetEntity.class;
@ -190,30 +200,16 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
}
@Override
public List<Asset> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {
// log.debug("Try to find assets by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink);
// List<AssetEntity> assetEntities = findPageWithTextSearch(new TenantId(tenantId), ASSET_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
// Arrays.asList(eq(ASSET_CUSTOMER_ID_PROPERTY, customerId),
// eq(ASSET_TENANT_ID_PROPERTY, tenantId)),
// pageLink);
//
// log.trace("Found assets [{}] by tenantId [{}], customerId [{}] and pageLink [{}]", assetEntities, tenantId, customerId, pageLink);
// return DaoUtil.convertDataList(assetEntities);
throw new UnsupportedOperationException("Cassandra is not supported yet");
}
@Override
public List<Asset> findAssetsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {
// log.debug("Try to find assets by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink);
// List<AssetEntity> assetEntities = findPageWithTextSearch(new TenantId(tenantId), ASSET_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
// Arrays.asList(eq(ASSET_TYPE_PROPERTY, type),
// eq(ASSET_CUSTOMER_ID_PROPERTY, customerId),
// eq(ASSET_TENANT_ID_PROPERTY, tenantId)),
// pageLink);
//
// log.trace("Found assets [{}] by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", assetEntities, tenantId, customerId, type, pageLink);
// return DaoUtil.convertDataList(assetEntities);
throw new UnsupportedOperationException("Cassandra is not supported yet");
public ListenableFuture<List<Asset>> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
log.debug("Try to find assets by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.ASSET, pageLink);
return Futures.transformAsync(relations, input -> {
List<ListenableFuture<Asset>> assetFutures = new ArrayList<>(input.size());
for (EntityRelation relation : input) {
assetFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
}
return Futures.successfulAsList(assetFutures);
}, MoreExecutors.directExecutor());
}
}

10
dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java

@ -162,16 +162,6 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
}
}
private void deleteRelation(TenantId tenantId, EntityRelation dashboardRelation) throws ExecutionException, InterruptedException {
log.debug("Deleting Dashboard relation: {}", dashboardRelation);
relationService.deleteRelationAsync(tenantId, dashboardRelation).get();
}
private void createRelation(TenantId tenantId, EntityRelation dashboardRelation) throws ExecutionException, InterruptedException {
log.debug("Creating Dashboard relation: {}", dashboardRelation);
relationService.saveRelationAsync(tenantId, dashboardRelation).get();
}
@Override
public void deleteDashboard(TenantId tenantId, DashboardId dashboardId) {
log.trace("Executing deleteDashboard [{}]", dashboardId);

42
dao/src/main/java/org/thingsboard/server/dao/device/CassandraDeviceDao.java

@ -25,16 +25,22 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.EntitySubtypeEntity;
import org.thingsboard.server.dao.model.nosql.DeviceEntity;
import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.util.NoSqlDao;
import javax.annotation.Nullable;
@ -68,6 +74,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
@NoSqlDao
public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao {
@Autowired
private RelationDao relationDao;
@Override
protected Class<DeviceEntity> getColumnFamilyClass() {
return DeviceEntity.class;
@ -190,30 +199,17 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
}
@Override
public List<Device> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {
// log.debug("Try to find devices by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink);
// List<DeviceEntity> deviceEntities = findPageWithTextSearch(new TenantId(tenantId), DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
// Arrays.asList(eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId),
// eq(DEVICE_TENANT_ID_PROPERTY, tenantId)),
// pageLink);
//
// log.trace("Found devices [{}] by tenantId [{}], customerId [{}] and pageLink [{}]", deviceEntities, tenantId, customerId, pageLink);
// return DaoUtil.convertDataList(deviceEntities);
throw new UnsupportedOperationException("Cassandra is not supported yet");
public ListenableFuture<List<Device>> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
log.debug("Try to find devices by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.DEVICE, pageLink);
return Futures.transformAsync(relations, input -> {
List<ListenableFuture<Device>> deviceFutures = new ArrayList<>(input.size());
for (EntityRelation relation : input) {
deviceFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
}
return Futures.successfulAsList(deviceFutures);
}, MoreExecutors.directExecutor());
}
@Override
public List<Device> findDevicesByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {
// log.debug("Try to find devices by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink);
// List<DeviceEntity> deviceEntities = findPageWithTextSearch(new TenantId(tenantId), DEVICE_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
// Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type),
// eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId),
// eq(DEVICE_TENANT_ID_PROPERTY, tenantId)),
// pageLink);
//
// log.trace("Found devices [{}] by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", deviceEntities, tenantId, customerId, type, pageLink);
// return DaoUtil.convertDataList(deviceEntities);
throw new UnsupportedOperationException("Cassandra is not supported yet");
}
}

14
dao/src/main/java/org/thingsboard/server/dao/device/DeviceDao.java

@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.Dao;
import java.util.List;
@ -124,16 +125,5 @@ public interface DeviceDao extends Dao<Device> {
* @param pageLink the page link
* @return the list of device objects
*/
List<Device> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink);
/**
* Find devices by tenantId, edgeId, type and page link.
*
* @param tenantId the tenantId
* @param edgeId the edgeId
* @param type the type
* @param pageLink the page link
* @return the list of device objects
*/
List<Device> findDevicesByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink);
ListenableFuture<List<Device>> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink);
}

64
dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java

@ -41,19 +41,26 @@ import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityId;
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.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.dao.customer.CustomerDao;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.service.Validator;
import org.thingsboard.server.dao.tenant.TenantDao;
import javax.annotation.Nullable;
@ -98,6 +105,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
@Autowired
private EntityViewService entityViewService;
@Autowired
private EdgeService edgeService;
@Autowired
private CacheManager cacheManager;
@ -324,36 +334,52 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
@Override
public Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId) {
Device device = findDeviceById(tenantId, deviceId);
device.setEdgeId(edgeId);
return saveDevice(device);
Edge edge = edgeService.findEdgeById(tenantId, edgeId);
if (edge == null) {
throw new DataValidationException("Can't assign device to non-existent edge!");
}
if (!edge.getTenantId().getId().equals(device.getTenantId().getId())) {
throw new DataValidationException("Can't assign device to edge from different tenant!");
}
try {
createRelation(tenantId, new EntityRelation(edgeId, deviceId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
} catch (ExecutionException | InterruptedException e) {
log.warn("[{}] Failed to create device relation. Edge Id: [{}]", deviceId, edgeId);
throw new RuntimeException(e);
}
return device;
}
@Override
public Device unassignDeviceFromEdge(TenantId tenantId, DeviceId deviceId) {
public Device unassignDeviceFromEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId) {
Device device = findDeviceById(tenantId, deviceId);
device.setEdgeId(null);
return saveDevice(device);
Edge edge = edgeService.findEdgeById(tenantId, edgeId);
if (edge == null) {
throw new DataValidationException("Can't unassign device from non-existent edge!");
}
try {
deleteRelation(tenantId, new EntityRelation(edgeId, deviceId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
} catch (ExecutionException | InterruptedException e) {
log.warn("[{}] Failed to delete device relation. Edge Id: [{}]", deviceId, edgeId);
throw new RuntimeException(e);
}
return device;
}
@Override
public TextPageData<Device> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink) {
public ListenableFuture<TimePageData<Device>> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
log.trace("Executing findDevicesByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<Device> devices = deviceDao.findDevicesByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
return new TextPageData<>(devices, pageLink);
}
@Override
public TextPageData<Device> findDevicesByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink) {
log.trace("Executing findDevicesByTenantIdAndEdgeIdAndType, tenantId [{}], edgeId [{}], type [{}], pageLink [{}]", tenantId, edgeId, type, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
validateString(type, "Incorrect type " + type);
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<Device> devices = deviceDao.findDevicesByTenantIdAndEdgeIdAndType(tenantId.getId(), edgeId.getId(), type, pageLink);
return new TextPageData<>(devices, pageLink);
ListenableFuture<List<Device>> devices = deviceDao.findDevicesByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
return Futures.transform(devices, new Function<List<Device>, TimePageData<Device>>() {
@Nullable
@Override
public TimePageData<Device> apply(@Nullable List<Device> devices) {
return new TimePageData<>(devices, pageLink);
}
}, MoreExecutors.directExecutor());
}
private DataValidator<Device> deviceValidator =

78
dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java

@ -62,6 +62,7 @@ import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.rule.RuleChainType;
@ -75,6 +76,7 @@ import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
@ -144,6 +146,9 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
@Autowired
private EntityViewService entityViewService;
@Autowired
private RelationService relationService;
private ExecutorService tsCallBackExecutor;
@PostConstruct
@ -219,7 +224,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
dashboardService.unassignEdgeDashboards(tenantId, edgeId);
// TODO: validate that rule chains are removed by deleteEntityRelations(tenantId, edgeId); call
ruleChainService.unassignEdgeRuleChains(tenantId, edgeId);
ruleChainService.unassignEdgeRuleChains(tenantId, edgeId);
List<Object> list = new ArrayList<>();
list.add(edge.getTenantId());
@ -385,15 +390,18 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
}
private void processCustomTbMsg(TenantId tenantId, TbMsg tbMsg, FutureCallback<Void> callback) {
EdgeId edgeId = getEdgeIdByOriginatorId(tenantId, tbMsg.getOriginator());
EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(tbMsg.getOriginator().getEntityType());
if (edgeId != null && edgeQueueEntityType != null) {
try {
saveEventToEdgeQueue(tenantId, edgeId, edgeQueueEntityType, tbMsg.getType(), Base64.encodeBase64String(TbMsg.toByteArray(tbMsg)), callback);
} catch (IOException e) {
log.error("Error while saving custom tbMsg into Edge Queue", e);
ListenableFuture<EdgeId> edgeIdFuture = getEdgeIdByOriginatorId(tenantId, tbMsg.getOriginator());
Futures.transform(edgeIdFuture, edgeId -> {
EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(tbMsg.getOriginator().getEntityType());
if (edgeId != null && edgeQueueEntityType != null) {
try {
saveEventToEdgeQueue(tenantId, edgeId, edgeQueueEntityType, tbMsg.getType(), Base64.encodeBase64String(TbMsg.toByteArray(tbMsg)), callback);
} catch (IOException e) {
log.error("Error while saving custom tbMsg into Edge Queue", e);
}
}
}
return null;
}, MoreExecutors.directExecutor());
}
private EdgeQueueEntityType getEdgeQueueTypeByEntityType(EntityType entityType) {
@ -410,23 +418,30 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
}
}
private EdgeId getEdgeIdByOriginatorId(TenantId tenantId, EntityId originatorId) {
switch (originatorId.getEntityType()) {
case DEVICE:
Device device = deviceService.findDeviceById(tenantId, new DeviceId(originatorId.getId()));
return device.getEdgeId();
case ASSET:
Asset asset = assetService.findAssetById(tenantId, new AssetId(originatorId.getId()));
return asset.getEdgeId();
case ENTITY_VIEW:
EntityView entityView = entityViewService.findEntityViewById(tenantId, new EntityViewId(originatorId.getId()));
return entityView.getEdgeId();
default:
log.info("Unsupported entity type: [{}]", originatorId.getEntityType());
return null;
private ListenableFuture<EdgeId> getEdgeIdByOriginatorId(TenantId tenantId, EntityId originatorId) {
List<EntityRelation> originatorEdgeRelations = relationService.findByToAndType(tenantId, originatorId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE);
if (originatorEdgeRelations != null && originatorEdgeRelations.size() > 0) {
return Futures.immediateFuture(new EdgeId(originatorEdgeRelations.get(0).getFrom().getId()));
} else {
return Futures.immediateFuture(null);
}
}
private void pushEventToEdge(TenantId tenantId, EntityId originatorId, EdgeQueueEntityType edgeQueueEntityType, TbMsg tbMsg, FutureCallback<Void> callback) {
ListenableFuture<EdgeId> edgeIdFuture = getEdgeIdByOriginatorId(tenantId, originatorId);
Futures.transform(edgeIdFuture, edgeId -> {
if (edgeId != null) {
try {
pushEventToEdge(tenantId, edgeId, edgeQueueEntityType, tbMsg, callback);
} catch (Exception e) {
log.error("Failed to push event to edge, edgeId [{}], tbMsg [{}]", edgeId, tbMsg, e);
}
}
return null;
},
MoreExecutors.directExecutor());
}
private void processDevice(TenantId tenantId, TbMsg tbMsg, FutureCallback<Void> callback) throws IOException {
switch (tbMsg.getType()) {
case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
@ -437,9 +452,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
case DataConstants.ENTITY_CREATED:
case DataConstants.ENTITY_UPDATED:
Device device = mapper.readValue(tbMsg.getData(), Device.class);
if (device.getEdgeId() != null) {
pushEventToEdge(tenantId, device.getEdgeId(), EdgeQueueEntityType.DEVICE, tbMsg, callback);
}
pushEventToEdge(tenantId, device.getId(), EdgeQueueEntityType.DEVICE, tbMsg, callback);
break;
default:
log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
@ -471,9 +484,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
case DataConstants.ENTITY_CREATED:
case DataConstants.ENTITY_UPDATED:
Asset asset = mapper.readValue(tbMsg.getData(), Asset.class);
if (asset.getEdgeId() != null) {
pushEventToEdge(tenantId, asset.getEdgeId(), EdgeQueueEntityType.ASSET, tbMsg, callback);
}
pushEventToEdge(tenantId, asset.getId(), EdgeQueueEntityType.ASSET, tbMsg, callback);
break;
default:
log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
@ -490,9 +501,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
case DataConstants.ENTITY_CREATED:
case DataConstants.ENTITY_UPDATED:
EntityView entityView = mapper.readValue(tbMsg.getData(), EntityView.class);
if (entityView.getEdgeId() != null) {
pushEventToEdge(tenantId, entityView.getEdgeId(), EdgeQueueEntityType.ENTITY_VIEW, tbMsg, callback);
}
pushEventToEdge(tenantId, entityView.getId(), EdgeQueueEntityType.ENTITY_VIEW, tbMsg, callback);
break;
default:
log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
@ -507,10 +516,9 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
case DataConstants.ALARM_ACK:
case DataConstants.ALARM_CLEAR:
Alarm alarm = mapper.readValue(tbMsg.getData(), Alarm.class);
EdgeId edgeId = getEdgeIdByOriginatorId(tenantId, alarm.getOriginator());
EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(alarm.getOriginator().getEntityType());
if (edgeId != null && edgeQueueEntityType != null) {
pushEventToEdge(tenantId, edgeId, EdgeQueueEntityType.ALARM, tbMsg, callback);
if (edgeQueueEntityType != null) {
pushEventToEdge(tenantId, alarm.getOriginator(), EdgeQueueEntityType.ALARM, tbMsg, callback);
}
break;
default:

12
dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java

@ -21,10 +21,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.dao.relation.RelationService;
import javax.annotation.PostConstruct;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
@Slf4j
public abstract class AbstractEntityService {
@ -42,6 +44,16 @@ public abstract class AbstractEntityService {
sqlDatabaseUsed = "sql".equalsIgnoreCase(databaseType);
}
protected void createRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {
log.debug("Creating relation: {}", relation);
relationService.saveRelation(tenantId, relation);
}
protected void deleteRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {
log.debug("Deleting relation: {}", relation);
relationService.deleteRelation(tenantId, relation);
}
protected void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
log.trace("Executing deleteEntityRelations [{}]", entityId);
relationService.deleteEntityRelations(tenantId, entityId);

44
dao/src/main/java/org/thingsboard/server/dao/entityview/CassandraEntityViewDao.java

@ -25,16 +25,23 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.model.EntitySubtypeEntity;
import org.thingsboard.server.dao.model.nosql.EntityViewEntity;
import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.util.NoSqlDao;
import javax.annotation.Nullable;
@ -73,6 +80,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.TENANT_ID_PROPERTY
@NoSqlDao
public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<EntityViewEntity, EntityView> implements EntityViewDao {
@Autowired
private RelationDao relationDao;
@Override
protected Class<EntityViewEntity> getColumnFamilyClass() {
return EntityViewEntity.class;
@ -186,30 +196,16 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {
// log.debug("Try to find entity views by tenantId [{}], customerId[{}] and pageLink [{}]",
// tenantId, customerId, pageLink);
// List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(new TenantId(tenantId),
// ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_CF,
// Arrays.asList(eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)),
// pageLink);
// log.trace("Found find entity views [{}] by tenantId [{}], customerId [{}] and pageLink [{}]",
// entityViewEntities, tenantId, customerId, pageLink);
// return DaoUtil.convertDataList(entityViewEntities);
throw new UnsupportedOperationException("Cassandra is not supported yet");
public ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
log.debug("Try to find entity views by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.ENTITY_VIEW, pageLink);
return Futures.transformAsync(relations, input -> {
List<ListenableFuture<EntityView>> entityViewFutures = new ArrayList<>(input.size());
for (EntityRelation relation : input) {
entityViewFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
}
return Futures.successfulAsList(entityViewFutures);
}, MoreExecutors.directExecutor());
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {
// log.debug("Try to find entity views by tenantId [{}], customerId[{}], type [{}] and pageLink [{}]",
// tenantId, customerId, type, pageLink);
// List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(new TenantId(tenantId),
// ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_TYPE_CF,
// Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type), eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)),
// pageLink);
// log.trace("Found find entity views [{}] by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]",
// entityViewEntities, tenantId, customerId, type, pageLink);
// return DaoUtil.convertDataList(entityViewEntities);
throw new UnsupportedOperationException("Cassandra is not supported yet");
}
}

23
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java

@ -5,7 +5,7 @@
* 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
* 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,
@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.Dao;
import java.util.List;
@ -110,22 +111,8 @@ public interface EntityViewDao extends Dao<EntityView> {
* @param pageLink the page link
* @return the list of entity view objects
*/
List<EntityView> findEntityViewsByTenantIdAndEdgeId(UUID tenantId,
UUID edgeId,
TextPageLink pageLink);
/**
* Find entity views by tenantId, edgeId, type and page link.
*
* @param tenantId the tenantId
* @param edgeId the edgeId
* @param type the type
* @param pageLink the page link
* @return the list of entity view objects
*/
List<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId,
UUID edgeId,
String type,
TextPageLink pageLink);
ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEdgeId(UUID tenantId,
UUID edgeId,
TimePageLink pageLink);
}

75
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java

@ -30,10 +30,12 @@ import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
@ -42,9 +44,13 @@ import org.thingsboard.server.common.data.id.EntityViewId;
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.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.customer.CustomerDao;
import org.thingsboard.server.dao.edge.EdgeService;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.service.DataValidator;
@ -58,6 +64,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import static org.thingsboard.server.common.data.CacheConstants.ENTITY_VIEW_CACHE;
@ -88,6 +95,9 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
@Autowired
private CustomerDao customerDao;
@Autowired
private EdgeService edgeService;
@Autowired
private CacheManager cacheManager;
@ -285,47 +295,56 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
}, MoreExecutors.directExecutor());
}
@CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
@Override
public EntityView assignEntityViewToEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId) {
EntityView entityView = findEntityViewById(tenantId, entityViewId);
entityView.setEdgeId(edgeId);
return saveEntityView(entityView);
Edge edge = edgeService.findEdgeById(tenantId, edgeId);
if (edge == null) {
throw new DataValidationException("Can't assign entityView to non-existent edge!");
}
if (!edge.getTenantId().getId().equals(entityView.getTenantId().getId())) {
throw new DataValidationException("Can't assign entityView to edge from different tenant!");
}
try {
createRelation(tenantId, new EntityRelation(edgeId, entityViewId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
} catch (ExecutionException | InterruptedException e) {
log.warn("[{}] Failed to create entityView relation. Edge Id: [{}]", entityViewId, edgeId);
throw new RuntimeException(e);
}
return entityView;
}
@CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
@Override
public EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId) {
public EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId) {
EntityView entityView = findEntityViewById(tenantId, entityViewId);
entityView.setEdgeId(null);
return saveEntityView(entityView);
}
@Override
public TextPageData<EntityView> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId,
TextPageLink pageLink) {
log.trace("Executing findEntityViewsByTenantIdAndEdgeId, tenantId [{}], edgeId [{}]," +
" pageLink [{}]", tenantId, edgeId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
List<EntityView> entityViews = entityViewDao.findEntityViewsByTenantIdAndEdgeId(tenantId.getId(),
edgeId.getId(), pageLink);
return new TextPageData<>(entityViews, pageLink);
Edge edge = edgeService.findEdgeById(tenantId, edgeId);
if (edge == null) {
throw new DataValidationException("Can't unassign entityView from non-existent edge!");
}
try {
deleteRelation(tenantId, new EntityRelation(edgeId, entityViewId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
} catch (ExecutionException | InterruptedException e) {
log.warn("[{}] Failed to delete entityView relation. Edge Id: [{}]", entityViewId, edgeId);
throw new RuntimeException(e);
}
return entityView;
}
@Override
public TextPageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink) {
log.trace("Executing findEntityViewsByTenantIdAndEdgeIdAndType, tenantId [{}], edgeId [{}]," +
" pageLink [{}], type [{}]", tenantId, edgeId, pageLink, type);
public ListenableFuture<TimePageData<EntityView>> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId,
TimePageLink pageLink) {
log.trace("Executing findEntityViewsByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
validateString(type, "Incorrect type " + type);
List<EntityView> entityViews = entityViewDao.findEntityViewsByTenantIdAndEdgeIdAndType(tenantId.getId(),
edgeId.getId(), type, pageLink);
return new TextPageData<>(entityViews, pageLink);
ListenableFuture<List<EntityView>> entityViews = entityViewDao.findEntityViewsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
return Futures.transform(entityViews, new Function<List<EntityView>, TimePageData<EntityView>>() {
@Nullable
@Override
public TimePageData<EntityView> apply(@Nullable List<EntityView> entityViews) {
return new TimePageData<>(entityViews, pageLink);
}
}, MoreExecutors.directExecutor());
}
private DataValidator<EntityView> entityViewValidator =

3
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -142,7 +142,6 @@ public class ModelConstants {
public static final String DEVICE_TYPE_PROPERTY = "type";
public static final String DEVICE_LABEL_PROPERTY = "label";
public static final String DEVICE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
public static final String DEVICE_EDGE_ID_PROPERTY = "edge_id";
public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text";
public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text";
public static final String DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_customer_and_search_text";
@ -158,7 +157,6 @@ public class ModelConstants {
public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
public static final String ENTITY_VIEW_NAME_PROPERTY = DEVICE_NAME_PROPERTY;
public static final String ENTITY_VIEW_EDGE_ID_PROPERTY = "edge_id";
public static final String ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_CF = "entity_view_by_tenant_and_customer";
public static final String ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_TYPE_CF = "entity_view_by_tenant_and_customer_and_type";
public static final String ENTITY_VIEW_BY_TENANT_AND_ENTITY_ID_CF = "entity_view_by_tenant_and_entity_id";
@ -206,7 +204,6 @@ public class ModelConstants {
public static final String ASSET_TYPE_PROPERTY = "type";
public static final String ASSET_LABEL_PROPERTY = "label";
public static final String ASSET_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
public static final String ASSET_EDGE_ID_PROPERTY = "edge_id";
public static final String ASSET_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "asset_by_tenant_and_search_text";
public static final String ASSET_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "asset_by_tenant_by_type_and_search_text";

22
dao/src/main/java/org/thingsboard/server/dao/model/nosql/AssetEntity.java

@ -25,7 +25,6 @@ import lombok.ToString;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.model.type.JsonCodec;
@ -35,11 +34,10 @@ import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_EDGE_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
@ -64,10 +62,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
@Column(name = ASSET_TYPE_PROPERTY)
private String type;
@PartitionKey(value = 4)
@Column(name = ASSET_EDGE_ID_PROPERTY)
private UUID edgeId;
@Column(name = ASSET_NAME_PROPERTY)
private String name;
@ -94,9 +88,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
if (asset.getCustomerId() != null) {
this.customerId = asset.getCustomerId().getId();
}
if (asset.getEdgeId() != null) {
this.edgeId = asset.getEdgeId().getId();
}
this.name = asset.getName();
this.type = asset.getType();
this.label = asset.getLabel();
@ -127,14 +118,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
this.customerId = customerId;
}
public UUID getEdgeId() {
return edgeId;
}
public void setEdgeId(UUID edgeId) {
this.edgeId = edgeId;
}
public String getName() {
return name;
}
@ -183,9 +166,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
if (customerId != null) {
asset.setCustomerId(new CustomerId(customerId));
}
if (edgeId != null) {
asset.setEdgeId(new EdgeId(edgeId));
}
asset.setName(name);
asset.setType(type);
asset.setLabel(label);

29
dao/src/main/java/org/thingsboard/server/dao/model/nosql/DeviceEntity.java

@ -25,14 +25,21 @@ import lombok.ToString;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.model.type.JsonCodec;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.*;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_CUSTOMER_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_LABEL_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_NAME_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
@Table(name = DEVICE_COLUMN_FAMILY_NAME)
@EqualsAndHashCode
@ -55,10 +62,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
@Column(name = DEVICE_TYPE_PROPERTY)
private String type;
@PartitionKey(value = 4)
@Column(name = DEVICE_EDGE_ID_PROPERTY)
private UUID edgeId;
@Column(name = DEVICE_NAME_PROPERTY)
private String name;
@ -85,9 +88,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
if (device.getCustomerId() != null) {
this.customerId = device.getCustomerId().getId();
}
if (device.getEdgeId() != null) {
this.edgeId = device.getEdgeId().getId();
}
this.name = device.getName();
this.type = device.getType();
this.label = device.getLabel();
@ -118,14 +118,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
this.customerId = customerId;
}
public UUID getEdgeId() {
return edgeId;
}
public void setEdgeId(UUID edgeId) {
this.edgeId = edgeId;
}
public String getName() {
return name;
}
@ -174,9 +166,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
if (customerId != null) {
device.setCustomerId(new CustomerId(customerId));
}
if (edgeId != null) {
device.setEdgeId(new EdgeId(edgeId));
}
device.setName(name);
device.setType(type);
device.setLabel(label);

12
dao/src/main/java/org/thingsboard/server/dao/model/nosql/EntityViewEntity.java

@ -29,7 +29,6 @@ import org.hibernate.annotations.Type;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
@ -42,7 +41,6 @@ import javax.persistence.Enumerated;
import java.io.IOException;
import java.util.UUID;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_EDGE_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_VIEW_TABLE_FAMILY_NAME;
@ -71,10 +69,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> {
@Column(name = DEVICE_TYPE_PROPERTY)
private String type;
@PartitionKey(value = 4)
@Column(name = DEVICE_EDGE_ID_PROPERTY)
private UUID edgeId;
@Enumerated(EnumType.STRING)
@Column(name = ENTITY_TYPE_PROPERTY)
private EntityType entityType;
@ -121,9 +115,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> {
if (entityView.getCustomerId() != null) {
this.customerId = entityView.getCustomerId().getId();
}
if (entityView.getEdgeId() != null) {
this.edgeId = entityView.getEdgeId().getId();
}
this.type = entityView.getType();
this.name = entityView.getName();
try {
@ -155,9 +146,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> {
if (customerId != null) {
entityView.setCustomerId(new CustomerId(customerId));
}
if (edgeId != null) {
entityView.setEdgeId(new EdgeId(edgeId));
}
entityView.setType(type);
entityView.setName(name);
try {

13
dao/src/main/java/org/thingsboard/server/dao/model/sql/AssetEntity.java

@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
@ -38,11 +37,10 @@ import javax.persistence.Table;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_EDGE_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
@Data
@ -58,9 +56,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
@Column(name = ASSET_CUSTOMER_ID_PROPERTY)
private String customerId;
@Column(name = ASSET_EDGE_ID_PROPERTY)
private String edgeId;
@Column(name = ASSET_NAME_PROPERTY)
private String name;
@ -91,9 +86,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
if (asset.getCustomerId() != null) {
this.customerId = UUIDConverter.fromTimeUUID(asset.getCustomerId().getId());
}
if (asset.getEdgeId() != null) {
this.edgeId = UUIDConverter.fromTimeUUID(asset.getEdgeId().getId());
}
this.name = asset.getName();
this.type = asset.getType();
this.label = asset.getLabel();
@ -124,9 +116,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
if (customerId != null) {
asset.setCustomerId(new CustomerId(UUIDConverter.fromString(customerId)));
}
if (edgeId != null) {
asset.setEdgeId(new EdgeId(UUIDConverter.fromString(edgeId)));
}
asset.setName(name);
asset.setType(type);
asset.setLabel(label);

10
dao/src/main/java/org/thingsboard/server/dao/model/sql/DeviceEntity.java

@ -24,7 +24,6 @@ import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
@ -48,9 +47,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT
@Column(name = ModelConstants.DEVICE_CUSTOMER_ID_PROPERTY)
private String customerId;
@Column(name = ModelConstants.DEVICE_EDGE_ID_PROPERTY)
private String edgeId;
@Column(name = ModelConstants.DEVICE_TYPE_PROPERTY)
private String type;
@ -81,9 +77,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT
if (device.getCustomerId() != null) {
this.customerId = toString(device.getCustomerId().getId());
}
if (device.getEdgeId() != null) {
this.edgeId = toString(device.getEdgeId().getId());
}
this.name = device.getName();
this.type = device.getType();
this.label = device.getLabel();
@ -110,9 +103,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT
if (customerId != null) {
device.setCustomerId(new CustomerId(toUUID(customerId)));
}
if (edgeId != null) {
device.setEdgeId(new EdgeId(toUUID(edgeId)));
}
device.setName(name);
device.setType(type);
device.setLabel(label);

10
dao/src/main/java/org/thingsboard/server/dao/model/sql/EntityViewEntity.java

@ -26,7 +26,6 @@ import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
@ -66,9 +65,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc
@Column(name = ModelConstants.ENTITY_VIEW_CUSTOMER_ID_PROPERTY)
private String customerId;
@Column(name = ModelConstants.ENTITY_VIEW_EDGE_ID_PROPERTY)
private String edgeId;
@Column(name = ModelConstants.DEVICE_TYPE_PROPERTY)
private String type;
@ -111,9 +107,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc
if (entityView.getCustomerId() != null) {
this.customerId = toString(entityView.getCustomerId().getId());
}
if (entityView.getEdgeId() != null) {
this.edgeId = toString(entityView.getEdgeId().getId());
}
this.type = entityView.getType();
this.name = entityView.getName();
try {
@ -151,9 +144,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc
if (customerId != null) {
entityView.setCustomerId(new CustomerId(toUUID(customerId)));
}
if (edgeId != null) {
entityView.setEdgeId(new EdgeId(toUUID(edgeId)));
}
entityView.setType(type);
entityView.setName(name);
try {

13
dao/src/main/java/org/thingsboard/server/dao/rule/BaseRuleChainService.java

@ -467,8 +467,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
return Futures.transform(ruleChains, new Function<List<RuleChain>, TimePageData<RuleChain>>() {
@Nullable
@Override
public TimePageData<RuleChain> apply(@Nullable List<RuleChain> ruleChain) {
return new TimePageData<>(ruleChain, pageLink);
public TimePageData<RuleChain> apply(@Nullable List<RuleChain> ruleChains) {
return new TimePageData<>(ruleChains, pageLink);
}
}, MoreExecutors.directExecutor());
}
@ -557,15 +557,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
ruleNodeDao.removeById(tenantId, entityId.getId());
}
private void createRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {
log.debug("Creating relation: {}", relation);
relationService.saveRelation(tenantId, relation);
}
private void deleteRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {
log.debug("Deleting relation: {}", relation);
relationService.deleteRelation(tenantId, relation);
}
private DataValidator<RuleChain> ruleChainValidator =
new DataValidator<RuleChain>() {

2
dao/src/main/java/org/thingsboard/server/dao/rule/CassandraRuleChainDao.java

@ -96,7 +96,7 @@ public class CassandraRuleChainDao extends CassandraAbstractSearchTextDao<RuleCh
@Override
public ListenableFuture<List<RuleChain>> findRuleChainsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
log.debug("Try to find rule chains by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.DASHBOARD, pageLink);
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.RULE_CHAIN, pageLink);
return Futures.transformAsync(relations, input -> {
List<ListenableFuture<RuleChain>> ruleChainFutures = new ArrayList<>(input.size());
for (EntityRelation relation : input) {

22
dao/src/main/java/org/thingsboard/server/dao/sql/asset/AssetRepository.java

@ -77,26 +77,4 @@ public interface AssetRepository extends CrudRepository<AssetEntity, String> {
@Query("SELECT DISTINCT a.type FROM AssetEntity a WHERE a.tenantId = :tenantId")
List<String> findTenantAssetTypes(@Param("tenantId") String tenantId);
@Query("SELECT a FROM AssetEntity a WHERE a.tenantId = :tenantId " +
"AND a.edgeId = :edgeId " +
"AND LOWER(a.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +
"AND a.id > :idOffset ORDER BY a.id")
List<AssetEntity> findByTenantIdAndEdgeId(@Param("tenantId") String tenantId,
@Param("edgeId") String edgeId,
@Param("textSearch") String textSearch,
@Param("idOffset") String idOffset,
Pageable pageable);
@Query("SELECT a FROM AssetEntity a WHERE a.tenantId = :tenantId " +
"AND a.edgeId = :edgeId AND a.type = :type " +
"AND LOWER(a.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +
"AND a.id > :idOffset ORDER BY a.id")
List<AssetEntity> findByTenantIdAndEdgeIdAndType(@Param("tenantId") String tenantId,
@Param("edgeId") String edgeId,
@Param("type") String type,
@Param("textSearch") String textSearch,
@Param("idOffset") String idOffset,
Pageable pageable);
}

44
dao/src/main/java/org/thingsboard/server/dao/sql/asset/JpaAssetDao.java

@ -15,19 +15,28 @@
*/
package org.thingsboard.server.dao.sql.asset;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.asset.AssetDao;
import org.thingsboard.server.dao.model.sql.AssetEntity;
import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.util.SqlDao;
@ -47,11 +56,15 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;
*/
@Component
@SqlDao
@Slf4j
public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao {
@Autowired
private AssetRepository assetRepository;
@Autowired
private RelationDao relationDao;
@Override
protected Class<AssetEntity> getEntityClass() {
return AssetEntity.class;
@ -141,27 +154,16 @@ public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> im
}
@Override
public List<Asset> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {
return DaoUtil.convertDataList(assetRepository
.findByTenantIdAndEdgeId(
fromTimeUUID(tenantId),
fromTimeUUID(edgeId),
Objects.toString(pageLink.getTextSearch(), ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
PageRequest.of(0, pageLink.getLimit())));
}
@Override
public List<Asset> findAssetsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {
return DaoUtil.convertDataList(assetRepository
.findByTenantIdAndEdgeIdAndType(
fromTimeUUID(tenantId),
fromTimeUUID(edgeId),
type,
Objects.toString(pageLink.getTextSearch(), ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
PageRequest.of(0, pageLink.getLimit())));
public ListenableFuture<List<Asset>> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
log.debug("Try to find assets by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.ASSET, pageLink);
return Futures.transformAsync(relations, input -> {
List<ListenableFuture<Asset>> assetFutures = new ArrayList<>(input.size());
for (EntityRelation relation : input) {
assetFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
}
return Futures.successfulAsList(assetFutures);
}, MoreExecutors.directExecutor());
}
}

22
dao/src/main/java/org/thingsboard/server/dao/sql/device/DeviceRepository.java

@ -85,26 +85,4 @@ public interface DeviceRepository extends CrudRepository<DeviceEntity, String> {
List<DeviceEntity> findDevicesByTenantIdAndCustomerIdAndIdIn(String tenantId, String customerId, List<String> deviceIds);
List<DeviceEntity> findDevicesByTenantIdAndIdIn(String tenantId, List<String> deviceIds);
@Query("SELECT d FROM DeviceEntity d WHERE d.tenantId = :tenantId " +
"AND d.edgeId = :edgeId " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " +
"AND d.id > :idOffset ORDER BY d.id")
List<DeviceEntity> findByTenantIdAndEdgeId(@Param("tenantId") String tenantId,
@Param("edgeId") String edgeId,
@Param("searchText") String searchText,
@Param("idOffset") String idOffset,
Pageable pageable);
@Query("SELECT d FROM DeviceEntity d WHERE d.tenantId = :tenantId " +
"AND d.edgeId = :edgeId " +
"AND d.type = :type " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +
"AND d.id > :idOffset ORDER BY d.id")
List<DeviceEntity> findByTenantIdAndEdgeIdAndType(@Param("tenantId") String tenantId,
@Param("edgeId") String edgeId,
@Param("type") String type,
@Param("textSearch") String textSearch,
@Param("idOffset") String idOffset,
Pageable pageable);
}

45
dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceDao.java

@ -15,7 +15,10 @@
*/
package org.thingsboard.server.dao.sql.device;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.CrudRepository;
@ -25,11 +28,17 @@ import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.device.DeviceDao;
import org.thingsboard.server.dao.model.sql.DeviceEntity;
import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.util.SqlDao;
@ -49,11 +58,15 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;
*/
@Component
@SqlDao
@Slf4j
public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao {
@Autowired
private DeviceRepository deviceRepository;
@Autowired
private RelationDao relationDao;
@Override
protected Class<DeviceEntity> getEntityClass() {
return DeviceEntity.class;
@ -149,28 +162,16 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
return list;
}
@Override
public List<Device> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {
return DaoUtil.convertDataList(
deviceRepository.findByTenantIdAndEdgeId(
fromTimeUUID(tenantId),
fromTimeUUID(edgeId),
Objects.toString(pageLink.getTextSearch(), ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
PageRequest.of(0, pageLink.getLimit())));
}
@Override
public List<Device> findDevicesByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {
return DaoUtil.convertDataList(
deviceRepository.findByTenantIdAndEdgeIdAndType(
fromTimeUUID(tenantId),
fromTimeUUID(edgeId),
type,
Objects.toString(pageLink.getTextSearch(), ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
PageRequest.of(0, pageLink.getLimit())));
public ListenableFuture<List<Device>> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
log.debug("Try to find devices by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.DEVICE, pageLink);
return Futures.transformAsync(relations, input -> {
List<ListenableFuture<Device>> deviceFutures = new ArrayList<>(input.size());
for (EntityRelation relation : input) {
deviceFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
}
return Futures.successfulAsList(deviceFutures);
}, MoreExecutors.directExecutor());
}
}

22
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/EntityViewRepository.java

@ -76,26 +76,4 @@ public interface EntityViewRepository extends CrudRepository<EntityViewEntity, S
@Query("SELECT DISTINCT ev.type FROM EntityViewEntity ev WHERE ev.tenantId = :tenantId")
List<String> findTenantEntityViewTypes(@Param("tenantId") String tenantId);
@Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " +
"AND e.edgeId = :edgeId " +
"AND LOWER(e.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " +
"AND e.id > :idOffset ORDER BY e.id")
List<EntityViewEntity> findByTenantIdAndEdgeId(@Param("tenantId") String tenantId,
@Param("edgeId") String edgeId,
@Param("searchText") String searchText,
@Param("idOffset") String idOffset,
Pageable pageable);
@Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " +
"AND e.edgeId = :edgeId " +
"AND e.type = :type " +
"AND LOWER(e.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " +
"AND e.id > :idOffset ORDER BY e.id")
List<EntityViewEntity> findByTenantIdAndEdgeIdAndType(@Param("tenantId") String tenantId,
@Param("edgeId") String edgeId,
@Param("type") String type,
@Param("searchText") String searchText,
@Param("idOffset") String idOffset,
Pageable pageable);
}

48
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java

@ -15,20 +15,29 @@
*/
package org.thingsboard.server.dao.sql.entityview;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.entityview.EntityViewDao;
import org.thingsboard.server.dao.model.sql.EntityViewEntity;
import org.thingsboard.server.dao.relation.RelationDao;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.util.SqlDao;
@ -47,12 +56,16 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;
*/
@Component
@SqlDao
@Slf4j
public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, EntityView>
implements EntityViewDao {
@Autowired
private EntityViewRepository entityViewRepository;
@Autowired
private RelationDao relationDao;
@Override
protected Class<EntityViewEntity> getEntityClass() {
return EntityViewEntity.class;
@ -140,30 +153,15 @@ public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity,
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndEdgeId(UUID tenantId,
UUID edgeId,
TextPageLink pageLink) {
return DaoUtil.convertDataList(
entityViewRepository.findByTenantIdAndEdgeId(
fromTimeUUID(tenantId),
fromTimeUUID(edgeId),
Objects.toString(pageLink.getTextSearch(), ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
PageRequest.of(0, pageLink.getLimit())
));
}
@Override
public List<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {
return DaoUtil.convertDataList(
entityViewRepository.findByTenantIdAndEdgeIdAndType(
fromTimeUUID(tenantId),
fromTimeUUID(edgeId),
type,
Objects.toString(pageLink.getTextSearch(), ""),
pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),
PageRequest.of(0, pageLink.getLimit())
));
public ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
log.debug("Try to find entity views by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.ENTITY_VIEW, pageLink);
return Futures.transformAsync(relations, input -> {
List<ListenableFuture<EntityView>> entityViewFutures = new ArrayList<>(input.size());
for (EntityRelation relation : input) {
entityViewFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
}
return Futures.successfulAsList(entityViewFutures);
}, MoreExecutors.directExecutor());
}
}

3
dao/src/main/resources/sql/schema-entities-hsql.sql

@ -42,7 +42,6 @@ CREATE TABLE IF NOT EXISTS asset (
id varchar(31) NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
additional_info varchar,
customer_id varchar(31),
edge_id varchar(31),
name varchar(255),
label varchar(255),
search_text varchar(255),
@ -120,7 +119,6 @@ CREATE TABLE IF NOT EXISTS device (
id varchar(31) NOT NULL CONSTRAINT device_pkey PRIMARY KEY,
additional_info varchar,
customer_id varchar(31),
edge_id varchar(31),
type varchar(255),
name varchar(255),
label varchar(255),
@ -247,7 +245,6 @@ CREATE TABLE IF NOT EXISTS entity_view (
entity_type varchar(255),
tenant_id varchar(31),
customer_id varchar(31),
edge_id varchar(31),
type varchar(255),
name varchar(255),
keys varchar(10000000),

3
dao/src/main/resources/sql/schema-entities.sql

@ -42,7 +42,6 @@ CREATE TABLE IF NOT EXISTS asset (
id varchar(31) NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
additional_info varchar,
customer_id varchar(31),
edge_id varchar(31),
name varchar(255),
label varchar(255),
search_text varchar(255),
@ -120,7 +119,6 @@ CREATE TABLE IF NOT EXISTS device (
id varchar(31) NOT NULL CONSTRAINT device_pkey PRIMARY KEY,
additional_info varchar,
customer_id varchar(31),
edge_id varchar(31),
type varchar(255),
name varchar(255),
label varchar(255),
@ -247,7 +245,6 @@ CREATE TABLE IF NOT EXISTS entity_view (
entity_type varchar(255),
tenant_id varchar(31),
customer_id varchar(31),
edge_id varchar(31),
type varchar(255),
name varchar(255),
keys varchar(10000000),

24
ui/src/app/api/asset.service.js

@ -18,7 +18,7 @@ export default angular.module('thingsboard.api.asset', [])
.name;
/*@ngInject*/
function AssetService($http, $q, customerService, userService) {
function AssetService($http, $q, $filter, customerService, userService) {
var service = {
getAsset: getAsset,
@ -307,9 +307,9 @@ function AssetService($http, $q, customerService, userService) {
return deferred.promise;
}
function unassignAssetFromEdge(assetId, ignoreErrors, config) {
function unassignAssetFromEdge(edgeId, assetId, ignoreErrors, config) {
var deferred = $q.defer();
var url = '/api/edge/asset/' + assetId;
var url = '/api/edge/' + edgeId + '/asset/' + assetId;
if (!config) {
config = {};
}
@ -325,24 +325,20 @@ function AssetService($http, $q, customerService, userService) {
function getEdgeAssets(edgeId, pageLink, config, type) {
var deferred = $q.defer();
var url = '/api/edge/' + edgeId + '/assets?limit=' + pageLink.limit;
if (angular.isDefined(pageLink.textSearch)) {
url += '&textSearch=' + pageLink.textSearch;
}
if (angular.isDefined(pageLink.idOffset)) {
url += '&idOffset=' + pageLink.idOffset;
}
if (angular.isDefined(pageLink.textOffset)) {
url += '&textOffset=' + pageLink.textOffset;
}
if (angular.isDefined(type) && type.length) {
url += '&type=' + type;
url += '&offset=' + pageLink.idOffset;
}
$http.get(url, config).then(function success(response) {
if (pageLink.textSearch) {
response.data.data = $filter('filter')(response.data.data, {name: pageLink.textSearch});
}
if (angular.isDefined(type) && type.length) {
response.data.data = $filter('filter')(response.data.data, {type: type});
}
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
}

25
ui/src/app/api/device.service.js

@ -20,7 +20,7 @@ export default angular.module('thingsboard.api.device', [thingsboardTypes])
.name;
/*@ngInject*/
function DeviceService($http, $q, $window, userService, attributeService, customerService, types) {
function DeviceService($http, $q, $window, $filter, userService, attributeService, customerService, types) {
var service = {
assignDeviceToCustomer: assignDeviceToCustomer,
@ -373,9 +373,9 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
return deferred.promise;
}
function unassignDeviceFromEdge(deviceId) {
function unassignDeviceFromEdge(edgeId, deviceId) {
var deferred = $q.defer();
var url = '/api/edge/device/' + deviceId;
var url = '/api/edge/' + edgeId + '/device/' + deviceId;
$http.delete(url).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {
@ -387,25 +387,20 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
function getEdgeDevices(edgeId, pageLink, config, type) {
var deferred = $q.defer();
var url = '/api/edge/' + edgeId + '/devices?limit=' + pageLink.limit;
if (angular.isDefined(pageLink.textSearch)) {
url += '&textSearch=' + pageLink.textSearch;
}
if (angular.isDefined(pageLink.idOffset)) {
url += '&idOffset=' + pageLink.idOffset;
}
if (angular.isDefined(pageLink.textOffset)) {
url += '&textOffset=' + pageLink.textOffset;
}
if (angular.isDefined(type) && type.length) {
url += '&type=' + type;
url += '&offset=' + pageLink.idOffset;
}
$http.get(url, config).then(function success(response) {
if (pageLink.textSearch) {
response.data.data = $filter('filter')(response.data.data, {name: pageLink.textSearch});
}
if (angular.isDefined(type) && type.length) {
response.data.data = $filter('filter')(response.data.data, {type: type});
}
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
}

24
ui/src/app/api/entity-view.service.js

@ -20,7 +20,7 @@ export default angular.module('thingsboard.api.entityView', [thingsboardTypes])
.name;
/*@ngInject*/
function EntityViewService($http, $q, $window, userService, attributeService, customerService, types) {
function EntityViewService($http, $q, $window, $filter, userService, attributeService, customerService, types) {
var service = {
assignEntityViewToCustomer: assignEntityViewToCustomer,
@ -234,9 +234,9 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu
return deferred.promise;
}
function unassignEntityViewFromEdge(entityViewId) {
function unassignEntityViewFromEdge(edgeId, entityViewId) {
var deferred = $q.defer();
var url = '/api/edge/entityView/' + entityViewId;
var url = '/api/edge/' + edgeId + '/entityView/' + entityViewId;
$http.delete(url).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {
@ -248,24 +248,20 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu
function getEdgeEntityViews(edgeId, pageLink, config, type) {
var deferred = $q.defer();
var url = '/api/edge/' + edgeId + '/entityViews?limit=' + pageLink.limit;
if (angular.isDefined(pageLink.textSearch)) {
url += '&textSearch=' + pageLink.textSearch;
}
if (angular.isDefined(pageLink.idOffset)) {
url += '&idOffset=' + pageLink.idOffset;
}
if (angular.isDefined(pageLink.textOffset)) {
url += '&textOffset=' + pageLink.textOffset;
}
if (angular.isDefined(type) && type.length) {
url += '&type=' + type;
url += '&offset=' + pageLink.idOffset;
}
$http.get(url, config).then(function success(response) {
if (pageLink.textSearch) {
response.data.data = $filter('filter')(response.data.data, {name: pageLink.textSearch});
}
if (angular.isDefined(type) && type.length) {
response.data.data = $filter('filter')(response.data.data, {type: type});
}
deferred.resolve(response.data);
}, function fail() {
deferred.reject();
});
return deferred.promise;
}
}

12
ui/src/app/asset/asset.controller.js

@ -327,7 +327,7 @@ export function AssetController($rootScope, userService, assetService, customerS
return assetService.getEdgeAssets(edgeId, pageLink, null, assetType);
};
deleteAssetFunction = function (assetId) {
return assetService.unassignAssetFromEdge(assetId);
return assetService.unassignAssetFromEdge(edgeId, assetId);
};
refreshAssetsParamsFunction = function () {
return {"edgeId": edgeId, "topIndex": vm.topIndex};
@ -630,7 +630,7 @@ export function AssetController($rootScope, userService, assetService, customerS
.cancel($translate.instant('action.no'))
.ok($translate.instant('action.yes'));
$mdDialog.show(confirm).then(function () {
assetService.unassignAssetFromEdge(asset.id.id).then(function success() {
assetService.unassignAssetFromEdge(edgeId, asset.id.id).then(function success() {
vm.grid.refreshList();
});
});
@ -639,15 +639,15 @@ export function AssetController($rootScope, userService, assetService, customerS
function unassignAssetsFromEdge($event, items) {
var confirm = $mdDialog.confirm()
.targetEvent($event)
.title($translate.instant('asset.unassign-assets-title', {count: items.selectedCount}, 'messageformat'))
.htmlContent($translate.instant('asset.unassign-assets-text'))
.ariaLabel($translate.instant('asset.unassign-asset'))
.title($translate.instant('asset.unassign-assets-from-edge-title', {count: items.selectedCount}, 'messageformat'))
.htmlContent($translate.instant('asset.unassign-assets-from-edge-text'))
.ariaLabel($translate.instant('asset.unassign-asset-from-edge'))
.cancel($translate.instant('action.no'))
.ok($translate.instant('action.yes'));
$mdDialog.show(confirm).then(function () {
var tasks = [];
for (var id in items.selections) {
tasks.push(assetService.unassignAssetFromEdge(id));
tasks.push(assetService.unassignAssetFromEdge(edgeId, id));
}
$q.all(tasks).then(function () {
vm.grid.refreshList();

12
ui/src/app/device/device.controller.js

@ -360,7 +360,7 @@ export function DeviceController($rootScope, userService, deviceService, custome
return deviceService.getEdgeDevices(edgeId, pageLink, null, deviceType);
};
deleteDeviceFunction = function (deviceId) {
return deviceService.unassignDeviceFromEdge(deviceId);
return deviceService.unassignDeviceFromEdge(edgeId, deviceId);
};
refreshDevicesParamsFunction = function () {
return {"edgeId": edgeId, "topIndex": vm.topIndex};
@ -679,7 +679,7 @@ export function DeviceController($rootScope, userService, deviceService, custome
.cancel($translate.instant('action.no'))
.ok($translate.instant('action.yes'));
$mdDialog.show(confirm).then(function () {
deviceService.unassignDeviceFromEdge(device.id.id).then(function success() {
deviceService.unassignDeviceFromEdge(edgeId, device.id.id).then(function success() {
vm.grid.refreshList();
});
});
@ -688,15 +688,15 @@ export function DeviceController($rootScope, userService, deviceService, custome
function unassignDevicesFromEdge($event, items) {
var confirm = $mdDialog.confirm()
.targetEvent($event)
.title($translate.instant('device.unassign-devices-title', {count: items.selectedCount}, 'messageformat'))
.htmlContent($translate.instant('device.unassign-devices-text'))
.ariaLabel($translate.instant('device.unassign-device'))
.title($translate.instant('device.unassign-devices-from-edge-title', {count: items.selectedCount}, 'messageformat'))
.htmlContent($translate.instant('device.unassign-devices-from-edge-text'))
.ariaLabel($translate.instant('device.unassign-device-from-edge'))
.cancel($translate.instant('action.no'))
.ok($translate.instant('action.yes'));
$mdDialog.show(confirm).then(function () {
var tasks = [];
for (var id in items.selections) {
tasks.push(deviceService.unassignDeviceFromEdge(id));
tasks.push(deviceService.unassignDeviceFromEdge(edgeId, id));
}
$q.all(tasks).then(function () {
vm.grid.refreshList();

19
ui/src/app/entity-view/entity-view.controller.js

@ -288,7 +288,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
return entityViewService.getEdgeEntityViews(edgeId, pageLink, null, entityViewType);
};
deleteEntityViewFunction = function (entityViewId) {
return entityViewService.unassignEntityViewFromEdge(entityViewId);
return entityViewService.unassignEntityViewFromEdge(edgeId, entityViewId);
};
refreshEntityViewsParamsFunction = function () {
return {"edgeId": edgeId, "topIndex": vm.topIndex};
@ -300,10 +300,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
},
name: function() { return $translate.instant('action.unassign') },
details: function() { return $translate.instant('entity-view.unassign-from-edge') },
icon: "assignment_return",
isEnabled: function(entityView) {
return entityView && entityView.edgeId && entityView.edgeId.id !== types.id.nullUid;
}
icon: "assignment_return"
}
);
@ -314,7 +311,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
},
name: function() { return $translate.instant('entity-view.unassign-entity-views') },
details: function(selectedCount) {
return $translate.instant('entity-view.unassign-entity-views-action-title', {count: selectedCount}, "messageformat");
return $translate.instant('entity-view.unassign-entity-views-from-edge-action-title', {count: selectedCount}, "messageformat");
},
icon: "assignment_return"
}
@ -581,15 +578,15 @@ export function EntityViewController($rootScope, userService, entityViewService,
function unassignEntityViewsFromEdge($event, items) {
var confirm = $mdDialog.confirm()
.targetEvent($event)
.title($translate.instant('entity-view.unassign-entity-views-title', {count: items.selectedCount}, 'messageformat'))
.htmlContent($translate.instant('entity-view.unassign-entity-views-text'))
.ariaLabel($translate.instant('entity-view.unassign-entity-view'))
.title($translate.instant('entity-view.unassign-entity-views-from-edge-title', {count: items.selectedCount}, 'messageformat'))
.htmlContent($translate.instant('entity-view.unassign-entity-views-from-edge-text'))
.ariaLabel($translate.instant('entity-view.unassign-entity-view-from-edge'))
.cancel($translate.instant('action.no'))
.ok($translate.instant('action.yes'));
$mdDialog.show(confirm).then(function () {
var tasks = [];
for (var id in items.selections) {
tasks.push(entityViewService.unassignEntityViewFromEdge(id));
tasks.push(entityViewService.unassignEntityViewFromEdge(edgeId, id));
}
$q.all(tasks).then(function () {
vm.grid.refreshList();
@ -612,7 +609,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
.cancel($translate.instant('action.no'))
.ok($translate.instant('action.yes'));
$mdDialog.show(confirm).then(function () {
entityViewService.unassignEntityViewFromEdge(entityView.id.id).then(function success() {
entityViewService.unassignEntityViewFromEdge(edgeId, entityView.id.id).then(function success() {
vm.grid.refreshList();
});
});

17
ui/src/app/locale/locale.constant-en_US.json

@ -291,9 +291,12 @@
"unassign-from-edge": "Unassign from edge",
"assign-to-edge": "Assign to edge",
"assign-to-edge-text": "Please select the edge to assign the asset(s)",
"unassign-asset-from-edge": "Unassign asset",
"unassign-asset-from-edge-title": "Are you sure you want to unassign the asset '{{assetName}}'?",
"unassign-asset-from-edge-text": "After the confirmation the asset will be unassigned and won't be accessible by the edge.",
"unassign-assets-from-edge-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from edge"
"unassign-assets-from-edge-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from edge",
"unassign-assets-from-edge-title": "Are you sure you want to unassign { count, plural, 1 {1 asset} other {# assets} }?",
"unassign-assets-from-edge-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the edge."
},
"attribute": {
"attributes": "Attributes",
@ -748,7 +751,10 @@
"assign-to-edge-text": "Please select the edge to assign the device(s)",
"unassign-device-from-edge-title": "Are you sure you want to unassign the device '{{deviceName}}'?",
"unassign-device-from-edge-text": "After the confirmation the device will be unassigned and won't be accessible by the edge.",
"unassign-devices-from-edge-action-title": "Unassign { count, plural, 1 {1 device} other {# devices} } from edge"
"unassign-devices-from-edge-action-title": "Unassign { count, plural, 1 {1 device} other {# devices} } from edge",
"unassign-device-from-edge": "Unassign device",
"unassign-devices-from-edge-title": "Are you sure you want to unassign { count, plural, 1 {1 device} other {# devices} }?",
"unassign-devices-from-edge-text": "After the confirmation all selected devices will be unassigned and won't be accessible by the edge."
},
"dialog": {
"close": "Close dialog"
@ -1054,7 +1060,10 @@
"assign-to-edge-text": "Please select the edge to assign the entity view(s)",
"unassign-entity-view-from-edge-title": "Are you sure you want to unassign the entity view '{{entityViewName}}'?",
"unassign-entity-view-from-edge-text": "After the confirmation the entity view will be unassigned and won't be accessible by the edge.",
"unassign-entity-views-from-edge-action-title": "Unassign { count, plural, 1 {1 entity view} other {# entity views} } from edge"
"unassign-entity-views-from-edge-action-title": "Unassign { count, plural, 1 {1 entity view} other {# entity views} } from edge",
"unassign-entity-view-from-edge": "Unassign entity view",
"unassign-entity-views-from-edge-title": "Are you sure you want to unassign { count, plural, 1 {1 entity view} other {# entity views} }?",
"unassign-entity-views-from-edge-text": "After the confirmation all selected entity views will be unassigned and won't be accessible by the edge."
},
"event": {
"event-type": "Event type",
@ -1580,7 +1589,7 @@
"invalid-rulechain-type-error": "Unable to import rule chain: Invalid rule chain type. Expected type is {{expectedRuleChainType}}.",
"set-default-edge": "Make edge rule chain default",
"set-default-edge-title": "Are you sure you want to make the edge rule chain '{{ruleChainName}}' default?",
"set-default-edge-text": "After the confirmation the edge rule chain will be added to default list and handle all incoming transport messages.",
"set-default-edge-text": "After the confirmation the edge rule chain will be added to default list and assigned to newly created edge(s).",
"remove-default-edge": "Remove edge rule chain from defaults",
"remove-default-edge-title": "Are you sure you want to remove the edge rule chain '{{ruleChainName}}' from default list?",
"remove-default-edge-text": "After the confirmation the edge rule chain will stop handling all incoming transport messages."

Loading…
Cancel
Save