Commit 134148c49f0cabfc269e66ce72c931405dd81e0d

Authored by Volodymyr Babak
1 parent 8416c206

Removed edgeId. Code clean up and refactoring

Showing 50 changed files with 499 additions and 688 deletions
@@ -40,6 +40,8 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -40,6 +40,8 @@ import org.thingsboard.server.common.data.id.EdgeId;
40 import org.thingsboard.server.common.data.id.TenantId; 40 import org.thingsboard.server.common.data.id.TenantId;
41 import org.thingsboard.server.common.data.page.TextPageData; 41 import org.thingsboard.server.common.data.page.TextPageData;
42 import org.thingsboard.server.common.data.page.TextPageLink; 42 import org.thingsboard.server.common.data.page.TextPageLink;
  43 +import org.thingsboard.server.common.data.page.TimePageData;
  44 +import org.thingsboard.server.common.data.page.TimePageLink;
43 import org.thingsboard.server.dao.exception.IncorrectParameterException; 45 import org.thingsboard.server.dao.exception.IncorrectParameterException;
44 import org.thingsboard.server.dao.model.ModelConstants; 46 import org.thingsboard.server.dao.model.ModelConstants;
45 import org.thingsboard.server.queue.util.TbCoreComponent; 47 import org.thingsboard.server.queue.util.TbCoreComponent;
@@ -51,6 +53,8 @@ import java.util.ArrayList; @@ -51,6 +53,8 @@ import java.util.ArrayList;
51 import java.util.List; 53 import java.util.List;
52 import java.util.stream.Collectors; 54 import java.util.stream.Collectors;
53 55
  56 +import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
  57 +
54 @RestController 58 @RestController
55 @TbCoreComponent 59 @TbCoreComponent
56 @RequestMapping("/api") 60 @RequestMapping("/api")
@@ -336,9 +340,9 @@ public class AssetController extends BaseController { @@ -336,9 +340,9 @@ public class AssetController extends BaseController {
336 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 340 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
337 @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.POST) 341 @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.POST)
338 @ResponseBody 342 @ResponseBody
339 - public Asset assignAssetToEdge(@PathVariable("edgeId") String strEdgeId, 343 + public Asset assignAssetToEdge(@PathVariable(EDGE_ID) String strEdgeId,
340 @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { 344 @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
341 - checkParameter("edgeId", strEdgeId); 345 + checkParameter(EDGE_ID, strEdgeId);
342 checkParameter(ASSET_ID, strAssetId); 346 checkParameter(ASSET_ID, strAssetId);
343 try { 347 try {
344 EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); 348 EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
@@ -365,20 +369,20 @@ public class AssetController extends BaseController { @@ -365,20 +369,20 @@ public class AssetController extends BaseController {
365 } 369 }
366 370
367 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 371 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
368 - @RequestMapping(value = "/edge/asset/{assetId}", method = RequestMethod.DELETE) 372 + @RequestMapping(value = "/edge/{edgeId}/asset/{assetId}", method = RequestMethod.DELETE)
369 @ResponseBody 373 @ResponseBody
370 - public Asset unassignAssetFromEdge(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { 374 + public Asset unassignAssetFromEdge(@PathVariable(EDGE_ID) String strEdgeId,
  375 + @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException {
  376 + checkParameter(EDGE_ID, strEdgeId);
371 checkParameter(ASSET_ID, strAssetId); 377 checkParameter(ASSET_ID, strAssetId);
372 try { 378 try {
  379 + EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
  380 + Edge edge = checkEdgeId(edgeId, Operation.READ);
  381 +
373 AssetId assetId = new AssetId(toUUID(strAssetId)); 382 AssetId assetId = new AssetId(toUUID(strAssetId));
374 Asset asset = checkAssetId(assetId, Operation.UNASSIGN_FROM_EDGE); 383 Asset asset = checkAssetId(assetId, Operation.UNASSIGN_FROM_EDGE);
375 - if (asset.getEdgeId() == null || asset.getEdgeId().getId().equals(ModelConstants.NULL_UUID)) {  
376 - throw new IncorrectParameterException("Asset isn't assigned to any edge!");  
377 - }  
378 384
379 - Edge edge = checkEdgeId(asset.getEdgeId(), Operation.READ);  
380 -  
381 - Asset savedAsset = checkNotNull(assetService.unassignAssetFromEdge(getTenantId(), assetId)); 385 + Asset savedAsset = checkNotNull(assetService.unassignAssetFromEdge(getTenantId(), assetId, edgeId));
382 386
383 logEntityAction(assetId, asset, 387 logEntityAction(assetId, asset,
384 asset.getCustomerId(), 388 asset.getCustomerId(),
@@ -398,24 +402,20 @@ public class AssetController extends BaseController { @@ -398,24 +402,20 @@ public class AssetController extends BaseController {
398 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 402 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
399 @RequestMapping(value = "/edge/{edgeId}/assets", params = {"limit"}, method = RequestMethod.GET) 403 @RequestMapping(value = "/edge/{edgeId}/assets", params = {"limit"}, method = RequestMethod.GET)
400 @ResponseBody 404 @ResponseBody
401 - public TextPageData<Asset> getEdgeAssets(  
402 - @PathVariable("edgeId") String strEdgeId, 405 + public TimePageData<Asset> getEdgeAssets(
  406 + @PathVariable(EDGE_ID) String strEdgeId,
403 @RequestParam int limit, 407 @RequestParam int limit,
404 - @RequestParam(required = false) String type,  
405 - @RequestParam(required = false) String textSearch,  
406 - @RequestParam(required = false) String idOffset,  
407 - @RequestParam(required = false) String textOffset) throws ThingsboardException {  
408 - checkParameter("edgeId", strEdgeId); 408 + @RequestParam(required = false) Long startTime,
  409 + @RequestParam(required = false) Long endTime,
  410 + @RequestParam(required = false, defaultValue = "false") boolean ascOrder,
  411 + @RequestParam(required = false) String offset) throws ThingsboardException {
  412 + checkParameter(EDGE_ID, strEdgeId);
409 try { 413 try {
410 TenantId tenantId = getCurrentUser().getTenantId(); 414 TenantId tenantId = getCurrentUser().getTenantId();
411 EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); 415 EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
412 checkEdgeId(edgeId, Operation.READ); 416 checkEdgeId(edgeId, Operation.READ);
413 - TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);  
414 - if (type != null && type.trim().length()>0) {  
415 - return checkNotNull(assetService.findAssetsByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink));  
416 - } else {  
417 - return checkNotNull(assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink));  
418 - } 417 + TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
  418 + return checkNotNull(assetService.findAssetsByTenantIdAndEdgeId(tenantId, edgeId, pageLink).get());
419 } catch (Exception e) { 419 } catch (Exception e) {
420 throw handleException(e); 420 throw handleException(e);
421 } 421 }
@@ -49,6 +49,9 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -49,6 +49,9 @@ import org.thingsboard.server.common.data.id.EdgeId;
49 import org.thingsboard.server.common.data.id.TenantId; 49 import org.thingsboard.server.common.data.id.TenantId;
50 import org.thingsboard.server.common.data.page.TextPageData; 50 import org.thingsboard.server.common.data.page.TextPageData;
51 import org.thingsboard.server.common.data.page.TextPageLink; 51 import org.thingsboard.server.common.data.page.TextPageLink;
  52 +import org.thingsboard.server.common.data.page.TimePageData;
  53 +import org.thingsboard.server.common.data.page.TimePageLink;
  54 +import org.thingsboard.server.common.data.rule.RuleChain;
52 import org.thingsboard.server.common.data.security.DeviceCredentials; 55 import org.thingsboard.server.common.data.security.DeviceCredentials;
53 import org.thingsboard.server.dao.device.claim.ClaimResponse; 56 import org.thingsboard.server.dao.device.claim.ClaimResponse;
54 import org.thingsboard.server.dao.device.claim.ClaimResult; 57 import org.thingsboard.server.dao.device.claim.ClaimResult;
@@ -519,19 +522,20 @@ public class DeviceController extends BaseController { @@ -519,19 +522,20 @@ public class DeviceController extends BaseController {
519 } 522 }
520 523
521 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 524 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
522 - @RequestMapping(value = "/edge/device/{deviceId}", method = RequestMethod.DELETE) 525 + @RequestMapping(value = "/edge/{edgeId}/device/{deviceId}", method = RequestMethod.DELETE)
523 @ResponseBody 526 @ResponseBody
524 - public Device unassignDeviceFromEdge(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { 527 + public Device unassignDeviceFromEdge(@PathVariable(EDGE_ID) String strEdgeId,
  528 + @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException {
  529 + checkParameter(EDGE_ID, strEdgeId);
525 checkParameter(DEVICE_ID, strDeviceId); 530 checkParameter(DEVICE_ID, strDeviceId);
526 try { 531 try {
  532 + EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
  533 + Edge edge = checkEdgeId(edgeId, Operation.READ);
  534 +
527 DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); 535 DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
528 Device device = checkDeviceId(deviceId, Operation.UNASSIGN_FROM_EDGE); 536 Device device = checkDeviceId(deviceId, Operation.UNASSIGN_FROM_EDGE);
529 - if (device.getEdgeId() == null || device.getEdgeId().getId().equals(ModelConstants.NULL_UUID)) {  
530 - throw new IncorrectParameterException("Device isn't assigned to any edge!");  
531 - }  
532 - Edge edge = checkEdgeId(device.getEdgeId(), Operation.READ);  
533 537
534 - Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(getCurrentUser().getTenantId(), deviceId)); 538 + Device savedDevice = checkNotNull(deviceService.unassignDeviceFromEdge(getCurrentUser().getTenantId(), deviceId, edgeId));
535 539
536 logEntityAction(deviceId, device, 540 logEntityAction(deviceId, device,
537 device.getCustomerId(), 541 device.getCustomerId(),
@@ -549,24 +553,20 @@ public class DeviceController extends BaseController { @@ -549,24 +553,20 @@ public class DeviceController extends BaseController {
549 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 553 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
550 @RequestMapping(value = "/edge/{edgeId}/devices", params = {"limit"}, method = RequestMethod.GET) 554 @RequestMapping(value = "/edge/{edgeId}/devices", params = {"limit"}, method = RequestMethod.GET)
551 @ResponseBody 555 @ResponseBody
552 - public TextPageData<Device> getEdgeDevices(  
553 - @PathVariable("edgeId") String strEdgeId, 556 + public TimePageData<Device> getEdgeDevices(
  557 + @PathVariable(EDGE_ID) String strEdgeId,
554 @RequestParam int limit, 558 @RequestParam int limit,
555 - @RequestParam(required = false) String type,  
556 - @RequestParam(required = false) String textSearch,  
557 - @RequestParam(required = false) String idOffset,  
558 - @RequestParam(required = false) String textOffset) throws ThingsboardException {  
559 - checkParameter("edgeId", strEdgeId); 559 + @RequestParam(required = false) Long startTime,
  560 + @RequestParam(required = false) Long endTime,
  561 + @RequestParam(required = false, defaultValue = "false") boolean ascOrder,
  562 + @RequestParam(required = false) String offset) throws ThingsboardException {
  563 + checkParameter(EDGE_ID, strEdgeId);
560 try { 564 try {
561 TenantId tenantId = getCurrentUser().getTenantId(); 565 TenantId tenantId = getCurrentUser().getTenantId();
562 EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); 566 EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
563 checkEdgeId(edgeId, Operation.READ); 567 checkEdgeId(edgeId, Operation.READ);
564 - TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);  
565 - if (type != null && type.trim().length()>0) {  
566 - return checkNotNull(deviceService.findDevicesByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink));  
567 - } else {  
568 - return checkNotNull(deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edgeId, pageLink));  
569 - } 568 + TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
  569 + return checkNotNull(deviceService.findDevicesByTenantIdAndEdgeId(tenantId, edgeId, pageLink).get());
570 } catch (Exception e) { 570 } catch (Exception e) {
571 throw handleException(e); 571 throw handleException(e);
572 } 572 }
@@ -48,6 +48,8 @@ import org.thingsboard.server.common.data.id.UUIDBased; @@ -48,6 +48,8 @@ import org.thingsboard.server.common.data.id.UUIDBased;
48 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 48 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
49 import org.thingsboard.server.common.data.page.TextPageData; 49 import org.thingsboard.server.common.data.page.TextPageData;
50 import org.thingsboard.server.common.data.page.TextPageLink; 50 import org.thingsboard.server.common.data.page.TextPageLink;
  51 +import org.thingsboard.server.common.data.page.TimePageData;
  52 +import org.thingsboard.server.common.data.page.TimePageLink;
51 import org.thingsboard.server.dao.exception.IncorrectParameterException; 53 import org.thingsboard.server.dao.exception.IncorrectParameterException;
52 import org.thingsboard.server.dao.model.ModelConstants; 54 import org.thingsboard.server.dao.model.ModelConstants;
53 import org.thingsboard.server.queue.util.TbCoreComponent; 55 import org.thingsboard.server.queue.util.TbCoreComponent;
@@ -400,18 +402,20 @@ public class EntityViewController extends BaseController { @@ -400,18 +402,20 @@ public class EntityViewController extends BaseController {
400 } 402 }
401 403
402 @PreAuthorize("hasAuthority('TENANT_ADMIN')") 404 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
403 - @RequestMapping(value = "/edge/entityView/{entityViewId}", method = RequestMethod.DELETE) 405 + @RequestMapping(value = "/edge/{edgeId}/entityView/{entityViewId}", method = RequestMethod.DELETE)
404 @ResponseBody 406 @ResponseBody
405 - public EntityView unassignEntityViewFromEdge(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { 407 + public EntityView unassignEntityViewFromEdge(@PathVariable(EDGE_ID) String strEdgeId,
  408 + @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException {
  409 + checkParameter(EDGE_ID, strEdgeId);
406 checkParameter(ENTITY_VIEW_ID, strEntityViewId); 410 checkParameter(ENTITY_VIEW_ID, strEntityViewId);
407 try { 411 try {
  412 + EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
  413 + Edge edge = checkEdgeId(edgeId, Operation.READ);
  414 +
408 EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); 415 EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
409 EntityView entityView = checkEntityViewId(entityViewId, Operation.UNASSIGN_FROM_EDGE); 416 EntityView entityView = checkEntityViewId(entityViewId, Operation.UNASSIGN_FROM_EDGE);
410 - if (entityView.getEdgeId() == null || entityView.getEdgeId().getId().equals(ModelConstants.NULL_UUID)) {  
411 - throw new IncorrectParameterException("Entity View isn't assigned to any edge!");  
412 - }  
413 - Edge edge = checkEdgeId(entityView.getEdgeId(), Operation.READ);  
414 - EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromEdge(getTenantId(), entityViewId)); 417 +
  418 + EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromEdge(getTenantId(), entityViewId, edgeId));
415 logEntityAction(entityViewId, entityView, 419 logEntityAction(entityViewId, entityView,
416 entityView.getCustomerId(), 420 entityView.getCustomerId(),
417 ActionType.UNASSIGNED_FROM_EDGE, null, strEntityViewId, edge.getId().toString(), edge.getName()); 421 ActionType.UNASSIGNED_FROM_EDGE, null, strEntityViewId, edge.getId().toString(), edge.getName());
@@ -428,24 +432,20 @@ public class EntityViewController extends BaseController { @@ -428,24 +432,20 @@ public class EntityViewController extends BaseController {
428 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") 432 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
429 @RequestMapping(value = "/edge/{edgeId}/entityViews", params = {"limit"}, method = RequestMethod.GET) 433 @RequestMapping(value = "/edge/{edgeId}/entityViews", params = {"limit"}, method = RequestMethod.GET)
430 @ResponseBody 434 @ResponseBody
431 - public TextPageData<EntityView> getEdgeEntityViews(  
432 - @PathVariable("edgeId") String strEdgeId, 435 + public TimePageData<EntityView> getEdgeEntityViews(
  436 + @PathVariable(EDGE_ID) String strEdgeId,
433 @RequestParam int limit, 437 @RequestParam int limit,
434 - @RequestParam(required = false) String type,  
435 - @RequestParam(required = false) String textSearch,  
436 - @RequestParam(required = false) String idOffset,  
437 - @RequestParam(required = false) String textOffset) throws ThingsboardException {  
438 - checkParameter("edgeId", strEdgeId); 438 + @RequestParam(required = false) Long startTime,
  439 + @RequestParam(required = false) Long endTime,
  440 + @RequestParam(required = false, defaultValue = "false") boolean ascOrder,
  441 + @RequestParam(required = false) String offset) throws ThingsboardException {
  442 + checkParameter(EDGE_ID, strEdgeId);
439 try { 443 try {
440 TenantId tenantId = getCurrentUser().getTenantId(); 444 TenantId tenantId = getCurrentUser().getTenantId();
441 EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); 445 EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
442 checkEdgeId(edgeId, Operation.READ); 446 checkEdgeId(edgeId, Operation.READ);
443 - TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);  
444 - if (type != null && type.trim().length()>0) {  
445 - return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeIdAndType(tenantId, edgeId, type, pageLink));  
446 - } else {  
447 - return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edgeId, pageLink));  
448 - } 447 + TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
  448 + return checkNotNull(entityViewService.findEntityViewsByTenantIdAndEdgeId(tenantId, edgeId, pageLink).get());
449 } catch (Exception e) { 449 } catch (Exception e) {
450 throw handleException(e); 450 throw handleException(e);
451 } 451 }
@@ -554,7 +554,7 @@ public final class EdgeGrpcSession implements Closeable { @@ -554,7 +554,7 @@ public final class EdgeGrpcSession implements Closeable {
554 case ENTITY_DELETED_RPC_MESSAGE: 554 case ENTITY_DELETED_RPC_MESSAGE:
555 Device device = ctx.getDeviceService().findDeviceByTenantIdAndName(edge.getTenantId(), deviceName); 555 Device device = ctx.getDeviceService().findDeviceByTenantIdAndName(edge.getTenantId(), deviceName);
556 if (device != null) { 556 if (device != null) {
557 - ctx.getDeviceService().unassignDeviceFromEdge(edge.getTenantId(), device.getId()); 557 + ctx.getDeviceService().unassignDeviceFromEdge(edge.getTenantId(), device.getId(), edge.getId());
558 } 558 }
559 break; 559 break;
560 } 560 }
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.service.edge.rpc.init; 16 package org.thingsboard.server.service.edge.rpc.init;
17 17
  18 +import com.google.common.util.concurrent.Futures;
18 import io.grpc.stub.StreamObserver; 19 import io.grpc.stub.StreamObserver;
19 import lombok.extern.slf4j.Slf4j; 20 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.beans.factory.annotation.Autowired;
@@ -54,6 +55,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgCo @@ -54,6 +55,7 @@ import org.thingsboard.server.service.edge.rpc.constructor.EntityViewUpdateMsgCo
54 import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor; 55 import org.thingsboard.server.service.edge.rpc.constructor.RuleChainUpdateMsgConstructor;
55 56
56 import java.util.UUID; 57 import java.util.UUID;
  58 +import java.util.concurrent.Future;
57 59
58 @Service 60 @Service
59 @Slf4j 61 @Slf4j
@@ -100,10 +102,10 @@ public class DefaultInitEdgeService implements InitEdgeService { @@ -100,10 +102,10 @@ public class DefaultInitEdgeService implements InitEdgeService {
100 102
101 private void initDevices(Edge edge, StreamObserver<ResponseMsg> outputStream) { 103 private void initDevices(Edge edge, StreamObserver<ResponseMsg> outputStream) {
102 try { 104 try {
103 - TextPageLink pageLink = new TextPageLink(100);  
104 - TextPageData<Device> pageData; 105 + TimePageLink pageLink = new TimePageLink(100);
  106 + TimePageData<Device> pageData;
105 do { 107 do {
106 - pageData = deviceService.findDevicesByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink); 108 + pageData = deviceService.findDevicesByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink).get();
107 if (!pageData.getData().isEmpty()) { 109 if (!pageData.getData().isEmpty()) {
108 log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); 110 log.trace("[{}] [{}] device(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
109 for (Device device : pageData.getData()) { 111 for (Device device : pageData.getData()) {
@@ -130,10 +132,10 @@ public class DefaultInitEdgeService implements InitEdgeService { @@ -130,10 +132,10 @@ public class DefaultInitEdgeService implements InitEdgeService {
130 132
131 private void initAssets(Edge edge, StreamObserver<ResponseMsg> outputStream) { 133 private void initAssets(Edge edge, StreamObserver<ResponseMsg> outputStream) {
132 try { 134 try {
133 - TextPageLink pageLink = new TextPageLink(100);  
134 - TextPageData<Asset> pageData; 135 + TimePageLink pageLink = new TimePageLink(100);
  136 + TimePageData<Asset> pageData;
135 do { 137 do {
136 - pageData = assetService.findAssetsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink); 138 + pageData = assetService.findAssetsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink).get();
137 if (!pageData.getData().isEmpty()) { 139 if (!pageData.getData().isEmpty()) {
138 log.trace("[{}] [{}] asset(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); 140 log.trace("[{}] [{}] asset(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
139 for (Asset asset : pageData.getData()) { 141 for (Asset asset : pageData.getData()) {
@@ -160,10 +162,10 @@ public class DefaultInitEdgeService implements InitEdgeService { @@ -160,10 +162,10 @@ public class DefaultInitEdgeService implements InitEdgeService {
160 162
161 private void initEntityViews(Edge edge, StreamObserver<ResponseMsg> outputStream) { 163 private void initEntityViews(Edge edge, StreamObserver<ResponseMsg> outputStream) {
162 try { 164 try {
163 - TextPageLink pageLink = new TextPageLink(100);  
164 - TextPageData<EntityView> pageData; 165 + TimePageLink pageLink = new TimePageLink(100);
  166 + TimePageData<EntityView> pageData;
165 do { 167 do {
166 - pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink); 168 + pageData = entityViewService.findEntityViewsByTenantIdAndEdgeId(edge.getTenantId(), edge.getId(), pageLink).get();
167 if (!pageData.getData().isEmpty()) { 169 if (!pageData.getData().isEmpty()) {
168 log.trace("[{}] [{}] entity view(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size()); 170 log.trace("[{}] [{}] entity view(s) are going to be pushed to edge.", edge.getId(), pageData.getData().size());
169 for (EntityView entityView : pageData.getData()) { 171 for (EntityView entityView : pageData.getData()) {
@@ -312,18 +312,6 @@ public class CassandraDatabaseUpgradeService extends AbstractCassandraDatabaseUp @@ -312,18 +312,6 @@ public class CassandraDatabaseUpgradeService extends AbstractCassandraDatabaseUp
312 loadCql(schemaUpdateFile); 312 loadCql(schemaUpdateFile);
313 313
314 try { 314 try {
315 - cluster.getSession().execute("alter table asset add edge_id text");  
316 - Thread.sleep(2500);  
317 - } catch (InvalidQueryException e) {}  
318 - try {  
319 - cluster.getSession().execute("alter table device add edge_id text");  
320 - Thread.sleep(2500);  
321 - } catch (InvalidQueryException e) {}  
322 - try {  
323 - cluster.getSession().execute("alter table entity_view add edge_id text");  
324 - Thread.sleep(2500);  
325 - } catch (InvalidQueryException e) {}  
326 - try {  
327 cluster.getSession().execute("alter table rule_chain add type text"); 315 cluster.getSession().execute("alter table rule_chain add type text");
328 Thread.sleep(2500); 316 Thread.sleep(2500);
329 } catch (InvalidQueryException e) {} 317 } catch (InvalidQueryException e) {}
@@ -239,15 +239,6 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService @@ -239,15 +239,6 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService
239 schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.6.0", SCHEMA_UPDATE_SQL); 239 schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "2.6.0", SCHEMA_UPDATE_SQL);
240 loadSql(schemaUpdateFile, conn); 240 loadSql(schemaUpdateFile, conn);
241 try { 241 try {
242 - conn.createStatement().execute("ALTER TABLE asset ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script  
243 - } catch (Exception e) {}  
244 - try {  
245 - conn.createStatement().execute("ALTER TABLE device ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script  
246 - } catch (Exception e) {}  
247 - try {  
248 - conn.createStatement().execute("ALTER TABLE entity_view ADD edge_id varchar(31)"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script  
249 - } catch (Exception e) {}  
250 - try {  
251 conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'SYSTEM'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script 242 conn.createStatement().execute("ALTER TABLE rule_chain ADD type varchar(255) DEFAULT 'SYSTEM'"); //NOSONAR, ignoring because method used to execute thingsboard database upgrade script
252 } catch (Exception e) {} 243 } catch (Exception e) {}
253 log.info("Schema updated."); 244 log.info("Schema updated.");
@@ -25,6 +25,8 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -25,6 +25,8 @@ import org.thingsboard.server.common.data.id.EdgeId;
25 import org.thingsboard.server.common.data.id.TenantId; 25 import org.thingsboard.server.common.data.id.TenantId;
26 import org.thingsboard.server.common.data.page.TextPageData; 26 import org.thingsboard.server.common.data.page.TextPageData;
27 import org.thingsboard.server.common.data.page.TextPageLink; 27 import org.thingsboard.server.common.data.page.TextPageLink;
  28 +import org.thingsboard.server.common.data.page.TimePageData;
  29 +import org.thingsboard.server.common.data.page.TimePageLink;
28 30
29 import java.util.List; 31 import java.util.List;
30 import java.util.Optional; 32 import java.util.Optional;
@@ -67,9 +69,7 @@ public interface AssetService { @@ -67,9 +69,7 @@ public interface AssetService {
67 69
68 Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId); 70 Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId);
69 71
70 - Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId); 72 + Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId);
71 73
72 - TextPageData<Asset> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink);  
73 -  
74 - TextPageData<Asset> findAssetsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink); 74 + ListenableFuture<TimePageData<Asset>> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
75 } 75 }
@@ -25,11 +25,13 @@ import org.thingsboard.server.common.data.id.EdgeId; @@ -25,11 +25,13 @@ import org.thingsboard.server.common.data.id.EdgeId;
25 import org.thingsboard.server.common.data.id.TenantId; 25 import org.thingsboard.server.common.data.id.TenantId;
26 import org.thingsboard.server.common.data.page.TextPageData; 26 import org.thingsboard.server.common.data.page.TextPageData;
27 import org.thingsboard.server.common.data.page.TextPageLink; 27 import org.thingsboard.server.common.data.page.TextPageLink;
  28 +import org.thingsboard.server.common.data.page.TimePageData;
  29 +import org.thingsboard.server.common.data.page.TimePageLink;
28 30
29 import java.util.List; 31 import java.util.List;
30 32
31 public interface DeviceService { 33 public interface DeviceService {
32 - 34 +
33 Device findDeviceById(TenantId tenantId, DeviceId deviceId); 35 Device findDeviceById(TenantId tenantId, DeviceId deviceId);
34 36
35 ListenableFuture<Device> findDeviceByIdAsync(TenantId tenantId, DeviceId deviceId); 37 ListenableFuture<Device> findDeviceByIdAsync(TenantId tenantId, DeviceId deviceId);
@@ -68,10 +70,7 @@ public interface DeviceService { @@ -68,10 +70,7 @@ public interface DeviceService {
68 70
69 Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId); 71 Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId);
70 72
71 - Device unassignDeviceFromEdge(TenantId tenantId, DeviceId deviceId);  
72 -  
73 - TextPageData<Device> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink);  
74 -  
75 - TextPageData<Device> findDevicesByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink); 73 + Device unassignDeviceFromEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId);
76 74
  75 + ListenableFuture<TimePageData<Device>> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
77 } 76 }
@@ -26,6 +26,8 @@ import org.thingsboard.server.common.data.id.EntityViewId; @@ -26,6 +26,8 @@ import org.thingsboard.server.common.data.id.EntityViewId;
26 import org.thingsboard.server.common.data.id.TenantId; 26 import org.thingsboard.server.common.data.id.TenantId;
27 import org.thingsboard.server.common.data.page.TextPageData; 27 import org.thingsboard.server.common.data.page.TextPageData;
28 import org.thingsboard.server.common.data.page.TextPageLink; 28 import org.thingsboard.server.common.data.page.TextPageLink;
  29 +import org.thingsboard.server.common.data.page.TimePageData;
  30 +import org.thingsboard.server.common.data.page.TimePageLink;
29 31
30 import java.util.List; 32 import java.util.List;
31 33
@@ -68,11 +70,7 @@ public interface EntityViewService { @@ -68,11 +70,7 @@ public interface EntityViewService {
68 70
69 EntityView assignEntityViewToEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId); 71 EntityView assignEntityViewToEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId);
70 72
71 - EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId);  
72 -  
73 - TextPageData<EntityView> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink);  
74 -  
75 - TextPageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink);  
76 - 73 + EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId);
77 74
  75 + ListenableFuture<TimePageData<EntityView>> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink);
78 } 76 }
@@ -18,7 +18,6 @@ package org.thingsboard.server.common.data; @@ -18,7 +18,6 @@ package org.thingsboard.server.common.data;
18 import lombok.EqualsAndHashCode; 18 import lombok.EqualsAndHashCode;
19 import org.thingsboard.server.common.data.id.CustomerId; 19 import org.thingsboard.server.common.data.id.CustomerId;
20 import org.thingsboard.server.common.data.id.DeviceId; 20 import org.thingsboard.server.common.data.id.DeviceId;
21 -import org.thingsboard.server.common.data.id.EdgeId;  
22 import org.thingsboard.server.common.data.id.TenantId; 21 import org.thingsboard.server.common.data.id.TenantId;
23 22
24 @EqualsAndHashCode(callSuper = true) 23 @EqualsAndHashCode(callSuper = true)
@@ -28,7 +27,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -28,7 +27,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
28 27
29 private TenantId tenantId; 28 private TenantId tenantId;
30 private CustomerId customerId; 29 private CustomerId customerId;
31 - private EdgeId edgeId;  
32 private String name; 30 private String name;
33 private String type; 31 private String type;
34 private String label; 32 private String label;
@@ -48,7 +46,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -48,7 +46,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
48 this.name = device.getName(); 46 this.name = device.getName();
49 this.type = device.getType(); 47 this.type = device.getType();
50 this.label = device.getLabel(); 48 this.label = device.getLabel();
51 - this.edgeId = device.getEdgeId();  
52 } 49 }
53 50
54 public TenantId getTenantId() { 51 public TenantId getTenantId() {
@@ -67,14 +64,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -67,14 +64,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
67 this.customerId = customerId; 64 this.customerId = customerId;
68 } 65 }
69 66
70 - public EdgeId getEdgeId() {  
71 - return edgeId;  
72 - }  
73 -  
74 - public void setEdgeId(EdgeId edgeId) {  
75 - this.edgeId = edgeId;  
76 - }  
77 -  
78 @Override 67 @Override
79 public String getName() { 68 public String getName() {
80 return name; 69 return name;
@@ -112,8 +101,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen @@ -112,8 +101,6 @@ public class Device extends SearchTextBasedWithAdditionalInfo<DeviceId> implemen
112 builder.append(tenantId); 101 builder.append(tenantId);
113 builder.append(", customerId="); 102 builder.append(", customerId=");
114 builder.append(customerId); 103 builder.append(customerId);
115 - builder.append(", edgeId=");  
116 - builder.append(edgeId);  
117 builder.append(", name="); 104 builder.append(", name=");
118 builder.append(name); 105 builder.append(name);
119 builder.append(", type="); 106 builder.append(", type=");
@@ -19,7 +19,6 @@ import lombok.AllArgsConstructor; @@ -19,7 +19,6 @@ import lombok.AllArgsConstructor;
19 import lombok.Data; 19 import lombok.Data;
20 import lombok.EqualsAndHashCode; 20 import lombok.EqualsAndHashCode;
21 import org.thingsboard.server.common.data.id.CustomerId; 21 import org.thingsboard.server.common.data.id.CustomerId;
22 -import org.thingsboard.server.common.data.id.EdgeId;  
23 import org.thingsboard.server.common.data.id.EntityId; 22 import org.thingsboard.server.common.data.id.EntityId;
24 import org.thingsboard.server.common.data.id.EntityViewId; 23 import org.thingsboard.server.common.data.id.EntityViewId;
25 import org.thingsboard.server.common.data.id.TenantId; 24 import org.thingsboard.server.common.data.id.TenantId;
@@ -40,7 +39,6 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo<EntityViewId> @@ -40,7 +39,6 @@ public class EntityView extends SearchTextBasedWithAdditionalInfo<EntityViewId>
40 private EntityId entityId; 39 private EntityId entityId;
41 private TenantId tenantId; 40 private TenantId tenantId;
42 private CustomerId customerId; 41 private CustomerId customerId;
43 - private EdgeId edgeId;  
44 private String name; 42 private String name;
45 private String type; 43 private String type;
46 private TelemetryEntityView keys; 44 private TelemetryEntityView keys;
@@ -15,13 +15,10 @@ @@ -15,13 +15,10 @@
15 */ 15 */
16 package org.thingsboard.server.common.data.asset; 16 package org.thingsboard.server.common.data.asset;
17 17
18 -import com.fasterxml.jackson.databind.JsonNode;  
19 import lombok.EqualsAndHashCode; 18 import lombok.EqualsAndHashCode;
20 import org.thingsboard.server.common.data.*; 19 import org.thingsboard.server.common.data.*;
21 import org.thingsboard.server.common.data.id.AssetId; 20 import org.thingsboard.server.common.data.id.AssetId;
22 import org.thingsboard.server.common.data.id.CustomerId; 21 import org.thingsboard.server.common.data.id.CustomerId;
23 -import org.thingsboard.server.common.data.id.EdgeId;  
24 -import org.thingsboard.server.common.data.id.EdgeId;  
25 import org.thingsboard.server.common.data.id.TenantId; 22 import org.thingsboard.server.common.data.id.TenantId;
26 23
27 @EqualsAndHashCode(callSuper = true) 24 @EqualsAndHashCode(callSuper = true)
@@ -34,7 +31,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -34,7 +31,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
34 private String name; 31 private String name;
35 private String type; 32 private String type;
36 private String label; 33 private String label;
37 - private EdgeId edgeId;  
38 34
39 public Asset() { 35 public Asset() {
40 super(); 36 super();
@@ -51,7 +47,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -51,7 +47,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
51 this.name = asset.getName(); 47 this.name = asset.getName();
52 this.type = asset.getType(); 48 this.type = asset.getType();
53 this.label = asset.getLabel(); 49 this.label = asset.getLabel();
54 - this.edgeId = asset.getEdgeId();  
55 } 50 }
56 51
57 public TenantId getTenantId() { 52 public TenantId getTenantId() {
@@ -70,14 +65,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -70,14 +65,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
70 this.customerId = customerId; 65 this.customerId = customerId;
71 } 66 }
72 67
73 - public EdgeId getEdgeId() {  
74 - return edgeId;  
75 - }  
76 -  
77 - public void setEdgeId(EdgeId edgeId) {  
78 - this.edgeId = edgeId;  
79 - }  
80 -  
81 @Override 68 @Override
82 public String getName() { 69 public String getName() {
83 return name; 70 return name;
@@ -115,8 +102,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements @@ -115,8 +102,6 @@ public class Asset extends SearchTextBasedWithAdditionalInfo<AssetId> implements
115 builder.append(tenantId); 102 builder.append(tenantId);
116 builder.append(", customerId="); 103 builder.append(", customerId=");
117 builder.append(customerId); 104 builder.append(customerId);
118 - builder.append(", edgeId=");  
119 - builder.append(edgeId);  
120 builder.append(", name="); 105 builder.append(", name=");
121 builder.append(name); 106 builder.append(name);
122 builder.append(", type="); 107 builder.append(", type=");
@@ -341,16 +341,6 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -341,16 +341,6 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
341 } 341 }
342 } 342 }
343 343
344 - private void deleteRelation(TenantId tenantId, EntityRelation alarmRelation) {  
345 - log.debug("Deleting Alarm relation: {}", alarmRelation);  
346 - relationService.deleteRelation(tenantId, alarmRelation);  
347 - }  
348 -  
349 - private void createRelation(TenantId tenantId, EntityRelation alarmRelation) {  
350 - log.debug("Creating Alarm relation: {}", alarmRelation);  
351 - relationService.saveRelation(tenantId, alarmRelation);  
352 - }  
353 -  
354 private Alarm merge(Alarm existing, Alarm alarm) { 344 private Alarm merge(Alarm existing, Alarm alarm) {
355 if (alarm.getStartTs() > existing.getEndTs()) { 345 if (alarm.getStartTs() > existing.getEndTs()) {
356 existing.setEndTs(alarm.getStartTs()); 346 existing.setEndTs(alarm.getStartTs());
@@ -395,7 +385,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -395,7 +385,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
395 } 385 }
396 } 386 }
397 387
398 - private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status, boolean createAnyRelation) { 388 + private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status, boolean createAnyRelation) throws ExecutionException, InterruptedException {
399 if (createAnyRelation) { 389 if (createAnyRelation) {
400 createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + AlarmSearchStatus.ANY.name(), RelationTypeGroup.ALARM)); 390 createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + AlarmSearchStatus.ANY.name(), RelationTypeGroup.ALARM));
401 } 391 }
@@ -404,13 +394,13 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -404,13 +394,13 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
404 createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM)); 394 createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM));
405 } 395 }
406 396
407 - private void deleteAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status) { 397 + private void deleteAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status) throws ExecutionException, InterruptedException {
408 deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.name(), RelationTypeGroup.ALARM)); 398 deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.name(), RelationTypeGroup.ALARM));
409 deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getClearSearchStatus().name(), RelationTypeGroup.ALARM)); 399 deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getClearSearchStatus().name(), RelationTypeGroup.ALARM));
410 deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM)); 400 deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM));
411 } 401 }
412 402
413 - private void updateAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus oldStatus, AlarmStatus newStatus) { 403 + private void updateAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus oldStatus, AlarmStatus newStatus) throws ExecutionException, InterruptedException {
414 deleteAlarmRelation(tenantId, entityId, alarmId, oldStatus); 404 deleteAlarmRelation(tenantId, entityId, alarmId, oldStatus);
415 createAlarmRelation(tenantId, entityId, alarmId, newStatus, false); 405 createAlarmRelation(tenantId, entityId, alarmId, newStatus, false);
416 } 406 }
@@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.EntitySubtype; @@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.EntitySubtype;
20 import org.thingsboard.server.common.data.asset.Asset; 20 import org.thingsboard.server.common.data.asset.Asset;
21 import org.thingsboard.server.common.data.id.TenantId; 21 import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.common.data.page.TextPageLink; 22 import org.thingsboard.server.common.data.page.TextPageLink;
  23 +import org.thingsboard.server.common.data.page.TimePageLink;
23 import org.thingsboard.server.dao.Dao; 24 import org.thingsboard.server.dao.Dao;
24 25
25 import java.util.List; 26 import java.util.List;
@@ -116,23 +117,12 @@ public interface AssetDao extends Dao<Asset> { @@ -116,23 +117,12 @@ public interface AssetDao extends Dao<Asset> {
116 ListenableFuture<List<EntitySubtype>> findTenantAssetTypesAsync(UUID tenantId); 117 ListenableFuture<List<EntitySubtype>> findTenantAssetTypesAsync(UUID tenantId);
117 118
118 /** 119 /**
119 - * Find assets by tenantId, customerId and page link. 120 + * Find assets by tenantId, edgeId and page link.
120 * 121 *
121 * @param tenantId the tenantId 122 * @param tenantId the tenantId
122 * @param edgeId the edgeId 123 * @param edgeId the edgeId
123 * @param pageLink the page link 124 * @param pageLink the page link
124 * @return the list of asset objects 125 * @return the list of asset objects
125 */ 126 */
126 - List<Asset> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink);  
127 -  
128 - /**  
129 - * Find assets by tenantId, customerId, type and page link.  
130 - *  
131 - * @param tenantId the tenantId  
132 - * @param edgeId the edgeId  
133 - * @param type the type  
134 - * @param pageLink the page link  
135 - * @return the list of asset objects  
136 - */  
137 - List<Asset> findAssetsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink); 127 + ListenableFuture<List<Asset>> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink);
138 } 128 }
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.asset; 16 package org.thingsboard.server.dao.asset;
17 17
18 18
  19 +import com.google.common.base.Function;
19 import com.google.common.util.concurrent.Futures; 20 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture; 21 import com.google.common.util.concurrent.ListenableFuture;
21 import com.google.common.util.concurrent.MoreExecutors; 22 import com.google.common.util.concurrent.MoreExecutors;
@@ -29,12 +30,14 @@ import org.springframework.cache.annotation.Cacheable; @@ -29,12 +30,14 @@ import org.springframework.cache.annotation.Cacheable;
29 import org.springframework.stereotype.Service; 30 import org.springframework.stereotype.Service;
30 import org.springframework.util.StringUtils; 31 import org.springframework.util.StringUtils;
31 import org.thingsboard.server.common.data.Customer; 32 import org.thingsboard.server.common.data.Customer;
  33 +import org.thingsboard.server.common.data.Device;
32 import org.thingsboard.server.common.data.EntitySubtype; 34 import org.thingsboard.server.common.data.EntitySubtype;
33 import org.thingsboard.server.common.data.EntityType; 35 import org.thingsboard.server.common.data.EntityType;
34 import org.thingsboard.server.common.data.EntityView; 36 import org.thingsboard.server.common.data.EntityView;
35 import org.thingsboard.server.common.data.Tenant; 37 import org.thingsboard.server.common.data.Tenant;
36 import org.thingsboard.server.common.data.asset.Asset; 38 import org.thingsboard.server.common.data.asset.Asset;
37 import org.thingsboard.server.common.data.asset.AssetSearchQuery; 39 import org.thingsboard.server.common.data.asset.AssetSearchQuery;
  40 +import org.thingsboard.server.common.data.edge.Edge;
38 import org.thingsboard.server.common.data.id.AssetId; 41 import org.thingsboard.server.common.data.id.AssetId;
39 import org.thingsboard.server.common.data.id.CustomerId; 42 import org.thingsboard.server.common.data.id.CustomerId;
40 import org.thingsboard.server.common.data.id.EdgeId; 43 import org.thingsboard.server.common.data.id.EdgeId;
@@ -42,9 +45,13 @@ import org.thingsboard.server.common.data.id.EntityId; @@ -42,9 +45,13 @@ import org.thingsboard.server.common.data.id.EntityId;
42 import org.thingsboard.server.common.data.id.TenantId; 45 import org.thingsboard.server.common.data.id.TenantId;
43 import org.thingsboard.server.common.data.page.TextPageData; 46 import org.thingsboard.server.common.data.page.TextPageData;
44 import org.thingsboard.server.common.data.page.TextPageLink; 47 import org.thingsboard.server.common.data.page.TextPageLink;
  48 +import org.thingsboard.server.common.data.page.TimePageData;
  49 +import org.thingsboard.server.common.data.page.TimePageLink;
45 import org.thingsboard.server.common.data.relation.EntityRelation; 50 import org.thingsboard.server.common.data.relation.EntityRelation;
46 import org.thingsboard.server.common.data.relation.EntitySearchDirection; 51 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
  52 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
47 import org.thingsboard.server.dao.customer.CustomerDao; 53 import org.thingsboard.server.dao.customer.CustomerDao;
  54 +import org.thingsboard.server.dao.edge.EdgeService;
48 import org.thingsboard.server.dao.entity.AbstractEntityService; 55 import org.thingsboard.server.dao.entity.AbstractEntityService;
49 import org.thingsboard.server.dao.entityview.EntityViewService; 56 import org.thingsboard.server.dao.entityview.EntityViewService;
50 import org.thingsboard.server.dao.exception.DataValidationException; 57 import org.thingsboard.server.dao.exception.DataValidationException;
@@ -52,6 +59,7 @@ import org.thingsboard.server.dao.service.DataValidator; @@ -52,6 +59,7 @@ import org.thingsboard.server.dao.service.DataValidator;
52 import org.thingsboard.server.dao.service.PaginatedRemover; 59 import org.thingsboard.server.dao.service.PaginatedRemover;
53 import org.thingsboard.server.dao.tenant.TenantDao; 60 import org.thingsboard.server.dao.tenant.TenantDao;
54 61
  62 +import javax.annotation.Nullable;
55 import java.util.ArrayList; 63 import java.util.ArrayList;
56 import java.util.Collections; 64 import java.util.Collections;
57 import java.util.Comparator; 65 import java.util.Comparator;
@@ -90,6 +98,9 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -90,6 +98,9 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
90 private EntityViewService entityViewService; 98 private EntityViewService entityViewService;
91 99
92 @Autowired 100 @Autowired
  101 + private EdgeService edgeService;
  102 +
  103 + @Autowired
93 private CacheManager cacheManager; 104 private CacheManager cacheManager;
94 105
95 @Override 106 @Override
@@ -285,36 +296,52 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -285,36 +296,52 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
285 @Override 296 @Override
286 public Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId) { 297 public Asset assignAssetToEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId) {
287 Asset asset = findAssetById(tenantId, assetId); 298 Asset asset = findAssetById(tenantId, assetId);
288 - asset.setEdgeId(edgeId);  
289 - return saveAsset(asset); 299 + Edge edge = edgeService.findEdgeById(tenantId, edgeId);
  300 + if (edge == null) {
  301 + throw new DataValidationException("Can't assign asset to non-existent edge!");
  302 + }
  303 + if (!edge.getTenantId().getId().equals(asset.getTenantId().getId())) {
  304 + throw new DataValidationException("Can't assign asset to edge from different tenant!");
  305 + }
  306 + try {
  307 + createRelation(tenantId, new EntityRelation(edgeId, assetId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
  308 + } catch (ExecutionException | InterruptedException e) {
  309 + log.warn("[{}] Failed to create asset relation. Edge Id: [{}]", assetId, edgeId);
  310 + throw new RuntimeException(e);
  311 + }
  312 + return asset;
290 } 313 }
291 314
292 @Override 315 @Override
293 - public Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId) { 316 + public Asset unassignAssetFromEdge(TenantId tenantId, AssetId assetId, EdgeId edgeId) {
294 Asset asset = findAssetById(tenantId, assetId); 317 Asset asset = findAssetById(tenantId, assetId);
295 - asset.setEdgeId(null);  
296 - return saveAsset(asset); 318 + Edge edge = edgeService.findEdgeById(tenantId, edgeId);
  319 + if (edge == null) {
  320 + throw new DataValidationException("Can't unassign asset from non-existent edge!");
  321 + }
  322 + try {
  323 + deleteRelation(tenantId, new EntityRelation(edgeId, assetId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
  324 + } catch (ExecutionException | InterruptedException e) {
  325 + log.warn("[{}] Failed to delete asset relation. Edge Id: [{}]", assetId, edgeId);
  326 + throw new RuntimeException(e);
  327 + }
  328 + return asset;
297 } 329 }
298 330
299 @Override 331 @Override
300 - public TextPageData<Asset> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink) { 332 + public ListenableFuture<TimePageData<Asset>> findAssetsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
301 log.trace("Executing findAssetsByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink); 333 log.trace("Executing findAssetsByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink);
302 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 334 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
303 validateId(edgeId, INCORRECT_EDGE_ID + edgeId); 335 validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
304 validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); 336 validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
305 - List<Asset> assets = assetDao.findAssetsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);  
306 - return new TextPageData<>(assets, pageLink);  
307 - }  
308 -  
309 - @Override  
310 - public TextPageData<Asset> findAssetsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink) {  
311 - log.trace("Executing findAssetsByTenantIdAndEdgeIdAndType, tenantId [{}], edgeId [{}], type [{}], pageLink [{}]", tenantId, edgeId, type, pageLink);  
312 - validateId(tenantId, INCORRECT_TENANT_ID + tenantId);  
313 - validateId(edgeId, INCORRECT_EDGE_ID + edgeId);  
314 - validateString(type, "Incorrect type " + type);  
315 - validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);  
316 - List<Asset> assets = assetDao.findAssetsByTenantIdAndEdgeIdAndType(tenantId.getId(), edgeId.getId(), type, pageLink);  
317 - return new TextPageData<>(assets, pageLink); 337 + ListenableFuture<List<Asset>> assets = assetDao.findAssetsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
  338 + return Futures.transform(assets, new Function<List<Asset>, TimePageData<Asset>>() {
  339 + @Nullable
  340 + @Override
  341 + public TimePageData<Asset> apply(@Nullable List<Asset> assets) {
  342 + return new TimePageData<>(assets, pageLink);
  343 + }
  344 + }, MoreExecutors.directExecutor());
318 } 345 }
319 346
320 private DataValidator<Asset> assetValidator = 347 private DataValidator<Asset> assetValidator =
@@ -25,16 +25,23 @@ import com.google.common.util.concurrent.Futures; @@ -25,16 +25,23 @@ import com.google.common.util.concurrent.Futures;
25 import com.google.common.util.concurrent.ListenableFuture; 25 import com.google.common.util.concurrent.ListenableFuture;
26 import com.google.common.util.concurrent.MoreExecutors; 26 import com.google.common.util.concurrent.MoreExecutors;
27 import lombok.extern.slf4j.Slf4j; 27 import lombok.extern.slf4j.Slf4j;
  28 +import org.springframework.beans.factory.annotation.Autowired;
28 import org.springframework.stereotype.Component; 29 import org.springframework.stereotype.Component;
  30 +import org.thingsboard.server.common.data.Device;
29 import org.thingsboard.server.common.data.EntitySubtype; 31 import org.thingsboard.server.common.data.EntitySubtype;
30 import org.thingsboard.server.common.data.EntityType; 32 import org.thingsboard.server.common.data.EntityType;
31 import org.thingsboard.server.common.data.asset.Asset; 33 import org.thingsboard.server.common.data.asset.Asset;
  34 +import org.thingsboard.server.common.data.id.EdgeId;
32 import org.thingsboard.server.common.data.id.TenantId; 35 import org.thingsboard.server.common.data.id.TenantId;
33 import org.thingsboard.server.common.data.page.TextPageLink; 36 import org.thingsboard.server.common.data.page.TextPageLink;
  37 +import org.thingsboard.server.common.data.page.TimePageLink;
  38 +import org.thingsboard.server.common.data.relation.EntityRelation;
  39 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
34 import org.thingsboard.server.dao.DaoUtil; 40 import org.thingsboard.server.dao.DaoUtil;
35 import org.thingsboard.server.dao.model.EntitySubtypeEntity; 41 import org.thingsboard.server.dao.model.EntitySubtypeEntity;
36 import org.thingsboard.server.dao.model.nosql.AssetEntity; 42 import org.thingsboard.server.dao.model.nosql.AssetEntity;
37 import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; 43 import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
  44 +import org.thingsboard.server.dao.relation.RelationDao;
38 import org.thingsboard.server.dao.util.NoSqlDao; 45 import org.thingsboard.server.dao.util.NoSqlDao;
39 46
40 import javax.annotation.Nullable; 47 import javax.annotation.Nullable;
@@ -68,6 +75,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; @@ -68,6 +75,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
68 @NoSqlDao 75 @NoSqlDao
69 public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao { 76 public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao {
70 77
  78 + @Autowired
  79 + private RelationDao relationDao;
  80 +
71 @Override 81 @Override
72 protected Class<AssetEntity> getColumnFamilyClass() { 82 protected Class<AssetEntity> getColumnFamilyClass() {
73 return AssetEntity.class; 83 return AssetEntity.class;
@@ -190,30 +200,16 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit @@ -190,30 +200,16 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
190 } 200 }
191 201
192 @Override 202 @Override
193 - public List<Asset> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {  
194 -// log.debug("Try to find assets by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink);  
195 -// List<AssetEntity> assetEntities = findPageWithTextSearch(new TenantId(tenantId), ASSET_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,  
196 -// Arrays.asList(eq(ASSET_CUSTOMER_ID_PROPERTY, customerId),  
197 -// eq(ASSET_TENANT_ID_PROPERTY, tenantId)),  
198 -// pageLink);  
199 -//  
200 -// log.trace("Found assets [{}] by tenantId [{}], customerId [{}] and pageLink [{}]", assetEntities, tenantId, customerId, pageLink);  
201 -// return DaoUtil.convertDataList(assetEntities);  
202 - throw new UnsupportedOperationException("Cassandra is not supported yet");  
203 - }  
204 -  
205 - @Override  
206 - public List<Asset> findAssetsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {  
207 -// log.debug("Try to find assets by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink);  
208 -// List<AssetEntity> assetEntities = findPageWithTextSearch(new TenantId(tenantId), ASSET_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,  
209 -// Arrays.asList(eq(ASSET_TYPE_PROPERTY, type),  
210 -// eq(ASSET_CUSTOMER_ID_PROPERTY, customerId),  
211 -// eq(ASSET_TENANT_ID_PROPERTY, tenantId)),  
212 -// pageLink);  
213 -//  
214 -// log.trace("Found assets [{}] by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", assetEntities, tenantId, customerId, type, pageLink);  
215 -// return DaoUtil.convertDataList(assetEntities);  
216 - throw new UnsupportedOperationException("Cassandra is not supported yet"); 203 + public ListenableFuture<List<Asset>> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
  204 + log.debug("Try to find assets by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
  205 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.ASSET, pageLink);
  206 + return Futures.transformAsync(relations, input -> {
  207 + List<ListenableFuture<Asset>> assetFutures = new ArrayList<>(input.size());
  208 + for (EntityRelation relation : input) {
  209 + assetFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
  210 + }
  211 + return Futures.successfulAsList(assetFutures);
  212 + }, MoreExecutors.directExecutor());
217 } 213 }
218 214
219 } 215 }
@@ -162,16 +162,6 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -162,16 +162,6 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
162 } 162 }
163 } 163 }
164 164
165 - private void deleteRelation(TenantId tenantId, EntityRelation dashboardRelation) throws ExecutionException, InterruptedException {  
166 - log.debug("Deleting Dashboard relation: {}", dashboardRelation);  
167 - relationService.deleteRelationAsync(tenantId, dashboardRelation).get();  
168 - }  
169 -  
170 - private void createRelation(TenantId tenantId, EntityRelation dashboardRelation) throws ExecutionException, InterruptedException {  
171 - log.debug("Creating Dashboard relation: {}", dashboardRelation);  
172 - relationService.saveRelationAsync(tenantId, dashboardRelation).get();  
173 - }  
174 -  
175 @Override 165 @Override
176 public void deleteDashboard(TenantId tenantId, DashboardId dashboardId) { 166 public void deleteDashboard(TenantId tenantId, DashboardId dashboardId) {
177 log.trace("Executing deleteDashboard [{}]", dashboardId); 167 log.trace("Executing deleteDashboard [{}]", dashboardId);
@@ -25,16 +25,22 @@ import com.google.common.util.concurrent.Futures; @@ -25,16 +25,22 @@ import com.google.common.util.concurrent.Futures;
25 import com.google.common.util.concurrent.ListenableFuture; 25 import com.google.common.util.concurrent.ListenableFuture;
26 import com.google.common.util.concurrent.MoreExecutors; 26 import com.google.common.util.concurrent.MoreExecutors;
27 import lombok.extern.slf4j.Slf4j; 27 import lombok.extern.slf4j.Slf4j;
  28 +import org.springframework.beans.factory.annotation.Autowired;
28 import org.springframework.stereotype.Component; 29 import org.springframework.stereotype.Component;
29 import org.thingsboard.server.common.data.Device; 30 import org.thingsboard.server.common.data.Device;
30 import org.thingsboard.server.common.data.EntitySubtype; 31 import org.thingsboard.server.common.data.EntitySubtype;
31 import org.thingsboard.server.common.data.EntityType; 32 import org.thingsboard.server.common.data.EntityType;
  33 +import org.thingsboard.server.common.data.id.EdgeId;
32 import org.thingsboard.server.common.data.id.TenantId; 34 import org.thingsboard.server.common.data.id.TenantId;
33 import org.thingsboard.server.common.data.page.TextPageLink; 35 import org.thingsboard.server.common.data.page.TextPageLink;
  36 +import org.thingsboard.server.common.data.page.TimePageLink;
  37 +import org.thingsboard.server.common.data.relation.EntityRelation;
  38 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
34 import org.thingsboard.server.dao.DaoUtil; 39 import org.thingsboard.server.dao.DaoUtil;
35 import org.thingsboard.server.dao.model.EntitySubtypeEntity; 40 import org.thingsboard.server.dao.model.EntitySubtypeEntity;
36 import org.thingsboard.server.dao.model.nosql.DeviceEntity; 41 import org.thingsboard.server.dao.model.nosql.DeviceEntity;
37 import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; 42 import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
  43 +import org.thingsboard.server.dao.relation.RelationDao;
38 import org.thingsboard.server.dao.util.NoSqlDao; 44 import org.thingsboard.server.dao.util.NoSqlDao;
39 45
40 import javax.annotation.Nullable; 46 import javax.annotation.Nullable;
@@ -68,6 +74,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; @@ -68,6 +74,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
68 @NoSqlDao 74 @NoSqlDao
69 public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao { 75 public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao {
70 76
  77 + @Autowired
  78 + private RelationDao relationDao;
  79 +
71 @Override 80 @Override
72 protected Class<DeviceEntity> getColumnFamilyClass() { 81 protected Class<DeviceEntity> getColumnFamilyClass() {
73 return DeviceEntity.class; 82 return DeviceEntity.class;
@@ -190,30 +199,17 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt @@ -190,30 +199,17 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
190 } 199 }
191 200
192 @Override 201 @Override
193 - public List<Device> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {  
194 -// log.debug("Try to find devices by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink);  
195 -// List<DeviceEntity> deviceEntities = findPageWithTextSearch(new TenantId(tenantId), DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,  
196 -// Arrays.asList(eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId),  
197 -// eq(DEVICE_TENANT_ID_PROPERTY, tenantId)),  
198 -// pageLink);  
199 -//  
200 -// log.trace("Found devices [{}] by tenantId [{}], customerId [{}] and pageLink [{}]", deviceEntities, tenantId, customerId, pageLink);  
201 -// return DaoUtil.convertDataList(deviceEntities);  
202 - throw new UnsupportedOperationException("Cassandra is not supported yet"); 202 + public ListenableFuture<List<Device>> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
  203 + log.debug("Try to find devices by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
  204 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.DEVICE, pageLink);
  205 + return Futures.transformAsync(relations, input -> {
  206 + List<ListenableFuture<Device>> deviceFutures = new ArrayList<>(input.size());
  207 + for (EntityRelation relation : input) {
  208 + deviceFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
  209 + }
  210 + return Futures.successfulAsList(deviceFutures);
  211 + }, MoreExecutors.directExecutor());
203 } 212 }
204 213
205 - @Override  
206 - public List<Device> findDevicesByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {  
207 -// log.debug("Try to find devices by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink);  
208 -// List<DeviceEntity> deviceEntities = findPageWithTextSearch(new TenantId(tenantId), DEVICE_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,  
209 -// Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type),  
210 -// eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId),  
211 -// eq(DEVICE_TENANT_ID_PROPERTY, tenantId)),  
212 -// pageLink);  
213 -//  
214 -// log.trace("Found devices [{}] by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", deviceEntities, tenantId, customerId, type, pageLink);  
215 -// return DaoUtil.convertDataList(deviceEntities);  
216 - throw new UnsupportedOperationException("Cassandra is not supported yet");  
217 - }  
218 214
219 } 215 }
@@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.Device; @@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.Device;
20 import org.thingsboard.server.common.data.EntitySubtype; 20 import org.thingsboard.server.common.data.EntitySubtype;
21 import org.thingsboard.server.common.data.id.TenantId; 21 import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.common.data.page.TextPageLink; 22 import org.thingsboard.server.common.data.page.TextPageLink;
  23 +import org.thingsboard.server.common.data.page.TimePageLink;
23 import org.thingsboard.server.dao.Dao; 24 import org.thingsboard.server.dao.Dao;
24 25
25 import java.util.List; 26 import java.util.List;
@@ -124,16 +125,5 @@ public interface DeviceDao extends Dao<Device> { @@ -124,16 +125,5 @@ public interface DeviceDao extends Dao<Device> {
124 * @param pageLink the page link 125 * @param pageLink the page link
125 * @return the list of device objects 126 * @return the list of device objects
126 */ 127 */
127 - List<Device> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink);  
128 -  
129 - /**  
130 - * Find devices by tenantId, edgeId, type and page link.  
131 - *  
132 - * @param tenantId the tenantId  
133 - * @param edgeId the edgeId  
134 - * @param type the type  
135 - * @param pageLink the page link  
136 - * @return the list of device objects  
137 - */  
138 - List<Device> findDevicesByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink); 128 + ListenableFuture<List<Device>> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink);
139 } 129 }
@@ -41,19 +41,26 @@ import org.thingsboard.server.common.data.id.CustomerId; @@ -41,19 +41,26 @@ import org.thingsboard.server.common.data.id.CustomerId;
41 import org.thingsboard.server.common.data.id.DeviceId; 41 import org.thingsboard.server.common.data.id.DeviceId;
42 import org.thingsboard.server.common.data.id.EdgeId; 42 import org.thingsboard.server.common.data.id.EdgeId;
43 import org.thingsboard.server.common.data.id.EntityId; 43 import org.thingsboard.server.common.data.id.EntityId;
  44 +import org.thingsboard.server.common.data.id.RuleChainId;
44 import org.thingsboard.server.common.data.id.TenantId; 45 import org.thingsboard.server.common.data.id.TenantId;
45 import org.thingsboard.server.common.data.page.TextPageData; 46 import org.thingsboard.server.common.data.page.TextPageData;
46 import org.thingsboard.server.common.data.page.TextPageLink; 47 import org.thingsboard.server.common.data.page.TextPageLink;
  48 +import org.thingsboard.server.common.data.page.TimePageData;
  49 +import org.thingsboard.server.common.data.page.TimePageLink;
47 import org.thingsboard.server.common.data.relation.EntityRelation; 50 import org.thingsboard.server.common.data.relation.EntityRelation;
48 import org.thingsboard.server.common.data.relation.EntitySearchDirection; 51 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
  52 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
  53 +import org.thingsboard.server.common.data.rule.RuleChain;
49 import org.thingsboard.server.common.data.security.DeviceCredentials; 54 import org.thingsboard.server.common.data.security.DeviceCredentials;
50 import org.thingsboard.server.common.data.security.DeviceCredentialsType; 55 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
51 import org.thingsboard.server.dao.customer.CustomerDao; 56 import org.thingsboard.server.dao.customer.CustomerDao;
  57 +import org.thingsboard.server.dao.edge.EdgeService;
52 import org.thingsboard.server.dao.entity.AbstractEntityService; 58 import org.thingsboard.server.dao.entity.AbstractEntityService;
53 import org.thingsboard.server.dao.entityview.EntityViewService; 59 import org.thingsboard.server.dao.entityview.EntityViewService;
54 import org.thingsboard.server.dao.exception.DataValidationException; 60 import org.thingsboard.server.dao.exception.DataValidationException;
55 import org.thingsboard.server.dao.service.DataValidator; 61 import org.thingsboard.server.dao.service.DataValidator;
56 import org.thingsboard.server.dao.service.PaginatedRemover; 62 import org.thingsboard.server.dao.service.PaginatedRemover;
  63 +import org.thingsboard.server.dao.service.Validator;
57 import org.thingsboard.server.dao.tenant.TenantDao; 64 import org.thingsboard.server.dao.tenant.TenantDao;
58 65
59 import javax.annotation.Nullable; 66 import javax.annotation.Nullable;
@@ -99,6 +106,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -99,6 +106,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
99 private EntityViewService entityViewService; 106 private EntityViewService entityViewService;
100 107
101 @Autowired 108 @Autowired
  109 + private EdgeService edgeService;
  110 +
  111 + @Autowired
102 private CacheManager cacheManager; 112 private CacheManager cacheManager;
103 113
104 @Override 114 @Override
@@ -324,36 +334,52 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -324,36 +334,52 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
324 @Override 334 @Override
325 public Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId) { 335 public Device assignDeviceToEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId) {
326 Device device = findDeviceById(tenantId, deviceId); 336 Device device = findDeviceById(tenantId, deviceId);
327 - device.setEdgeId(edgeId);  
328 - return saveDevice(device); 337 + Edge edge = edgeService.findEdgeById(tenantId, edgeId);
  338 + if (edge == null) {
  339 + throw new DataValidationException("Can't assign device to non-existent edge!");
  340 + }
  341 + if (!edge.getTenantId().getId().equals(device.getTenantId().getId())) {
  342 + throw new DataValidationException("Can't assign device to edge from different tenant!");
  343 + }
  344 + try {
  345 + createRelation(tenantId, new EntityRelation(edgeId, deviceId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
  346 + } catch (ExecutionException | InterruptedException e) {
  347 + log.warn("[{}] Failed to create device relation. Edge Id: [{}]", deviceId, edgeId);
  348 + throw new RuntimeException(e);
  349 + }
  350 + return device;
329 } 351 }
330 352
331 @Override 353 @Override
332 - public Device unassignDeviceFromEdge(TenantId tenantId, DeviceId deviceId) { 354 + public Device unassignDeviceFromEdge(TenantId tenantId, DeviceId deviceId, EdgeId edgeId) {
333 Device device = findDeviceById(tenantId, deviceId); 355 Device device = findDeviceById(tenantId, deviceId);
334 - device.setEdgeId(null);  
335 - return saveDevice(device); 356 + Edge edge = edgeService.findEdgeById(tenantId, edgeId);
  357 + if (edge == null) {
  358 + throw new DataValidationException("Can't unassign device from non-existent edge!");
  359 + }
  360 + try {
  361 + deleteRelation(tenantId, new EntityRelation(edgeId, deviceId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
  362 + } catch (ExecutionException | InterruptedException e) {
  363 + log.warn("[{}] Failed to delete device relation. Edge Id: [{}]", deviceId, edgeId);
  364 + throw new RuntimeException(e);
  365 + }
  366 + return device;
336 } 367 }
337 368
338 @Override 369 @Override
339 - public TextPageData<Device> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TextPageLink pageLink) { 370 + public ListenableFuture<TimePageData<Device>> findDevicesByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) {
340 log.trace("Executing findDevicesByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink); 371 log.trace("Executing findDevicesByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink);
341 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 372 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
342 validateId(edgeId, INCORRECT_EDGE_ID + edgeId); 373 validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
343 validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); 374 validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
344 - List<Device> devices = deviceDao.findDevicesByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);  
345 - return new TextPageData<>(devices, pageLink);  
346 - }  
347 -  
348 - @Override  
349 - public TextPageData<Device> findDevicesByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink) {  
350 - log.trace("Executing findDevicesByTenantIdAndEdgeIdAndType, tenantId [{}], edgeId [{}], type [{}], pageLink [{}]", tenantId, edgeId, type, pageLink);  
351 - validateId(tenantId, INCORRECT_TENANT_ID + tenantId);  
352 - validateId(edgeId, INCORRECT_EDGE_ID + edgeId);  
353 - validateString(type, "Incorrect type " + type);  
354 - validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);  
355 - List<Device> devices = deviceDao.findDevicesByTenantIdAndEdgeIdAndType(tenantId.getId(), edgeId.getId(), type, pageLink);  
356 - return new TextPageData<>(devices, pageLink); 375 + ListenableFuture<List<Device>> devices = deviceDao.findDevicesByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
  376 + return Futures.transform(devices, new Function<List<Device>, TimePageData<Device>>() {
  377 + @Nullable
  378 + @Override
  379 + public TimePageData<Device> apply(@Nullable List<Device> devices) {
  380 + return new TimePageData<>(devices, pageLink);
  381 + }
  382 + }, MoreExecutors.directExecutor());
357 } 383 }
358 384
359 private DataValidator<Device> deviceValidator = 385 private DataValidator<Device> deviceValidator =
@@ -62,6 +62,7 @@ import org.thingsboard.server.common.data.page.TimePageData; @@ -62,6 +62,7 @@ import org.thingsboard.server.common.data.page.TimePageData;
62 import org.thingsboard.server.common.data.page.TimePageLink; 62 import org.thingsboard.server.common.data.page.TimePageLink;
63 import org.thingsboard.server.common.data.relation.EntityRelation; 63 import org.thingsboard.server.common.data.relation.EntityRelation;
64 import org.thingsboard.server.common.data.relation.EntitySearchDirection; 64 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
  65 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
65 import org.thingsboard.server.common.data.rule.RuleChain; 66 import org.thingsboard.server.common.data.rule.RuleChain;
66 import org.thingsboard.server.common.data.rule.RuleChainMetaData; 67 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
67 import org.thingsboard.server.common.data.rule.RuleChainType; 68 import org.thingsboard.server.common.data.rule.RuleChainType;
@@ -75,6 +76,7 @@ import org.thingsboard.server.dao.entity.AbstractEntityService; @@ -75,6 +76,7 @@ import org.thingsboard.server.dao.entity.AbstractEntityService;
75 import org.thingsboard.server.dao.entityview.EntityViewService; 76 import org.thingsboard.server.dao.entityview.EntityViewService;
76 import org.thingsboard.server.dao.event.EventService; 77 import org.thingsboard.server.dao.event.EventService;
77 import org.thingsboard.server.dao.exception.DataValidationException; 78 import org.thingsboard.server.dao.exception.DataValidationException;
  79 +import org.thingsboard.server.dao.relation.RelationService;
78 import org.thingsboard.server.dao.rule.RuleChainService; 80 import org.thingsboard.server.dao.rule.RuleChainService;
79 import org.thingsboard.server.dao.service.DataValidator; 81 import org.thingsboard.server.dao.service.DataValidator;
80 import org.thingsboard.server.dao.service.PaginatedRemover; 82 import org.thingsboard.server.dao.service.PaginatedRemover;
@@ -144,6 +146,9 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @@ -144,6 +146,9 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
144 @Autowired 146 @Autowired
145 private EntityViewService entityViewService; 147 private EntityViewService entityViewService;
146 148
  149 + @Autowired
  150 + private RelationService relationService;
  151 +
147 private ExecutorService tsCallBackExecutor; 152 private ExecutorService tsCallBackExecutor;
148 153
149 @PostConstruct 154 @PostConstruct
@@ -219,7 +224,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @@ -219,7 +224,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
219 224
220 dashboardService.unassignEdgeDashboards(tenantId, edgeId); 225 dashboardService.unassignEdgeDashboards(tenantId, edgeId);
221 // TODO: validate that rule chains are removed by deleteEntityRelations(tenantId, edgeId); call 226 // TODO: validate that rule chains are removed by deleteEntityRelations(tenantId, edgeId); call
222 - ruleChainService.unassignEdgeRuleChains(tenantId, edgeId); 227 + ruleChainService.unassignEdgeRuleChains(tenantId, edgeId);
223 228
224 List<Object> list = new ArrayList<>(); 229 List<Object> list = new ArrayList<>();
225 list.add(edge.getTenantId()); 230 list.add(edge.getTenantId());
@@ -385,15 +390,18 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @@ -385,15 +390,18 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
385 } 390 }
386 391
387 private void processCustomTbMsg(TenantId tenantId, TbMsg tbMsg, FutureCallback<Void> callback) { 392 private void processCustomTbMsg(TenantId tenantId, TbMsg tbMsg, FutureCallback<Void> callback) {
388 - EdgeId edgeId = getEdgeIdByOriginatorId(tenantId, tbMsg.getOriginator());  
389 - EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(tbMsg.getOriginator().getEntityType());  
390 - if (edgeId != null && edgeQueueEntityType != null) {  
391 - try {  
392 - saveEventToEdgeQueue(tenantId, edgeId, edgeQueueEntityType, tbMsg.getType(), Base64.encodeBase64String(TbMsg.toByteArray(tbMsg)), callback);  
393 - } catch (IOException e) {  
394 - log.error("Error while saving custom tbMsg into Edge Queue", e); 393 + ListenableFuture<EdgeId> edgeIdFuture = getEdgeIdByOriginatorId(tenantId, tbMsg.getOriginator());
  394 + Futures.transform(edgeIdFuture, edgeId -> {
  395 + EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(tbMsg.getOriginator().getEntityType());
  396 + if (edgeId != null && edgeQueueEntityType != null) {
  397 + try {
  398 + saveEventToEdgeQueue(tenantId, edgeId, edgeQueueEntityType, tbMsg.getType(), Base64.encodeBase64String(TbMsg.toByteArray(tbMsg)), callback);
  399 + } catch (IOException e) {
  400 + log.error("Error while saving custom tbMsg into Edge Queue", e);
  401 + }
395 } 402 }
396 - } 403 + return null;
  404 + }, MoreExecutors.directExecutor());
397 } 405 }
398 406
399 private EdgeQueueEntityType getEdgeQueueTypeByEntityType(EntityType entityType) { 407 private EdgeQueueEntityType getEdgeQueueTypeByEntityType(EntityType entityType) {
@@ -410,23 +418,30 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @@ -410,23 +418,30 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
410 } 418 }
411 } 419 }
412 420
413 - private EdgeId getEdgeIdByOriginatorId(TenantId tenantId, EntityId originatorId) {  
414 - switch (originatorId.getEntityType()) {  
415 - case DEVICE:  
416 - Device device = deviceService.findDeviceById(tenantId, new DeviceId(originatorId.getId()));  
417 - return device.getEdgeId();  
418 - case ASSET:  
419 - Asset asset = assetService.findAssetById(tenantId, new AssetId(originatorId.getId()));  
420 - return asset.getEdgeId();  
421 - case ENTITY_VIEW:  
422 - EntityView entityView = entityViewService.findEntityViewById(tenantId, new EntityViewId(originatorId.getId()));  
423 - return entityView.getEdgeId();  
424 - default:  
425 - log.info("Unsupported entity type: [{}]", originatorId.getEntityType());  
426 - return null; 421 + private ListenableFuture<EdgeId> getEdgeIdByOriginatorId(TenantId tenantId, EntityId originatorId) {
  422 + List<EntityRelation> originatorEdgeRelations = relationService.findByToAndType(tenantId, originatorId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE);
  423 + if (originatorEdgeRelations != null && originatorEdgeRelations.size() > 0) {
  424 + return Futures.immediateFuture(new EdgeId(originatorEdgeRelations.get(0).getFrom().getId()));
  425 + } else {
  426 + return Futures.immediateFuture(null);
427 } 427 }
428 } 428 }
429 429
  430 + private void pushEventToEdge(TenantId tenantId, EntityId originatorId, EdgeQueueEntityType edgeQueueEntityType, TbMsg tbMsg, FutureCallback<Void> callback) {
  431 + ListenableFuture<EdgeId> edgeIdFuture = getEdgeIdByOriginatorId(tenantId, originatorId);
  432 + Futures.transform(edgeIdFuture, edgeId -> {
  433 + if (edgeId != null) {
  434 + try {
  435 + pushEventToEdge(tenantId, edgeId, edgeQueueEntityType, tbMsg, callback);
  436 + } catch (Exception e) {
  437 + log.error("Failed to push event to edge, edgeId [{}], tbMsg [{}]", edgeId, tbMsg, e);
  438 + }
  439 + }
  440 + return null;
  441 + },
  442 + MoreExecutors.directExecutor());
  443 + }
  444 +
430 private void processDevice(TenantId tenantId, TbMsg tbMsg, FutureCallback<Void> callback) throws IOException { 445 private void processDevice(TenantId tenantId, TbMsg tbMsg, FutureCallback<Void> callback) throws IOException {
431 switch (tbMsg.getType()) { 446 switch (tbMsg.getType()) {
432 case DataConstants.ENTITY_ASSIGNED_TO_EDGE: 447 case DataConstants.ENTITY_ASSIGNED_TO_EDGE:
@@ -437,9 +452,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @@ -437,9 +452,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
437 case DataConstants.ENTITY_CREATED: 452 case DataConstants.ENTITY_CREATED:
438 case DataConstants.ENTITY_UPDATED: 453 case DataConstants.ENTITY_UPDATED:
439 Device device = mapper.readValue(tbMsg.getData(), Device.class); 454 Device device = mapper.readValue(tbMsg.getData(), Device.class);
440 - if (device.getEdgeId() != null) {  
441 - pushEventToEdge(tenantId, device.getEdgeId(), EdgeQueueEntityType.DEVICE, tbMsg, callback);  
442 - } 455 + pushEventToEdge(tenantId, device.getId(), EdgeQueueEntityType.DEVICE, tbMsg, callback);
443 break; 456 break;
444 default: 457 default:
445 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); 458 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
@@ -471,9 +484,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @@ -471,9 +484,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
471 case DataConstants.ENTITY_CREATED: 484 case DataConstants.ENTITY_CREATED:
472 case DataConstants.ENTITY_UPDATED: 485 case DataConstants.ENTITY_UPDATED:
473 Asset asset = mapper.readValue(tbMsg.getData(), Asset.class); 486 Asset asset = mapper.readValue(tbMsg.getData(), Asset.class);
474 - if (asset.getEdgeId() != null) {  
475 - pushEventToEdge(tenantId, asset.getEdgeId(), EdgeQueueEntityType.ASSET, tbMsg, callback);  
476 - } 487 + pushEventToEdge(tenantId, asset.getId(), EdgeQueueEntityType.ASSET, tbMsg, callback);
477 break; 488 break;
478 default: 489 default:
479 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); 490 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
@@ -490,9 +501,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @@ -490,9 +501,7 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
490 case DataConstants.ENTITY_CREATED: 501 case DataConstants.ENTITY_CREATED:
491 case DataConstants.ENTITY_UPDATED: 502 case DataConstants.ENTITY_UPDATED:
492 EntityView entityView = mapper.readValue(tbMsg.getData(), EntityView.class); 503 EntityView entityView = mapper.readValue(tbMsg.getData(), EntityView.class);
493 - if (entityView.getEdgeId() != null) {  
494 - pushEventToEdge(tenantId, entityView.getEdgeId(), EdgeQueueEntityType.ENTITY_VIEW, tbMsg, callback);  
495 - } 504 + pushEventToEdge(tenantId, entityView.getId(), EdgeQueueEntityType.ENTITY_VIEW, tbMsg, callback);
496 break; 505 break;
497 default: 506 default:
498 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg); 507 log.warn("Unsupported msgType [{}], tbMsg [{}]", tbMsg.getType(), tbMsg);
@@ -507,10 +516,9 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic @@ -507,10 +516,9 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
507 case DataConstants.ALARM_ACK: 516 case DataConstants.ALARM_ACK:
508 case DataConstants.ALARM_CLEAR: 517 case DataConstants.ALARM_CLEAR:
509 Alarm alarm = mapper.readValue(tbMsg.getData(), Alarm.class); 518 Alarm alarm = mapper.readValue(tbMsg.getData(), Alarm.class);
510 - EdgeId edgeId = getEdgeIdByOriginatorId(tenantId, alarm.getOriginator());  
511 EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(alarm.getOriginator().getEntityType()); 519 EdgeQueueEntityType edgeQueueEntityType = getEdgeQueueTypeByEntityType(alarm.getOriginator().getEntityType());
512 - if (edgeId != null && edgeQueueEntityType != null) {  
513 - pushEventToEdge(tenantId, edgeId, EdgeQueueEntityType.ALARM, tbMsg, callback); 520 + if (edgeQueueEntityType != null) {
  521 + pushEventToEdge(tenantId, alarm.getOriginator(), EdgeQueueEntityType.ALARM, tbMsg, callback);
514 } 522 }
515 break; 523 break;
516 default: 524 default:
@@ -21,10 +21,12 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -21,10 +21,12 @@ import org.springframework.beans.factory.annotation.Autowired;
21 import org.springframework.beans.factory.annotation.Value; 21 import org.springframework.beans.factory.annotation.Value;
22 import org.thingsboard.server.common.data.id.EntityId; 22 import org.thingsboard.server.common.data.id.EntityId;
23 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
  24 +import org.thingsboard.server.common.data.relation.EntityRelation;
24 import org.thingsboard.server.dao.relation.RelationService; 25 import org.thingsboard.server.dao.relation.RelationService;
25 26
26 import javax.annotation.PostConstruct; 27 import javax.annotation.PostConstruct;
27 import java.util.Optional; 28 import java.util.Optional;
  29 +import java.util.concurrent.ExecutionException;
28 30
29 @Slf4j 31 @Slf4j
30 public abstract class AbstractEntityService { 32 public abstract class AbstractEntityService {
@@ -42,6 +44,16 @@ public abstract class AbstractEntityService { @@ -42,6 +44,16 @@ public abstract class AbstractEntityService {
42 sqlDatabaseUsed = "sql".equalsIgnoreCase(databaseType); 44 sqlDatabaseUsed = "sql".equalsIgnoreCase(databaseType);
43 } 45 }
44 46
  47 + protected void createRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {
  48 + log.debug("Creating relation: {}", relation);
  49 + relationService.saveRelation(tenantId, relation);
  50 + }
  51 +
  52 + protected void deleteRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {
  53 + log.debug("Deleting relation: {}", relation);
  54 + relationService.deleteRelation(tenantId, relation);
  55 + }
  56 +
45 protected void deleteEntityRelations(TenantId tenantId, EntityId entityId) { 57 protected void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
46 log.trace("Executing deleteEntityRelations [{}]", entityId); 58 log.trace("Executing deleteEntityRelations [{}]", entityId);
47 relationService.deleteEntityRelations(tenantId, entityId); 59 relationService.deleteEntityRelations(tenantId, entityId);
@@ -25,16 +25,23 @@ import com.google.common.util.concurrent.Futures; @@ -25,16 +25,23 @@ import com.google.common.util.concurrent.Futures;
25 import com.google.common.util.concurrent.ListenableFuture; 25 import com.google.common.util.concurrent.ListenableFuture;
26 import com.google.common.util.concurrent.MoreExecutors; 26 import com.google.common.util.concurrent.MoreExecutors;
27 import lombok.extern.slf4j.Slf4j; 27 import lombok.extern.slf4j.Slf4j;
  28 +import org.springframework.beans.factory.annotation.Autowired;
28 import org.springframework.stereotype.Component; 29 import org.springframework.stereotype.Component;
  30 +import org.thingsboard.server.common.data.Device;
29 import org.thingsboard.server.common.data.EntitySubtype; 31 import org.thingsboard.server.common.data.EntitySubtype;
30 import org.thingsboard.server.common.data.EntityType; 32 import org.thingsboard.server.common.data.EntityType;
31 import org.thingsboard.server.common.data.EntityView; 33 import org.thingsboard.server.common.data.EntityView;
  34 +import org.thingsboard.server.common.data.id.EdgeId;
32 import org.thingsboard.server.common.data.id.TenantId; 35 import org.thingsboard.server.common.data.id.TenantId;
33 import org.thingsboard.server.common.data.page.TextPageLink; 36 import org.thingsboard.server.common.data.page.TextPageLink;
  37 +import org.thingsboard.server.common.data.page.TimePageLink;
  38 +import org.thingsboard.server.common.data.relation.EntityRelation;
  39 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
34 import org.thingsboard.server.dao.DaoUtil; 40 import org.thingsboard.server.dao.DaoUtil;
35 import org.thingsboard.server.dao.model.EntitySubtypeEntity; 41 import org.thingsboard.server.dao.model.EntitySubtypeEntity;
36 import org.thingsboard.server.dao.model.nosql.EntityViewEntity; 42 import org.thingsboard.server.dao.model.nosql.EntityViewEntity;
37 import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao; 43 import org.thingsboard.server.dao.nosql.CassandraAbstractSearchTextDao;
  44 +import org.thingsboard.server.dao.relation.RelationDao;
38 import org.thingsboard.server.dao.util.NoSqlDao; 45 import org.thingsboard.server.dao.util.NoSqlDao;
39 46
40 import javax.annotation.Nullable; 47 import javax.annotation.Nullable;
@@ -73,6 +80,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.TENANT_ID_PROPERTY @@ -73,6 +80,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.TENANT_ID_PROPERTY
73 @NoSqlDao 80 @NoSqlDao
74 public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<EntityViewEntity, EntityView> implements EntityViewDao { 81 public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<EntityViewEntity, EntityView> implements EntityViewDao {
75 82
  83 + @Autowired
  84 + private RelationDao relationDao;
  85 +
76 @Override 86 @Override
77 protected Class<EntityViewEntity> getColumnFamilyClass() { 87 protected Class<EntityViewEntity> getColumnFamilyClass() {
78 return EntityViewEntity.class; 88 return EntityViewEntity.class;
@@ -186,30 +196,16 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit @@ -186,30 +196,16 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
186 } 196 }
187 197
188 @Override 198 @Override
189 - public List<EntityView> findEntityViewsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {  
190 -// log.debug("Try to find entity views by tenantId [{}], customerId[{}] and pageLink [{}]",  
191 -// tenantId, customerId, pageLink);  
192 -// List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(new TenantId(tenantId),  
193 -// ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_CF,  
194 -// Arrays.asList(eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)),  
195 -// pageLink);  
196 -// log.trace("Found find entity views [{}] by tenantId [{}], customerId [{}] and pageLink [{}]",  
197 -// entityViewEntities, tenantId, customerId, pageLink);  
198 -// return DaoUtil.convertDataList(entityViewEntities);  
199 - throw new UnsupportedOperationException("Cassandra is not supported yet"); 199 + public ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
  200 + log.debug("Try to find entity views by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
  201 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.ENTITY_VIEW, pageLink);
  202 + return Futures.transformAsync(relations, input -> {
  203 + List<ListenableFuture<EntityView>> entityViewFutures = new ArrayList<>(input.size());
  204 + for (EntityRelation relation : input) {
  205 + entityViewFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
  206 + }
  207 + return Futures.successfulAsList(entityViewFutures);
  208 + }, MoreExecutors.directExecutor());
200 } 209 }
201 210
202 - @Override  
203 - public List<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {  
204 -// log.debug("Try to find entity views by tenantId [{}], customerId[{}], type [{}] and pageLink [{}]",  
205 -// tenantId, customerId, type, pageLink);  
206 -// List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(new TenantId(tenantId),  
207 -// ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_TYPE_CF,  
208 -// Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type), eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)),  
209 -// pageLink);  
210 -// log.trace("Found find entity views [{}] by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]",  
211 -// entityViewEntities, tenantId, customerId, type, pageLink);  
212 -// return DaoUtil.convertDataList(entityViewEntities);  
213 - throw new UnsupportedOperationException("Cassandra is not supported yet");  
214 - }  
215 } 211 }
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at 6 * You may obtain a copy of the License at
7 * 7 *
8 - * http://www.apache.org/licenses/LICENSE-2.0 8 + * http://www.apache.org/licenses/LICENSE-2.0
9 * 9 *
10 * Unless required by applicable law or agreed to in writing, software 10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, 11 * distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.EntitySubtype; @@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.EntitySubtype;
20 import org.thingsboard.server.common.data.EntityView; 20 import org.thingsboard.server.common.data.EntityView;
21 import org.thingsboard.server.common.data.id.TenantId; 21 import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.common.data.page.TextPageLink; 22 import org.thingsboard.server.common.data.page.TextPageLink;
  23 +import org.thingsboard.server.common.data.page.TimePageLink;
23 import org.thingsboard.server.dao.Dao; 24 import org.thingsboard.server.dao.Dao;
24 25
25 import java.util.List; 26 import java.util.List;
@@ -110,22 +111,8 @@ public interface EntityViewDao extends Dao<EntityView> { @@ -110,22 +111,8 @@ public interface EntityViewDao extends Dao<EntityView> {
110 * @param pageLink the page link 111 * @param pageLink the page link
111 * @return the list of entity view objects 112 * @return the list of entity view objects
112 */ 113 */
113 - List<EntityView> findEntityViewsByTenantIdAndEdgeId(UUID tenantId,  
114 - UUID edgeId,  
115 - TextPageLink pageLink);  
116 -  
117 - /**  
118 - * Find entity views by tenantId, edgeId, type and page link.  
119 - *  
120 - * @param tenantId the tenantId  
121 - * @param edgeId the edgeId  
122 - * @param type the type  
123 - * @param pageLink the page link  
124 - * @return the list of entity view objects  
125 - */  
126 - List<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId,  
127 - UUID edgeId,  
128 - String type,  
129 - TextPageLink pageLink); 114 + ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEdgeId(UUID tenantId,
  115 + UUID edgeId,
  116 + TimePageLink pageLink);
130 117
131 } 118 }
@@ -30,10 +30,12 @@ import org.springframework.cache.annotation.Cacheable; @@ -30,10 +30,12 @@ import org.springframework.cache.annotation.Cacheable;
30 import org.springframework.cache.annotation.Caching; 30 import org.springframework.cache.annotation.Caching;
31 import org.springframework.stereotype.Service; 31 import org.springframework.stereotype.Service;
32 import org.thingsboard.server.common.data.Customer; 32 import org.thingsboard.server.common.data.Customer;
  33 +import org.thingsboard.server.common.data.Device;
33 import org.thingsboard.server.common.data.EntitySubtype; 34 import org.thingsboard.server.common.data.EntitySubtype;
34 import org.thingsboard.server.common.data.EntityType; 35 import org.thingsboard.server.common.data.EntityType;
35 import org.thingsboard.server.common.data.EntityView; 36 import org.thingsboard.server.common.data.EntityView;
36 import org.thingsboard.server.common.data.Tenant; 37 import org.thingsboard.server.common.data.Tenant;
  38 +import org.thingsboard.server.common.data.edge.Edge;
37 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; 39 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
38 import org.thingsboard.server.common.data.id.CustomerId; 40 import org.thingsboard.server.common.data.id.CustomerId;
39 import org.thingsboard.server.common.data.id.EdgeId; 41 import org.thingsboard.server.common.data.id.EdgeId;
@@ -42,9 +44,13 @@ import org.thingsboard.server.common.data.id.EntityViewId; @@ -42,9 +44,13 @@ import org.thingsboard.server.common.data.id.EntityViewId;
42 import org.thingsboard.server.common.data.id.TenantId; 44 import org.thingsboard.server.common.data.id.TenantId;
43 import org.thingsboard.server.common.data.page.TextPageData; 45 import org.thingsboard.server.common.data.page.TextPageData;
44 import org.thingsboard.server.common.data.page.TextPageLink; 46 import org.thingsboard.server.common.data.page.TextPageLink;
  47 +import org.thingsboard.server.common.data.page.TimePageData;
  48 +import org.thingsboard.server.common.data.page.TimePageLink;
45 import org.thingsboard.server.common.data.relation.EntityRelation; 49 import org.thingsboard.server.common.data.relation.EntityRelation;
46 import org.thingsboard.server.common.data.relation.EntitySearchDirection; 50 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
  51 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
47 import org.thingsboard.server.dao.customer.CustomerDao; 52 import org.thingsboard.server.dao.customer.CustomerDao;
  53 +import org.thingsboard.server.dao.edge.EdgeService;
48 import org.thingsboard.server.dao.entity.AbstractEntityService; 54 import org.thingsboard.server.dao.entity.AbstractEntityService;
49 import org.thingsboard.server.dao.exception.DataValidationException; 55 import org.thingsboard.server.dao.exception.DataValidationException;
50 import org.thingsboard.server.dao.service.DataValidator; 56 import org.thingsboard.server.dao.service.DataValidator;
@@ -58,6 +64,7 @@ import java.util.Collections; @@ -58,6 +64,7 @@ import java.util.Collections;
58 import java.util.Comparator; 64 import java.util.Comparator;
59 import java.util.List; 65 import java.util.List;
60 import java.util.Optional; 66 import java.util.Optional;
  67 +import java.util.concurrent.ExecutionException;
61 import java.util.stream.Collectors; 68 import java.util.stream.Collectors;
62 69
63 import static org.thingsboard.server.common.data.CacheConstants.ENTITY_VIEW_CACHE; 70 import static org.thingsboard.server.common.data.CacheConstants.ENTITY_VIEW_CACHE;
@@ -89,6 +96,9 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -89,6 +96,9 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
89 private CustomerDao customerDao; 96 private CustomerDao customerDao;
90 97
91 @Autowired 98 @Autowired
  99 + private EdgeService edgeService;
  100 +
  101 + @Autowired
92 private CacheManager cacheManager; 102 private CacheManager cacheManager;
93 103
94 @Caching(evict = { 104 @Caching(evict = {
@@ -285,47 +295,56 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -285,47 +295,56 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
285 }, MoreExecutors.directExecutor()); 295 }, MoreExecutors.directExecutor());
286 } 296 }
287 297
288 -  
289 - @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")  
290 @Override 298 @Override
291 public EntityView assignEntityViewToEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId) { 299 public EntityView assignEntityViewToEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId) {
292 EntityView entityView = findEntityViewById(tenantId, entityViewId); 300 EntityView entityView = findEntityViewById(tenantId, entityViewId);
293 - entityView.setEdgeId(edgeId);  
294 - return saveEntityView(entityView); 301 + Edge edge = edgeService.findEdgeById(tenantId, edgeId);
  302 + if (edge == null) {
  303 + throw new DataValidationException("Can't assign entityView to non-existent edge!");
  304 + }
  305 + if (!edge.getTenantId().getId().equals(entityView.getTenantId().getId())) {
  306 + throw new DataValidationException("Can't assign entityView to edge from different tenant!");
  307 + }
  308 + try {
  309 + createRelation(tenantId, new EntityRelation(edgeId, entityViewId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
  310 + } catch (ExecutionException | InterruptedException e) {
  311 + log.warn("[{}] Failed to create entityView relation. Edge Id: [{}]", entityViewId, edgeId);
  312 + throw new RuntimeException(e);
  313 + }
  314 + return entityView;
295 } 315 }
296 316
297 - @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")  
298 @Override 317 @Override
299 - public EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId) { 318 + public EntityView unassignEntityViewFromEdge(TenantId tenantId, EntityViewId entityViewId, EdgeId edgeId) {
300 EntityView entityView = findEntityViewById(tenantId, entityViewId); 319 EntityView entityView = findEntityViewById(tenantId, entityViewId);
301 - entityView.setEdgeId(null);  
302 - return saveEntityView(entityView);  
303 - }  
304 -  
305 - @Override  
306 - public TextPageData<EntityView> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId,  
307 - TextPageLink pageLink) {  
308 - log.trace("Executing findEntityViewsByTenantIdAndEdgeId, tenantId [{}], edgeId [{}]," +  
309 - " pageLink [{}]", tenantId, edgeId, pageLink);  
310 - validateId(tenantId, INCORRECT_TENANT_ID + tenantId);  
311 - validateId(edgeId, INCORRECT_EDGE_ID + edgeId);  
312 - validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);  
313 - List<EntityView> entityViews = entityViewDao.findEntityViewsByTenantIdAndEdgeId(tenantId.getId(),  
314 - edgeId.getId(), pageLink);  
315 - return new TextPageData<>(entityViews, pageLink); 320 + Edge edge = edgeService.findEdgeById(tenantId, edgeId);
  321 + if (edge == null) {
  322 + throw new DataValidationException("Can't unassign entityView from non-existent edge!");
  323 + }
  324 + try {
  325 + deleteRelation(tenantId, new EntityRelation(edgeId, entityViewId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE));
  326 + } catch (ExecutionException | InterruptedException e) {
  327 + log.warn("[{}] Failed to delete entityView relation. Edge Id: [{}]", entityViewId, edgeId);
  328 + throw new RuntimeException(e);
  329 + }
  330 + return entityView;
316 } 331 }
317 332
318 @Override 333 @Override
319 - public TextPageData<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(TenantId tenantId, EdgeId edgeId, String type, TextPageLink pageLink) {  
320 - log.trace("Executing findEntityViewsByTenantIdAndEdgeIdAndType, tenantId [{}], edgeId [{}]," +  
321 - " pageLink [{}], type [{}]", tenantId, edgeId, pageLink, type); 334 + public ListenableFuture<TimePageData<EntityView>> findEntityViewsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId,
  335 + TimePageLink pageLink) {
  336 + log.trace("Executing findEntityViewsByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink);
322 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 337 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
323 validateId(edgeId, INCORRECT_EDGE_ID + edgeId); 338 validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
324 validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); 339 validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink);
325 - validateString(type, "Incorrect type " + type);  
326 - List<EntityView> entityViews = entityViewDao.findEntityViewsByTenantIdAndEdgeIdAndType(tenantId.getId(),  
327 - edgeId.getId(), type, pageLink);  
328 - return new TextPageData<>(entityViews, pageLink); 340 + ListenableFuture<List<EntityView>> entityViews = entityViewDao.findEntityViewsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink);
  341 + return Futures.transform(entityViews, new Function<List<EntityView>, TimePageData<EntityView>>() {
  342 + @Nullable
  343 + @Override
  344 + public TimePageData<EntityView> apply(@Nullable List<EntityView> entityViews) {
  345 + return new TimePageData<>(entityViews, pageLink);
  346 + }
  347 + }, MoreExecutors.directExecutor());
329 } 348 }
330 349
331 private DataValidator<EntityView> entityViewValidator = 350 private DataValidator<EntityView> entityViewValidator =
@@ -142,7 +142,6 @@ public class ModelConstants { @@ -142,7 +142,6 @@ public class ModelConstants {
142 public static final String DEVICE_TYPE_PROPERTY = "type"; 142 public static final String DEVICE_TYPE_PROPERTY = "type";
143 public static final String DEVICE_LABEL_PROPERTY = "label"; 143 public static final String DEVICE_LABEL_PROPERTY = "label";
144 public static final String DEVICE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; 144 public static final String DEVICE_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
145 - public static final String DEVICE_EDGE_ID_PROPERTY = "edge_id";  
146 public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text"; 145 public static final String DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_and_search_text";
147 public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text"; 146 public static final String DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_tenant_by_type_and_search_text";
148 public static final String DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "device_by_customer_and_search_text"; 147 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 { @@ -158,7 +157,6 @@ public class ModelConstants {
158 public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; 157 public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
159 public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY; 158 public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
160 public static final String ENTITY_VIEW_NAME_PROPERTY = DEVICE_NAME_PROPERTY; 159 public static final String ENTITY_VIEW_NAME_PROPERTY = DEVICE_NAME_PROPERTY;
161 - public static final String ENTITY_VIEW_EDGE_ID_PROPERTY = "edge_id";  
162 public static final String ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_CF = "entity_view_by_tenant_and_customer"; 160 public static final String ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_CF = "entity_view_by_tenant_and_customer";
163 public static final String ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_TYPE_CF = "entity_view_by_tenant_and_customer_and_type"; 161 public static final String ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_TYPE_CF = "entity_view_by_tenant_and_customer_and_type";
164 public static final String ENTITY_VIEW_BY_TENANT_AND_ENTITY_ID_CF = "entity_view_by_tenant_and_entity_id"; 162 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 { @@ -206,7 +204,6 @@ public class ModelConstants {
206 public static final String ASSET_TYPE_PROPERTY = "type"; 204 public static final String ASSET_TYPE_PROPERTY = "type";
207 public static final String ASSET_LABEL_PROPERTY = "label"; 205 public static final String ASSET_LABEL_PROPERTY = "label";
208 public static final String ASSET_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY; 206 public static final String ASSET_ADDITIONAL_INFO_PROPERTY = ADDITIONAL_INFO_PROPERTY;
209 - public static final String ASSET_EDGE_ID_PROPERTY = "edge_id";  
210 207
211 public static final String ASSET_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "asset_by_tenant_and_search_text"; 208 public static final String ASSET_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "asset_by_tenant_and_search_text";
212 public static final String ASSET_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "asset_by_tenant_by_type_and_search_text"; 209 public static final String ASSET_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME = "asset_by_tenant_by_type_and_search_text";
@@ -25,7 +25,6 @@ import lombok.ToString; @@ -25,7 +25,6 @@ import lombok.ToString;
25 import org.thingsboard.server.common.data.asset.Asset; 25 import org.thingsboard.server.common.data.asset.Asset;
26 import org.thingsboard.server.common.data.id.AssetId; 26 import org.thingsboard.server.common.data.id.AssetId;
27 import org.thingsboard.server.common.data.id.CustomerId; 27 import org.thingsboard.server.common.data.id.CustomerId;
28 -import org.thingsboard.server.common.data.id.EdgeId;  
29 import org.thingsboard.server.common.data.id.TenantId; 28 import org.thingsboard.server.common.data.id.TenantId;
30 import org.thingsboard.server.dao.model.SearchTextEntity; 29 import org.thingsboard.server.dao.model.SearchTextEntity;
31 import org.thingsboard.server.dao.model.type.JsonCodec; 30 import org.thingsboard.server.dao.model.type.JsonCodec;
@@ -35,11 +34,10 @@ import java.util.UUID; @@ -35,11 +34,10 @@ import java.util.UUID;
35 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY; 34 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_ADDITIONAL_INFO_PROPERTY;
36 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_COLUMN_FAMILY_NAME; 35 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_COLUMN_FAMILY_NAME;
37 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_PROPERTY; 36 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_PROPERTY;
38 -import static org.thingsboard.server.dao.model.ModelConstants.ASSET_EDGE_ID_PROPERTY; 37 +import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;
39 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY; 38 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY;
40 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY; 39 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY;
41 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY; 40 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY;
42 -import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;  
43 import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY; 41 import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
44 import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; 42 import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
45 43
@@ -64,10 +62,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> { @@ -64,10 +62,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
64 @Column(name = ASSET_TYPE_PROPERTY) 62 @Column(name = ASSET_TYPE_PROPERTY)
65 private String type; 63 private String type;
66 64
67 - @PartitionKey(value = 4)  
68 - @Column(name = ASSET_EDGE_ID_PROPERTY)  
69 - private UUID edgeId;  
70 -  
71 @Column(name = ASSET_NAME_PROPERTY) 65 @Column(name = ASSET_NAME_PROPERTY)
72 private String name; 66 private String name;
73 67
@@ -94,9 +88,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> { @@ -94,9 +88,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
94 if (asset.getCustomerId() != null) { 88 if (asset.getCustomerId() != null) {
95 this.customerId = asset.getCustomerId().getId(); 89 this.customerId = asset.getCustomerId().getId();
96 } 90 }
97 - if (asset.getEdgeId() != null) {  
98 - this.edgeId = asset.getEdgeId().getId();  
99 - }  
100 this.name = asset.getName(); 91 this.name = asset.getName();
101 this.type = asset.getType(); 92 this.type = asset.getType();
102 this.label = asset.getLabel(); 93 this.label = asset.getLabel();
@@ -127,14 +118,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> { @@ -127,14 +118,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
127 this.customerId = customerId; 118 this.customerId = customerId;
128 } 119 }
129 120
130 - public UUID getEdgeId() {  
131 - return edgeId;  
132 - }  
133 -  
134 - public void setEdgeId(UUID edgeId) {  
135 - this.edgeId = edgeId;  
136 - }  
137 -  
138 public String getName() { 121 public String getName() {
139 return name; 122 return name;
140 } 123 }
@@ -183,9 +166,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> { @@ -183,9 +166,6 @@ public final class AssetEntity implements SearchTextEntity<Asset> {
183 if (customerId != null) { 166 if (customerId != null) {
184 asset.setCustomerId(new CustomerId(customerId)); 167 asset.setCustomerId(new CustomerId(customerId));
185 } 168 }
186 - if (edgeId != null) {  
187 - asset.setEdgeId(new EdgeId(edgeId));  
188 - }  
189 asset.setName(name); 169 asset.setName(name);
190 asset.setType(type); 170 asset.setType(type);
191 asset.setLabel(label); 171 asset.setLabel(label);
@@ -25,14 +25,21 @@ import lombok.ToString; @@ -25,14 +25,21 @@ import lombok.ToString;
25 import org.thingsboard.server.common.data.Device; 25 import org.thingsboard.server.common.data.Device;
26 import org.thingsboard.server.common.data.id.CustomerId; 26 import org.thingsboard.server.common.data.id.CustomerId;
27 import org.thingsboard.server.common.data.id.DeviceId; 27 import org.thingsboard.server.common.data.id.DeviceId;
28 -import org.thingsboard.server.common.data.id.EdgeId;  
29 import org.thingsboard.server.common.data.id.TenantId; 28 import org.thingsboard.server.common.data.id.TenantId;
30 import org.thingsboard.server.dao.model.SearchTextEntity; 29 import org.thingsboard.server.dao.model.SearchTextEntity;
31 import org.thingsboard.server.dao.model.type.JsonCodec; 30 import org.thingsboard.server.dao.model.type.JsonCodec;
32 31
33 import java.util.UUID; 32 import java.util.UUID;
34 33
35 -import static org.thingsboard.server.dao.model.ModelConstants.*; 34 +import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_ADDITIONAL_INFO_PROPERTY;
  35 +import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_COLUMN_FAMILY_NAME;
  36 +import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_CUSTOMER_ID_PROPERTY;
  37 +import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_LABEL_PROPERTY;
  38 +import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_NAME_PROPERTY;
  39 +import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TENANT_ID_PROPERTY;
  40 +import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TYPE_PROPERTY;
  41 +import static org.thingsboard.server.dao.model.ModelConstants.ID_PROPERTY;
  42 +import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
36 43
37 @Table(name = DEVICE_COLUMN_FAMILY_NAME) 44 @Table(name = DEVICE_COLUMN_FAMILY_NAME)
38 @EqualsAndHashCode 45 @EqualsAndHashCode
@@ -55,10 +62,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> { @@ -55,10 +62,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
55 @Column(name = DEVICE_TYPE_PROPERTY) 62 @Column(name = DEVICE_TYPE_PROPERTY)
56 private String type; 63 private String type;
57 64
58 - @PartitionKey(value = 4)  
59 - @Column(name = DEVICE_EDGE_ID_PROPERTY)  
60 - private UUID edgeId;  
61 -  
62 @Column(name = DEVICE_NAME_PROPERTY) 65 @Column(name = DEVICE_NAME_PROPERTY)
63 private String name; 66 private String name;
64 67
@@ -85,9 +88,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> { @@ -85,9 +88,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
85 if (device.getCustomerId() != null) { 88 if (device.getCustomerId() != null) {
86 this.customerId = device.getCustomerId().getId(); 89 this.customerId = device.getCustomerId().getId();
87 } 90 }
88 - if (device.getEdgeId() != null) {  
89 - this.edgeId = device.getEdgeId().getId();  
90 - }  
91 this.name = device.getName(); 91 this.name = device.getName();
92 this.type = device.getType(); 92 this.type = device.getType();
93 this.label = device.getLabel(); 93 this.label = device.getLabel();
@@ -118,14 +118,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> { @@ -118,14 +118,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
118 this.customerId = customerId; 118 this.customerId = customerId;
119 } 119 }
120 120
121 - public UUID getEdgeId() {  
122 - return edgeId;  
123 - }  
124 -  
125 - public void setEdgeId(UUID edgeId) {  
126 - this.edgeId = edgeId;  
127 - }  
128 -  
129 public String getName() { 121 public String getName() {
130 return name; 122 return name;
131 } 123 }
@@ -174,9 +166,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> { @@ -174,9 +166,6 @@ public final class DeviceEntity implements SearchTextEntity<Device> {
174 if (customerId != null) { 166 if (customerId != null) {
175 device.setCustomerId(new CustomerId(customerId)); 167 device.setCustomerId(new CustomerId(customerId));
176 } 168 }
177 - if (edgeId != null) {  
178 - device.setEdgeId(new EdgeId(edgeId));  
179 - }  
180 device.setName(name); 169 device.setName(name);
181 device.setType(type); 170 device.setType(type);
182 device.setLabel(label); 171 device.setLabel(label);
@@ -29,7 +29,6 @@ import org.hibernate.annotations.Type; @@ -29,7 +29,6 @@ import org.hibernate.annotations.Type;
29 import org.thingsboard.server.common.data.EntityType; 29 import org.thingsboard.server.common.data.EntityType;
30 import org.thingsboard.server.common.data.EntityView; 30 import org.thingsboard.server.common.data.EntityView;
31 import org.thingsboard.server.common.data.id.CustomerId; 31 import org.thingsboard.server.common.data.id.CustomerId;
32 -import org.thingsboard.server.common.data.id.EdgeId;  
33 import org.thingsboard.server.common.data.id.EntityIdFactory; 32 import org.thingsboard.server.common.data.id.EntityIdFactory;
34 import org.thingsboard.server.common.data.id.EntityViewId; 33 import org.thingsboard.server.common.data.id.EntityViewId;
35 import org.thingsboard.server.common.data.id.TenantId; 34 import org.thingsboard.server.common.data.id.TenantId;
@@ -42,7 +41,6 @@ import javax.persistence.Enumerated; @@ -42,7 +41,6 @@ import javax.persistence.Enumerated;
42 import java.io.IOException; 41 import java.io.IOException;
43 import java.util.UUID; 42 import java.util.UUID;
44 43
45 -import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_EDGE_ID_PROPERTY;  
46 import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TYPE_PROPERTY; 44 import static org.thingsboard.server.dao.model.ModelConstants.DEVICE_TYPE_PROPERTY;
47 import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_TYPE_PROPERTY; 45 import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_TYPE_PROPERTY;
48 import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_VIEW_TABLE_FAMILY_NAME; 46 import static org.thingsboard.server.dao.model.ModelConstants.ENTITY_VIEW_TABLE_FAMILY_NAME;
@@ -71,10 +69,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> { @@ -71,10 +69,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> {
71 @Column(name = DEVICE_TYPE_PROPERTY) 69 @Column(name = DEVICE_TYPE_PROPERTY)
72 private String type; 70 private String type;
73 71
74 - @PartitionKey(value = 4)  
75 - @Column(name = DEVICE_EDGE_ID_PROPERTY)  
76 - private UUID edgeId;  
77 -  
78 @Enumerated(EnumType.STRING) 72 @Enumerated(EnumType.STRING)
79 @Column(name = ENTITY_TYPE_PROPERTY) 73 @Column(name = ENTITY_TYPE_PROPERTY)
80 private EntityType entityType; 74 private EntityType entityType;
@@ -121,9 +115,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> { @@ -121,9 +115,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> {
121 if (entityView.getCustomerId() != null) { 115 if (entityView.getCustomerId() != null) {
122 this.customerId = entityView.getCustomerId().getId(); 116 this.customerId = entityView.getCustomerId().getId();
123 } 117 }
124 - if (entityView.getEdgeId() != null) {  
125 - this.edgeId = entityView.getEdgeId().getId();  
126 - }  
127 this.type = entityView.getType(); 118 this.type = entityView.getType();
128 this.name = entityView.getName(); 119 this.name = entityView.getName();
129 try { 120 try {
@@ -155,9 +146,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> { @@ -155,9 +146,6 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> {
155 if (customerId != null) { 146 if (customerId != null) {
156 entityView.setCustomerId(new CustomerId(customerId)); 147 entityView.setCustomerId(new CustomerId(customerId));
157 } 148 }
158 - if (edgeId != null) {  
159 - entityView.setEdgeId(new EdgeId(edgeId));  
160 - }  
161 entityView.setType(type); 149 entityView.setType(type);
162 entityView.setName(name); 150 entityView.setName(name);
163 try { 151 try {
@@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.UUIDConverter; @@ -25,7 +25,6 @@ import org.thingsboard.server.common.data.UUIDConverter;
25 import org.thingsboard.server.common.data.asset.Asset; 25 import org.thingsboard.server.common.data.asset.Asset;
26 import org.thingsboard.server.common.data.id.AssetId; 26 import org.thingsboard.server.common.data.id.AssetId;
27 import org.thingsboard.server.common.data.id.CustomerId; 27 import org.thingsboard.server.common.data.id.CustomerId;
28 -import org.thingsboard.server.common.data.id.EdgeId;  
29 import org.thingsboard.server.common.data.id.TenantId; 28 import org.thingsboard.server.common.data.id.TenantId;
30 import org.thingsboard.server.dao.model.BaseSqlEntity; 29 import org.thingsboard.server.dao.model.BaseSqlEntity;
31 import org.thingsboard.server.dao.model.ModelConstants; 30 import org.thingsboard.server.dao.model.ModelConstants;
@@ -38,11 +37,10 @@ import javax.persistence.Table; @@ -38,11 +37,10 @@ import javax.persistence.Table;
38 37
39 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_COLUMN_FAMILY_NAME; 38 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_COLUMN_FAMILY_NAME;
40 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_PROPERTY; 39 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_CUSTOMER_ID_PROPERTY;
41 -import static org.thingsboard.server.dao.model.ModelConstants.ASSET_EDGE_ID_PROPERTY; 40 +import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;
42 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY; 41 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_NAME_PROPERTY;
43 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY; 42 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TENANT_ID_PROPERTY;
44 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY; 43 import static org.thingsboard.server.dao.model.ModelConstants.ASSET_TYPE_PROPERTY;
45 -import static org.thingsboard.server.dao.model.ModelConstants.ASSET_LABEL_PROPERTY;  
46 import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY; 44 import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
47 45
48 @Data 46 @Data
@@ -58,9 +56,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex @@ -58,9 +56,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
58 @Column(name = ASSET_CUSTOMER_ID_PROPERTY) 56 @Column(name = ASSET_CUSTOMER_ID_PROPERTY)
59 private String customerId; 57 private String customerId;
60 58
61 - @Column(name = ASSET_EDGE_ID_PROPERTY)  
62 - private String edgeId;  
63 -  
64 @Column(name = ASSET_NAME_PROPERTY) 59 @Column(name = ASSET_NAME_PROPERTY)
65 private String name; 60 private String name;
66 61
@@ -91,9 +86,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex @@ -91,9 +86,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
91 if (asset.getCustomerId() != null) { 86 if (asset.getCustomerId() != null) {
92 this.customerId = UUIDConverter.fromTimeUUID(asset.getCustomerId().getId()); 87 this.customerId = UUIDConverter.fromTimeUUID(asset.getCustomerId().getId());
93 } 88 }
94 - if (asset.getEdgeId() != null) {  
95 - this.edgeId = UUIDConverter.fromTimeUUID(asset.getEdgeId().getId());  
96 - }  
97 this.name = asset.getName(); 89 this.name = asset.getName();
98 this.type = asset.getType(); 90 this.type = asset.getType();
99 this.label = asset.getLabel(); 91 this.label = asset.getLabel();
@@ -124,9 +116,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex @@ -124,9 +116,6 @@ public final class AssetEntity extends BaseSqlEntity<Asset> implements SearchTex
124 if (customerId != null) { 116 if (customerId != null) {
125 asset.setCustomerId(new CustomerId(UUIDConverter.fromString(customerId))); 117 asset.setCustomerId(new CustomerId(UUIDConverter.fromString(customerId)));
126 } 118 }
127 - if (edgeId != null) {  
128 - asset.setEdgeId(new EdgeId(UUIDConverter.fromString(edgeId)));  
129 - }  
130 asset.setName(name); 119 asset.setName(name);
131 asset.setType(type); 120 asset.setType(type);
132 asset.setLabel(label); 121 asset.setLabel(label);
@@ -24,7 +24,6 @@ import org.hibernate.annotations.TypeDef; @@ -24,7 +24,6 @@ import org.hibernate.annotations.TypeDef;
24 import org.thingsboard.server.common.data.Device; 24 import org.thingsboard.server.common.data.Device;
25 import org.thingsboard.server.common.data.id.CustomerId; 25 import org.thingsboard.server.common.data.id.CustomerId;
26 import org.thingsboard.server.common.data.id.DeviceId; 26 import org.thingsboard.server.common.data.id.DeviceId;
27 -import org.thingsboard.server.common.data.id.EdgeId;  
28 import org.thingsboard.server.common.data.id.TenantId; 27 import org.thingsboard.server.common.data.id.TenantId;
29 import org.thingsboard.server.dao.model.BaseSqlEntity; 28 import org.thingsboard.server.dao.model.BaseSqlEntity;
30 import org.thingsboard.server.dao.model.ModelConstants; 29 import org.thingsboard.server.dao.model.ModelConstants;
@@ -48,9 +47,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT @@ -48,9 +47,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT
48 @Column(name = ModelConstants.DEVICE_CUSTOMER_ID_PROPERTY) 47 @Column(name = ModelConstants.DEVICE_CUSTOMER_ID_PROPERTY)
49 private String customerId; 48 private String customerId;
50 49
51 - @Column(name = ModelConstants.DEVICE_EDGE_ID_PROPERTY)  
52 - private String edgeId;  
53 -  
54 @Column(name = ModelConstants.DEVICE_TYPE_PROPERTY) 50 @Column(name = ModelConstants.DEVICE_TYPE_PROPERTY)
55 private String type; 51 private String type;
56 52
@@ -81,9 +77,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT @@ -81,9 +77,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT
81 if (device.getCustomerId() != null) { 77 if (device.getCustomerId() != null) {
82 this.customerId = toString(device.getCustomerId().getId()); 78 this.customerId = toString(device.getCustomerId().getId());
83 } 79 }
84 - if (device.getEdgeId() != null) {  
85 - this.edgeId = toString(device.getEdgeId().getId());  
86 - }  
87 this.name = device.getName(); 80 this.name = device.getName();
88 this.type = device.getType(); 81 this.type = device.getType();
89 this.label = device.getLabel(); 82 this.label = device.getLabel();
@@ -110,9 +103,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT @@ -110,9 +103,6 @@ public final class DeviceEntity extends BaseSqlEntity<Device> implements SearchT
110 if (customerId != null) { 103 if (customerId != null) {
111 device.setCustomerId(new CustomerId(toUUID(customerId))); 104 device.setCustomerId(new CustomerId(toUUID(customerId)));
112 } 105 }
113 - if (edgeId != null) {  
114 - device.setEdgeId(new EdgeId(toUUID(edgeId)));  
115 - }  
116 device.setName(name); 106 device.setName(name);
117 device.setType(type); 107 device.setType(type);
118 device.setLabel(label); 108 device.setLabel(label);
@@ -26,7 +26,6 @@ import org.hibernate.annotations.TypeDef; @@ -26,7 +26,6 @@ import org.hibernate.annotations.TypeDef;
26 import org.thingsboard.server.common.data.EntityType; 26 import org.thingsboard.server.common.data.EntityType;
27 import org.thingsboard.server.common.data.EntityView; 27 import org.thingsboard.server.common.data.EntityView;
28 import org.thingsboard.server.common.data.id.CustomerId; 28 import org.thingsboard.server.common.data.id.CustomerId;
29 -import org.thingsboard.server.common.data.id.EdgeId;  
30 import org.thingsboard.server.common.data.id.EntityIdFactory; 29 import org.thingsboard.server.common.data.id.EntityIdFactory;
31 import org.thingsboard.server.common.data.id.EntityViewId; 30 import org.thingsboard.server.common.data.id.EntityViewId;
32 import org.thingsboard.server.common.data.id.TenantId; 31 import org.thingsboard.server.common.data.id.TenantId;
@@ -66,9 +65,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc @@ -66,9 +65,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc
66 @Column(name = ModelConstants.ENTITY_VIEW_CUSTOMER_ID_PROPERTY) 65 @Column(name = ModelConstants.ENTITY_VIEW_CUSTOMER_ID_PROPERTY)
67 private String customerId; 66 private String customerId;
68 67
69 - @Column(name = ModelConstants.ENTITY_VIEW_EDGE_ID_PROPERTY)  
70 - private String edgeId;  
71 -  
72 @Column(name = ModelConstants.DEVICE_TYPE_PROPERTY) 68 @Column(name = ModelConstants.DEVICE_TYPE_PROPERTY)
73 private String type; 69 private String type;
74 70
@@ -111,9 +107,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc @@ -111,9 +107,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc
111 if (entityView.getCustomerId() != null) { 107 if (entityView.getCustomerId() != null) {
112 this.customerId = toString(entityView.getCustomerId().getId()); 108 this.customerId = toString(entityView.getCustomerId().getId());
113 } 109 }
114 - if (entityView.getEdgeId() != null) {  
115 - this.edgeId = toString(entityView.getEdgeId().getId());  
116 - }  
117 this.type = entityView.getType(); 110 this.type = entityView.getType();
118 this.name = entityView.getName(); 111 this.name = entityView.getName();
119 try { 112 try {
@@ -151,9 +144,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc @@ -151,9 +144,6 @@ public class EntityViewEntity extends BaseSqlEntity<EntityView> implements Searc
151 if (customerId != null) { 144 if (customerId != null) {
152 entityView.setCustomerId(new CustomerId(toUUID(customerId))); 145 entityView.setCustomerId(new CustomerId(toUUID(customerId)));
153 } 146 }
154 - if (edgeId != null) {  
155 - entityView.setEdgeId(new EdgeId(toUUID(edgeId)));  
156 - }  
157 entityView.setType(type); 147 entityView.setType(type);
158 entityView.setName(name); 148 entityView.setName(name);
159 try { 149 try {
@@ -467,8 +467,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -467,8 +467,8 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
467 return Futures.transform(ruleChains, new Function<List<RuleChain>, TimePageData<RuleChain>>() { 467 return Futures.transform(ruleChains, new Function<List<RuleChain>, TimePageData<RuleChain>>() {
468 @Nullable 468 @Nullable
469 @Override 469 @Override
470 - public TimePageData<RuleChain> apply(@Nullable List<RuleChain> ruleChain) {  
471 - return new TimePageData<>(ruleChain, pageLink); 470 + public TimePageData<RuleChain> apply(@Nullable List<RuleChain> ruleChains) {
  471 + return new TimePageData<>(ruleChains, pageLink);
472 } 472 }
473 }, MoreExecutors.directExecutor()); 473 }, MoreExecutors.directExecutor());
474 } 474 }
@@ -557,15 +557,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -557,15 +557,6 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
557 ruleNodeDao.removeById(tenantId, entityId.getId()); 557 ruleNodeDao.removeById(tenantId, entityId.getId());
558 } 558 }
559 559
560 - private void createRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {  
561 - log.debug("Creating relation: {}", relation);  
562 - relationService.saveRelation(tenantId, relation);  
563 - }  
564 -  
565 - private void deleteRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {  
566 - log.debug("Deleting relation: {}", relation);  
567 - relationService.deleteRelation(tenantId, relation);  
568 - }  
569 560
570 private DataValidator<RuleChain> ruleChainValidator = 561 private DataValidator<RuleChain> ruleChainValidator =
571 new DataValidator<RuleChain>() { 562 new DataValidator<RuleChain>() {
@@ -96,7 +96,7 @@ public class CassandraRuleChainDao extends CassandraAbstractSearchTextDao<RuleCh @@ -96,7 +96,7 @@ public class CassandraRuleChainDao extends CassandraAbstractSearchTextDao<RuleCh
96 @Override 96 @Override
97 public ListenableFuture<List<RuleChain>> findRuleChainsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) { 97 public ListenableFuture<List<RuleChain>> findRuleChainsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
98 log.debug("Try to find rule chains by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink); 98 log.debug("Try to find rule chains by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
99 - ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.DASHBOARD, pageLink); 99 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.RULE_CHAIN, pageLink);
100 return Futures.transformAsync(relations, input -> { 100 return Futures.transformAsync(relations, input -> {
101 List<ListenableFuture<RuleChain>> ruleChainFutures = new ArrayList<>(input.size()); 101 List<ListenableFuture<RuleChain>> ruleChainFutures = new ArrayList<>(input.size());
102 for (EntityRelation relation : input) { 102 for (EntityRelation relation : input) {
@@ -77,26 +77,4 @@ public interface AssetRepository extends CrudRepository<AssetEntity, String> { @@ -77,26 +77,4 @@ public interface AssetRepository extends CrudRepository<AssetEntity, String> {
77 77
78 @Query("SELECT DISTINCT a.type FROM AssetEntity a WHERE a.tenantId = :tenantId") 78 @Query("SELECT DISTINCT a.type FROM AssetEntity a WHERE a.tenantId = :tenantId")
79 List<String> findTenantAssetTypes(@Param("tenantId") String tenantId); 79 List<String> findTenantAssetTypes(@Param("tenantId") String tenantId);
80 -  
81 - @Query("SELECT a FROM AssetEntity a WHERE a.tenantId = :tenantId " +  
82 - "AND a.edgeId = :edgeId " +  
83 - "AND LOWER(a.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +  
84 - "AND a.id > :idOffset ORDER BY a.id")  
85 - List<AssetEntity> findByTenantIdAndEdgeId(@Param("tenantId") String tenantId,  
86 - @Param("edgeId") String edgeId,  
87 - @Param("textSearch") String textSearch,  
88 - @Param("idOffset") String idOffset,  
89 - Pageable pageable);  
90 -  
91 - @Query("SELECT a FROM AssetEntity a WHERE a.tenantId = :tenantId " +  
92 - "AND a.edgeId = :edgeId AND a.type = :type " +  
93 - "AND LOWER(a.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +  
94 - "AND a.id > :idOffset ORDER BY a.id")  
95 - List<AssetEntity> findByTenantIdAndEdgeIdAndType(@Param("tenantId") String tenantId,  
96 - @Param("edgeId") String edgeId,  
97 - @Param("type") String type,  
98 - @Param("textSearch") String textSearch,  
99 - @Param("idOffset") String idOffset,  
100 - Pageable pageable);  
101 -  
102 } 80 }
@@ -15,19 +15,28 @@ @@ -15,19 +15,28 @@
15 */ 15 */
16 package org.thingsboard.server.dao.sql.asset; 16 package org.thingsboard.server.dao.sql.asset;
17 17
  18 +import com.google.common.util.concurrent.Futures;
18 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
  21 +import lombok.extern.slf4j.Slf4j;
19 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.data.domain.PageRequest; 23 import org.springframework.data.domain.PageRequest;
21 import org.springframework.data.repository.CrudRepository; 24 import org.springframework.data.repository.CrudRepository;
22 import org.springframework.stereotype.Component; 25 import org.springframework.stereotype.Component;
  26 +import org.thingsboard.server.common.data.Device;
23 import org.thingsboard.server.common.data.EntitySubtype; 27 import org.thingsboard.server.common.data.EntitySubtype;
24 import org.thingsboard.server.common.data.EntityType; 28 import org.thingsboard.server.common.data.EntityType;
25 import org.thingsboard.server.common.data.asset.Asset; 29 import org.thingsboard.server.common.data.asset.Asset;
  30 +import org.thingsboard.server.common.data.id.EdgeId;
26 import org.thingsboard.server.common.data.id.TenantId; 31 import org.thingsboard.server.common.data.id.TenantId;
27 import org.thingsboard.server.common.data.page.TextPageLink; 32 import org.thingsboard.server.common.data.page.TextPageLink;
  33 +import org.thingsboard.server.common.data.page.TimePageLink;
  34 +import org.thingsboard.server.common.data.relation.EntityRelation;
  35 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
28 import org.thingsboard.server.dao.DaoUtil; 36 import org.thingsboard.server.dao.DaoUtil;
29 import org.thingsboard.server.dao.asset.AssetDao; 37 import org.thingsboard.server.dao.asset.AssetDao;
30 import org.thingsboard.server.dao.model.sql.AssetEntity; 38 import org.thingsboard.server.dao.model.sql.AssetEntity;
  39 +import org.thingsboard.server.dao.relation.RelationDao;
31 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 40 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
32 import org.thingsboard.server.dao.util.SqlDao; 41 import org.thingsboard.server.dao.util.SqlDao;
33 42
@@ -47,11 +56,15 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR; @@ -47,11 +56,15 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;
47 */ 56 */
48 @Component 57 @Component
49 @SqlDao 58 @SqlDao
  59 +@Slf4j
50 public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao { 60 public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> implements AssetDao {
51 61
52 @Autowired 62 @Autowired
53 private AssetRepository assetRepository; 63 private AssetRepository assetRepository;
54 64
  65 + @Autowired
  66 + private RelationDao relationDao;
  67 +
55 @Override 68 @Override
56 protected Class<AssetEntity> getEntityClass() { 69 protected Class<AssetEntity> getEntityClass() {
57 return AssetEntity.class; 70 return AssetEntity.class;
@@ -141,27 +154,16 @@ public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> im @@ -141,27 +154,16 @@ public class JpaAssetDao extends JpaAbstractSearchTextDao<AssetEntity, Asset> im
141 } 154 }
142 155
143 @Override 156 @Override
144 - public List<Asset> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {  
145 - return DaoUtil.convertDataList(assetRepository  
146 - .findByTenantIdAndEdgeId(  
147 - fromTimeUUID(tenantId),  
148 - fromTimeUUID(edgeId),  
149 - Objects.toString(pageLink.getTextSearch(), ""),  
150 - pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),  
151 - PageRequest.of(0, pageLink.getLimit())));  
152 - }  
153 -  
154 -  
155 - @Override  
156 - public List<Asset> findAssetsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {  
157 - return DaoUtil.convertDataList(assetRepository  
158 - .findByTenantIdAndEdgeIdAndType(  
159 - fromTimeUUID(tenantId),  
160 - fromTimeUUID(edgeId),  
161 - type,  
162 - Objects.toString(pageLink.getTextSearch(), ""),  
163 - pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),  
164 - PageRequest.of(0, pageLink.getLimit()))); 157 + public ListenableFuture<List<Asset>> findAssetsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
  158 + log.debug("Try to find assets by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
  159 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.ASSET, pageLink);
  160 + return Futures.transformAsync(relations, input -> {
  161 + List<ListenableFuture<Asset>> assetFutures = new ArrayList<>(input.size());
  162 + for (EntityRelation relation : input) {
  163 + assetFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
  164 + }
  165 + return Futures.successfulAsList(assetFutures);
  166 + }, MoreExecutors.directExecutor());
165 } 167 }
166 168
167 } 169 }
@@ -85,26 +85,4 @@ public interface DeviceRepository extends CrudRepository<DeviceEntity, String> { @@ -85,26 +85,4 @@ public interface DeviceRepository extends CrudRepository<DeviceEntity, String> {
85 List<DeviceEntity> findDevicesByTenantIdAndCustomerIdAndIdIn(String tenantId, String customerId, List<String> deviceIds); 85 List<DeviceEntity> findDevicesByTenantIdAndCustomerIdAndIdIn(String tenantId, String customerId, List<String> deviceIds);
86 86
87 List<DeviceEntity> findDevicesByTenantIdAndIdIn(String tenantId, List<String> deviceIds); 87 List<DeviceEntity> findDevicesByTenantIdAndIdIn(String tenantId, List<String> deviceIds);
88 -  
89 - @Query("SELECT d FROM DeviceEntity d WHERE d.tenantId = :tenantId " +  
90 - "AND d.edgeId = :edgeId " +  
91 - "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " +  
92 - "AND d.id > :idOffset ORDER BY d.id")  
93 - List<DeviceEntity> findByTenantIdAndEdgeId(@Param("tenantId") String tenantId,  
94 - @Param("edgeId") String edgeId,  
95 - @Param("searchText") String searchText,  
96 - @Param("idOffset") String idOffset,  
97 - Pageable pageable);  
98 -  
99 - @Query("SELECT d FROM DeviceEntity d WHERE d.tenantId = :tenantId " +  
100 - "AND d.edgeId = :edgeId " +  
101 - "AND d.type = :type " +  
102 - "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%')) " +  
103 - "AND d.id > :idOffset ORDER BY d.id")  
104 - List<DeviceEntity> findByTenantIdAndEdgeIdAndType(@Param("tenantId") String tenantId,  
105 - @Param("edgeId") String edgeId,  
106 - @Param("type") String type,  
107 - @Param("textSearch") String textSearch,  
108 - @Param("idOffset") String idOffset,  
109 - Pageable pageable);  
110 } 88 }
@@ -15,7 +15,10 @@ @@ -15,7 +15,10 @@
15 */ 15 */
16 package org.thingsboard.server.dao.sql.device; 16 package org.thingsboard.server.dao.sql.device;
17 17
  18 +import com.google.common.util.concurrent.Futures;
18 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
  21 +import lombok.extern.slf4j.Slf4j;
19 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.data.domain.PageRequest; 23 import org.springframework.data.domain.PageRequest;
21 import org.springframework.data.repository.CrudRepository; 24 import org.springframework.data.repository.CrudRepository;
@@ -25,11 +28,17 @@ import org.thingsboard.server.common.data.Device; @@ -25,11 +28,17 @@ import org.thingsboard.server.common.data.Device;
25 import org.thingsboard.server.common.data.EntitySubtype; 28 import org.thingsboard.server.common.data.EntitySubtype;
26 import org.thingsboard.server.common.data.EntityType; 29 import org.thingsboard.server.common.data.EntityType;
27 import org.thingsboard.server.common.data.UUIDConverter; 30 import org.thingsboard.server.common.data.UUIDConverter;
  31 +import org.thingsboard.server.common.data.id.EdgeId;
28 import org.thingsboard.server.common.data.id.TenantId; 32 import org.thingsboard.server.common.data.id.TenantId;
29 import org.thingsboard.server.common.data.page.TextPageLink; 33 import org.thingsboard.server.common.data.page.TextPageLink;
  34 +import org.thingsboard.server.common.data.page.TimePageLink;
  35 +import org.thingsboard.server.common.data.relation.EntityRelation;
  36 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
  37 +import org.thingsboard.server.common.data.rule.RuleChain;
30 import org.thingsboard.server.dao.DaoUtil; 38 import org.thingsboard.server.dao.DaoUtil;
31 import org.thingsboard.server.dao.device.DeviceDao; 39 import org.thingsboard.server.dao.device.DeviceDao;
32 import org.thingsboard.server.dao.model.sql.DeviceEntity; 40 import org.thingsboard.server.dao.model.sql.DeviceEntity;
  41 +import org.thingsboard.server.dao.relation.RelationDao;
33 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 42 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
34 import org.thingsboard.server.dao.util.SqlDao; 43 import org.thingsboard.server.dao.util.SqlDao;
35 44
@@ -49,11 +58,15 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR; @@ -49,11 +58,15 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;
49 */ 58 */
50 @Component 59 @Component
51 @SqlDao 60 @SqlDao
  61 +@Slf4j
52 public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao { 62 public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> implements DeviceDao {
53 63
54 @Autowired 64 @Autowired
55 private DeviceRepository deviceRepository; 65 private DeviceRepository deviceRepository;
56 66
  67 + @Autowired
  68 + private RelationDao relationDao;
  69 +
57 @Override 70 @Override
58 protected Class<DeviceEntity> getEntityClass() { 71 protected Class<DeviceEntity> getEntityClass() {
59 return DeviceEntity.class; 72 return DeviceEntity.class;
@@ -149,28 +162,16 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device> @@ -149,28 +162,16 @@ public class JpaDeviceDao extends JpaAbstractSearchTextDao<DeviceEntity, Device>
149 return list; 162 return list;
150 } 163 }
151 164
152 -  
153 @Override 165 @Override
154 - public List<Device> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TextPageLink pageLink) {  
155 - return DaoUtil.convertDataList(  
156 - deviceRepository.findByTenantIdAndEdgeId(  
157 - fromTimeUUID(tenantId),  
158 - fromTimeUUID(edgeId),  
159 - Objects.toString(pageLink.getTextSearch(), ""),  
160 - pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),  
161 - PageRequest.of(0, pageLink.getLimit())));  
162 - }  
163 -  
164 - @Override  
165 - public List<Device> findDevicesByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {  
166 - return DaoUtil.convertDataList(  
167 - deviceRepository.findByTenantIdAndEdgeIdAndType(  
168 - fromTimeUUID(tenantId),  
169 - fromTimeUUID(edgeId),  
170 - type,  
171 - Objects.toString(pageLink.getTextSearch(), ""),  
172 - pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),  
173 - PageRequest.of(0, pageLink.getLimit()))); 166 + public ListenableFuture<List<Device>> findDevicesByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
  167 + log.debug("Try to find devices by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
  168 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.DEVICE, pageLink);
  169 + return Futures.transformAsync(relations, input -> {
  170 + List<ListenableFuture<Device>> deviceFutures = new ArrayList<>(input.size());
  171 + for (EntityRelation relation : input) {
  172 + deviceFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
  173 + }
  174 + return Futures.successfulAsList(deviceFutures);
  175 + }, MoreExecutors.directExecutor());
174 } 176 }
175 -  
176 } 177 }
@@ -76,26 +76,4 @@ public interface EntityViewRepository extends CrudRepository<EntityViewEntity, S @@ -76,26 +76,4 @@ public interface EntityViewRepository extends CrudRepository<EntityViewEntity, S
76 76
77 @Query("SELECT DISTINCT ev.type FROM EntityViewEntity ev WHERE ev.tenantId = :tenantId") 77 @Query("SELECT DISTINCT ev.type FROM EntityViewEntity ev WHERE ev.tenantId = :tenantId")
78 List<String> findTenantEntityViewTypes(@Param("tenantId") String tenantId); 78 List<String> findTenantEntityViewTypes(@Param("tenantId") String tenantId);
79 -  
80 - @Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " +  
81 - "AND e.edgeId = :edgeId " +  
82 - "AND LOWER(e.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " +  
83 - "AND e.id > :idOffset ORDER BY e.id")  
84 - List<EntityViewEntity> findByTenantIdAndEdgeId(@Param("tenantId") String tenantId,  
85 - @Param("edgeId") String edgeId,  
86 - @Param("searchText") String searchText,  
87 - @Param("idOffset") String idOffset,  
88 - Pageable pageable);  
89 -  
90 - @Query("SELECT e FROM EntityViewEntity e WHERE e.tenantId = :tenantId " +  
91 - "AND e.edgeId = :edgeId " +  
92 - "AND e.type = :type " +  
93 - "AND LOWER(e.searchText) LIKE LOWER(CONCAT(:searchText, '%')) " +  
94 - "AND e.id > :idOffset ORDER BY e.id")  
95 - List<EntityViewEntity> findByTenantIdAndEdgeIdAndType(@Param("tenantId") String tenantId,  
96 - @Param("edgeId") String edgeId,  
97 - @Param("type") String type,  
98 - @Param("searchText") String searchText,  
99 - @Param("idOffset") String idOffset,  
100 - Pageable pageable);  
101 } 79 }
@@ -15,20 +15,29 @@ @@ -15,20 +15,29 @@
15 */ 15 */
16 package org.thingsboard.server.dao.sql.entityview; 16 package org.thingsboard.server.dao.sql.entityview;
17 17
  18 +import com.google.common.util.concurrent.Futures;
18 import com.google.common.util.concurrent.ListenableFuture; 19 import com.google.common.util.concurrent.ListenableFuture;
  20 +import com.google.common.util.concurrent.MoreExecutors;
  21 +import lombok.extern.slf4j.Slf4j;
19 import org.springframework.beans.factory.annotation.Autowired; 22 import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.data.domain.PageRequest; 23 import org.springframework.data.domain.PageRequest;
21 import org.springframework.data.repository.CrudRepository; 24 import org.springframework.data.repository.CrudRepository;
22 import org.springframework.stereotype.Component; 25 import org.springframework.stereotype.Component;
  26 +import org.thingsboard.server.common.data.Device;
23 import org.thingsboard.server.common.data.EntitySubtype; 27 import org.thingsboard.server.common.data.EntitySubtype;
24 import org.thingsboard.server.common.data.EntityType; 28 import org.thingsboard.server.common.data.EntityType;
25 import org.thingsboard.server.common.data.EntityView; 29 import org.thingsboard.server.common.data.EntityView;
26 import org.thingsboard.server.common.data.UUIDConverter; 30 import org.thingsboard.server.common.data.UUIDConverter;
  31 +import org.thingsboard.server.common.data.id.EdgeId;
27 import org.thingsboard.server.common.data.id.TenantId; 32 import org.thingsboard.server.common.data.id.TenantId;
28 import org.thingsboard.server.common.data.page.TextPageLink; 33 import org.thingsboard.server.common.data.page.TextPageLink;
  34 +import org.thingsboard.server.common.data.page.TimePageLink;
  35 +import org.thingsboard.server.common.data.relation.EntityRelation;
  36 +import org.thingsboard.server.common.data.relation.RelationTypeGroup;
29 import org.thingsboard.server.dao.DaoUtil; 37 import org.thingsboard.server.dao.DaoUtil;
30 import org.thingsboard.server.dao.entityview.EntityViewDao; 38 import org.thingsboard.server.dao.entityview.EntityViewDao;
31 import org.thingsboard.server.dao.model.sql.EntityViewEntity; 39 import org.thingsboard.server.dao.model.sql.EntityViewEntity;
  40 +import org.thingsboard.server.dao.relation.RelationDao;
32 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao; 41 import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
33 import org.thingsboard.server.dao.util.SqlDao; 42 import org.thingsboard.server.dao.util.SqlDao;
34 43
@@ -47,12 +56,16 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR; @@ -47,12 +56,16 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR;
47 */ 56 */
48 @Component 57 @Component
49 @SqlDao 58 @SqlDao
  59 +@Slf4j
50 public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, EntityView> 60 public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, EntityView>
51 implements EntityViewDao { 61 implements EntityViewDao {
52 62
53 @Autowired 63 @Autowired
54 private EntityViewRepository entityViewRepository; 64 private EntityViewRepository entityViewRepository;
55 65
  66 + @Autowired
  67 + private RelationDao relationDao;
  68 +
56 @Override 69 @Override
57 protected Class<EntityViewEntity> getEntityClass() { 70 protected Class<EntityViewEntity> getEntityClass() {
58 return EntityViewEntity.class; 71 return EntityViewEntity.class;
@@ -140,30 +153,15 @@ public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity, @@ -140,30 +153,15 @@ public class JpaEntityViewDao extends JpaAbstractSearchTextDao<EntityViewEntity,
140 } 153 }
141 154
142 @Override 155 @Override
143 - public List<EntityView> findEntityViewsByTenantIdAndEdgeId(UUID tenantId,  
144 - UUID edgeId,  
145 - TextPageLink pageLink) {  
146 - return DaoUtil.convertDataList(  
147 - entityViewRepository.findByTenantIdAndEdgeId(  
148 - fromTimeUUID(tenantId),  
149 - fromTimeUUID(edgeId),  
150 - Objects.toString(pageLink.getTextSearch(), ""),  
151 - pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),  
152 - PageRequest.of(0, pageLink.getLimit())  
153 - ));  
154 - }  
155 -  
156 - @Override  
157 - public List<EntityView> findEntityViewsByTenantIdAndEdgeIdAndType(UUID tenantId, UUID edgeId, String type, TextPageLink pageLink) {  
158 - return DaoUtil.convertDataList(  
159 - entityViewRepository.findByTenantIdAndEdgeIdAndType(  
160 - fromTimeUUID(tenantId),  
161 - fromTimeUUID(edgeId),  
162 - type,  
163 - Objects.toString(pageLink.getTextSearch(), ""),  
164 - pageLink.getIdOffset() == null ? NULL_UUID_STR : fromTimeUUID(pageLink.getIdOffset()),  
165 - PageRequest.of(0, pageLink.getLimit())  
166 - )); 156 + public ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEdgeId(UUID tenantId, UUID edgeId, TimePageLink pageLink) {
  157 + log.debug("Try to find entity views by tenantId [{}], edgeId [{}] and pageLink [{}]", tenantId, edgeId, pageLink);
  158 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new EdgeId(edgeId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.EDGE, EntityType.ENTITY_VIEW, pageLink);
  159 + return Futures.transformAsync(relations, input -> {
  160 + List<ListenableFuture<EntityView>> entityViewFutures = new ArrayList<>(input.size());
  161 + for (EntityRelation relation : input) {
  162 + entityViewFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
  163 + }
  164 + return Futures.successfulAsList(entityViewFutures);
  165 + }, MoreExecutors.directExecutor());
167 } 166 }
168 -  
169 } 167 }
@@ -42,7 +42,6 @@ CREATE TABLE IF NOT EXISTS asset ( @@ -42,7 +42,6 @@ CREATE TABLE IF NOT EXISTS asset (
42 id varchar(31) NOT NULL CONSTRAINT asset_pkey PRIMARY KEY, 42 id varchar(31) NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
43 additional_info varchar, 43 additional_info varchar,
44 customer_id varchar(31), 44 customer_id varchar(31),
45 - edge_id varchar(31),  
46 name varchar(255), 45 name varchar(255),
47 label varchar(255), 46 label varchar(255),
48 search_text varchar(255), 47 search_text varchar(255),
@@ -120,7 +119,6 @@ CREATE TABLE IF NOT EXISTS device ( @@ -120,7 +119,6 @@ CREATE TABLE IF NOT EXISTS device (
120 id varchar(31) NOT NULL CONSTRAINT device_pkey PRIMARY KEY, 119 id varchar(31) NOT NULL CONSTRAINT device_pkey PRIMARY KEY,
121 additional_info varchar, 120 additional_info varchar,
122 customer_id varchar(31), 121 customer_id varchar(31),
123 - edge_id varchar(31),  
124 type varchar(255), 122 type varchar(255),
125 name varchar(255), 123 name varchar(255),
126 label varchar(255), 124 label varchar(255),
@@ -247,7 +245,6 @@ CREATE TABLE IF NOT EXISTS entity_view ( @@ -247,7 +245,6 @@ CREATE TABLE IF NOT EXISTS entity_view (
247 entity_type varchar(255), 245 entity_type varchar(255),
248 tenant_id varchar(31), 246 tenant_id varchar(31),
249 customer_id varchar(31), 247 customer_id varchar(31),
250 - edge_id varchar(31),  
251 type varchar(255), 248 type varchar(255),
252 name varchar(255), 249 name varchar(255),
253 keys varchar(10000000), 250 keys varchar(10000000),
@@ -42,7 +42,6 @@ CREATE TABLE IF NOT EXISTS asset ( @@ -42,7 +42,6 @@ CREATE TABLE IF NOT EXISTS asset (
42 id varchar(31) NOT NULL CONSTRAINT asset_pkey PRIMARY KEY, 42 id varchar(31) NOT NULL CONSTRAINT asset_pkey PRIMARY KEY,
43 additional_info varchar, 43 additional_info varchar,
44 customer_id varchar(31), 44 customer_id varchar(31),
45 - edge_id varchar(31),  
46 name varchar(255), 45 name varchar(255),
47 label varchar(255), 46 label varchar(255),
48 search_text varchar(255), 47 search_text varchar(255),
@@ -120,7 +119,6 @@ CREATE TABLE IF NOT EXISTS device ( @@ -120,7 +119,6 @@ CREATE TABLE IF NOT EXISTS device (
120 id varchar(31) NOT NULL CONSTRAINT device_pkey PRIMARY KEY, 119 id varchar(31) NOT NULL CONSTRAINT device_pkey PRIMARY KEY,
121 additional_info varchar, 120 additional_info varchar,
122 customer_id varchar(31), 121 customer_id varchar(31),
123 - edge_id varchar(31),  
124 type varchar(255), 122 type varchar(255),
125 name varchar(255), 123 name varchar(255),
126 label varchar(255), 124 label varchar(255),
@@ -247,7 +245,6 @@ CREATE TABLE IF NOT EXISTS entity_view ( @@ -247,7 +245,6 @@ CREATE TABLE IF NOT EXISTS entity_view (
247 entity_type varchar(255), 245 entity_type varchar(255),
248 tenant_id varchar(31), 246 tenant_id varchar(31),
249 customer_id varchar(31), 247 customer_id varchar(31),
250 - edge_id varchar(31),  
251 type varchar(255), 248 type varchar(255),
252 name varchar(255), 249 name varchar(255),
253 keys varchar(10000000), 250 keys varchar(10000000),
@@ -18,7 +18,7 @@ export default angular.module('thingsboard.api.asset', []) @@ -18,7 +18,7 @@ export default angular.module('thingsboard.api.asset', [])
18 .name; 18 .name;
19 19
20 /*@ngInject*/ 20 /*@ngInject*/
21 -function AssetService($http, $q, customerService, userService) { 21 +function AssetService($http, $q, $filter, customerService, userService) {
22 22
23 var service = { 23 var service = {
24 getAsset: getAsset, 24 getAsset: getAsset,
@@ -307,9 +307,9 @@ function AssetService($http, $q, customerService, userService) { @@ -307,9 +307,9 @@ function AssetService($http, $q, customerService, userService) {
307 return deferred.promise; 307 return deferred.promise;
308 } 308 }
309 309
310 - function unassignAssetFromEdge(assetId, ignoreErrors, config) { 310 + function unassignAssetFromEdge(edgeId, assetId, ignoreErrors, config) {
311 var deferred = $q.defer(); 311 var deferred = $q.defer();
312 - var url = '/api/edge/asset/' + assetId; 312 + var url = '/api/edge/' + edgeId + '/asset/' + assetId;
313 if (!config) { 313 if (!config) {
314 config = {}; 314 config = {};
315 } 315 }
@@ -325,24 +325,20 @@ function AssetService($http, $q, customerService, userService) { @@ -325,24 +325,20 @@ function AssetService($http, $q, customerService, userService) {
325 function getEdgeAssets(edgeId, pageLink, config, type) { 325 function getEdgeAssets(edgeId, pageLink, config, type) {
326 var deferred = $q.defer(); 326 var deferred = $q.defer();
327 var url = '/api/edge/' + edgeId + '/assets?limit=' + pageLink.limit; 327 var url = '/api/edge/' + edgeId + '/assets?limit=' + pageLink.limit;
328 - if (angular.isDefined(pageLink.textSearch)) {  
329 - url += '&textSearch=' + pageLink.textSearch;  
330 - }  
331 if (angular.isDefined(pageLink.idOffset)) { 328 if (angular.isDefined(pageLink.idOffset)) {
332 - url += '&idOffset=' + pageLink.idOffset;  
333 - }  
334 - if (angular.isDefined(pageLink.textOffset)) {  
335 - url += '&textOffset=' + pageLink.textOffset;  
336 - }  
337 - if (angular.isDefined(type) && type.length) {  
338 - url += '&type=' + type; 329 + url += '&offset=' + pageLink.idOffset;
339 } 330 }
340 $http.get(url, config).then(function success(response) { 331 $http.get(url, config).then(function success(response) {
  332 + if (pageLink.textSearch) {
  333 + response.data.data = $filter('filter')(response.data.data, {name: pageLink.textSearch});
  334 + }
  335 + if (angular.isDefined(type) && type.length) {
  336 + response.data.data = $filter('filter')(response.data.data, {type: type});
  337 + }
341 deferred.resolve(response.data); 338 deferred.resolve(response.data);
342 }, function fail() { 339 }, function fail() {
343 deferred.reject(); 340 deferred.reject();
344 }); 341 });
345 -  
346 return deferred.promise; 342 return deferred.promise;
347 } 343 }
348 } 344 }
@@ -20,7 +20,7 @@ export default angular.module('thingsboard.api.device', [thingsboardTypes]) @@ -20,7 +20,7 @@ export default angular.module('thingsboard.api.device', [thingsboardTypes])
20 .name; 20 .name;
21 21
22 /*@ngInject*/ 22 /*@ngInject*/
23 -function DeviceService($http, $q, $window, userService, attributeService, customerService, types) { 23 +function DeviceService($http, $q, $window, $filter, userService, attributeService, customerService, types) {
24 24
25 var service = { 25 var service = {
26 assignDeviceToCustomer: assignDeviceToCustomer, 26 assignDeviceToCustomer: assignDeviceToCustomer,
@@ -373,9 +373,9 @@ function DeviceService($http, $q, $window, userService, attributeService, custom @@ -373,9 +373,9 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
373 return deferred.promise; 373 return deferred.promise;
374 } 374 }
375 375
376 - function unassignDeviceFromEdge(deviceId) { 376 + function unassignDeviceFromEdge(edgeId, deviceId) {
377 var deferred = $q.defer(); 377 var deferred = $q.defer();
378 - var url = '/api/edge/device/' + deviceId; 378 + var url = '/api/edge/' + edgeId + '/device/' + deviceId;
379 $http.delete(url).then(function success(response) { 379 $http.delete(url).then(function success(response) {
380 deferred.resolve(response.data); 380 deferred.resolve(response.data);
381 }, function fail() { 381 }, function fail() {
@@ -387,25 +387,20 @@ function DeviceService($http, $q, $window, userService, attributeService, custom @@ -387,25 +387,20 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
387 function getEdgeDevices(edgeId, pageLink, config, type) { 387 function getEdgeDevices(edgeId, pageLink, config, type) {
388 var deferred = $q.defer(); 388 var deferred = $q.defer();
389 var url = '/api/edge/' + edgeId + '/devices?limit=' + pageLink.limit; 389 var url = '/api/edge/' + edgeId + '/devices?limit=' + pageLink.limit;
390 - if (angular.isDefined(pageLink.textSearch)) {  
391 - url += '&textSearch=' + pageLink.textSearch;  
392 - }  
393 if (angular.isDefined(pageLink.idOffset)) { 390 if (angular.isDefined(pageLink.idOffset)) {
394 - url += '&idOffset=' + pageLink.idOffset;  
395 - }  
396 - if (angular.isDefined(pageLink.textOffset)) {  
397 - url += '&textOffset=' + pageLink.textOffset;  
398 - }  
399 - if (angular.isDefined(type) && type.length) {  
400 - url += '&type=' + type; 391 + url += '&offset=' + pageLink.idOffset;
401 } 392 }
402 $http.get(url, config).then(function success(response) { 393 $http.get(url, config).then(function success(response) {
  394 + if (pageLink.textSearch) {
  395 + response.data.data = $filter('filter')(response.data.data, {name: pageLink.textSearch});
  396 + }
  397 + if (angular.isDefined(type) && type.length) {
  398 + response.data.data = $filter('filter')(response.data.data, {type: type});
  399 + }
403 deferred.resolve(response.data); 400 deferred.resolve(response.data);
404 }, function fail() { 401 }, function fail() {
405 deferred.reject(); 402 deferred.reject();
406 }); 403 });
407 -  
408 return deferred.promise; 404 return deferred.promise;
409 } 405 }
410 -  
411 } 406 }
@@ -20,7 +20,7 @@ export default angular.module('thingsboard.api.entityView', [thingsboardTypes]) @@ -20,7 +20,7 @@ export default angular.module('thingsboard.api.entityView', [thingsboardTypes])
20 .name; 20 .name;
21 21
22 /*@ngInject*/ 22 /*@ngInject*/
23 -function EntityViewService($http, $q, $window, userService, attributeService, customerService, types) { 23 +function EntityViewService($http, $q, $window, $filter, userService, attributeService, customerService, types) {
24 24
25 var service = { 25 var service = {
26 assignEntityViewToCustomer: assignEntityViewToCustomer, 26 assignEntityViewToCustomer: assignEntityViewToCustomer,
@@ -234,9 +234,9 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu @@ -234,9 +234,9 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu
234 return deferred.promise; 234 return deferred.promise;
235 } 235 }
236 236
237 - function unassignEntityViewFromEdge(entityViewId) { 237 + function unassignEntityViewFromEdge(edgeId, entityViewId) {
238 var deferred = $q.defer(); 238 var deferred = $q.defer();
239 - var url = '/api/edge/entityView/' + entityViewId; 239 + var url = '/api/edge/' + edgeId + '/entityView/' + entityViewId;
240 $http.delete(url).then(function success(response) { 240 $http.delete(url).then(function success(response) {
241 deferred.resolve(response.data); 241 deferred.resolve(response.data);
242 }, function fail() { 242 }, function fail() {
@@ -248,24 +248,20 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu @@ -248,24 +248,20 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu
248 function getEdgeEntityViews(edgeId, pageLink, config, type) { 248 function getEdgeEntityViews(edgeId, pageLink, config, type) {
249 var deferred = $q.defer(); 249 var deferred = $q.defer();
250 var url = '/api/edge/' + edgeId + '/entityViews?limit=' + pageLink.limit; 250 var url = '/api/edge/' + edgeId + '/entityViews?limit=' + pageLink.limit;
251 - if (angular.isDefined(pageLink.textSearch)) {  
252 - url += '&textSearch=' + pageLink.textSearch;  
253 - }  
254 if (angular.isDefined(pageLink.idOffset)) { 251 if (angular.isDefined(pageLink.idOffset)) {
255 - url += '&idOffset=' + pageLink.idOffset;  
256 - }  
257 - if (angular.isDefined(pageLink.textOffset)) {  
258 - url += '&textOffset=' + pageLink.textOffset;  
259 - }  
260 - if (angular.isDefined(type) && type.length) {  
261 - url += '&type=' + type; 252 + url += '&offset=' + pageLink.idOffset;
262 } 253 }
263 $http.get(url, config).then(function success(response) { 254 $http.get(url, config).then(function success(response) {
  255 + if (pageLink.textSearch) {
  256 + response.data.data = $filter('filter')(response.data.data, {name: pageLink.textSearch});
  257 + }
  258 + if (angular.isDefined(type) && type.length) {
  259 + response.data.data = $filter('filter')(response.data.data, {type: type});
  260 + }
264 deferred.resolve(response.data); 261 deferred.resolve(response.data);
265 }, function fail() { 262 }, function fail() {
266 deferred.reject(); 263 deferred.reject();
267 }); 264 });
268 -  
269 return deferred.promise; 265 return deferred.promise;
270 } 266 }
271 } 267 }
@@ -327,7 +327,7 @@ export function AssetController($rootScope, userService, assetService, customerS @@ -327,7 +327,7 @@ export function AssetController($rootScope, userService, assetService, customerS
327 return assetService.getEdgeAssets(edgeId, pageLink, null, assetType); 327 return assetService.getEdgeAssets(edgeId, pageLink, null, assetType);
328 }; 328 };
329 deleteAssetFunction = function (assetId) { 329 deleteAssetFunction = function (assetId) {
330 - return assetService.unassignAssetFromEdge(assetId); 330 + return assetService.unassignAssetFromEdge(edgeId, assetId);
331 }; 331 };
332 refreshAssetsParamsFunction = function () { 332 refreshAssetsParamsFunction = function () {
333 return {"edgeId": edgeId, "topIndex": vm.topIndex}; 333 return {"edgeId": edgeId, "topIndex": vm.topIndex};
@@ -630,7 +630,7 @@ export function AssetController($rootScope, userService, assetService, customerS @@ -630,7 +630,7 @@ export function AssetController($rootScope, userService, assetService, customerS
630 .cancel($translate.instant('action.no')) 630 .cancel($translate.instant('action.no'))
631 .ok($translate.instant('action.yes')); 631 .ok($translate.instant('action.yes'));
632 $mdDialog.show(confirm).then(function () { 632 $mdDialog.show(confirm).then(function () {
633 - assetService.unassignAssetFromEdge(asset.id.id).then(function success() { 633 + assetService.unassignAssetFromEdge(edgeId, asset.id.id).then(function success() {
634 vm.grid.refreshList(); 634 vm.grid.refreshList();
635 }); 635 });
636 }); 636 });
@@ -639,15 +639,15 @@ export function AssetController($rootScope, userService, assetService, customerS @@ -639,15 +639,15 @@ export function AssetController($rootScope, userService, assetService, customerS
639 function unassignAssetsFromEdge($event, items) { 639 function unassignAssetsFromEdge($event, items) {
640 var confirm = $mdDialog.confirm() 640 var confirm = $mdDialog.confirm()
641 .targetEvent($event) 641 .targetEvent($event)
642 - .title($translate.instant('asset.unassign-assets-title', {count: items.selectedCount}, 'messageformat'))  
643 - .htmlContent($translate.instant('asset.unassign-assets-text'))  
644 - .ariaLabel($translate.instant('asset.unassign-asset')) 642 + .title($translate.instant('asset.unassign-assets-from-edge-title', {count: items.selectedCount}, 'messageformat'))
  643 + .htmlContent($translate.instant('asset.unassign-assets-from-edge-text'))
  644 + .ariaLabel($translate.instant('asset.unassign-asset-from-edge'))
645 .cancel($translate.instant('action.no')) 645 .cancel($translate.instant('action.no'))
646 .ok($translate.instant('action.yes')); 646 .ok($translate.instant('action.yes'));
647 $mdDialog.show(confirm).then(function () { 647 $mdDialog.show(confirm).then(function () {
648 var tasks = []; 648 var tasks = [];
649 for (var id in items.selections) { 649 for (var id in items.selections) {
650 - tasks.push(assetService.unassignAssetFromEdge(id)); 650 + tasks.push(assetService.unassignAssetFromEdge(edgeId, id));
651 } 651 }
652 $q.all(tasks).then(function () { 652 $q.all(tasks).then(function () {
653 vm.grid.refreshList(); 653 vm.grid.refreshList();
@@ -360,7 +360,7 @@ export function DeviceController($rootScope, userService, deviceService, custome @@ -360,7 +360,7 @@ export function DeviceController($rootScope, userService, deviceService, custome
360 return deviceService.getEdgeDevices(edgeId, pageLink, null, deviceType); 360 return deviceService.getEdgeDevices(edgeId, pageLink, null, deviceType);
361 }; 361 };
362 deleteDeviceFunction = function (deviceId) { 362 deleteDeviceFunction = function (deviceId) {
363 - return deviceService.unassignDeviceFromEdge(deviceId); 363 + return deviceService.unassignDeviceFromEdge(edgeId, deviceId);
364 }; 364 };
365 refreshDevicesParamsFunction = function () { 365 refreshDevicesParamsFunction = function () {
366 return {"edgeId": edgeId, "topIndex": vm.topIndex}; 366 return {"edgeId": edgeId, "topIndex": vm.topIndex};
@@ -679,7 +679,7 @@ export function DeviceController($rootScope, userService, deviceService, custome @@ -679,7 +679,7 @@ export function DeviceController($rootScope, userService, deviceService, custome
679 .cancel($translate.instant('action.no')) 679 .cancel($translate.instant('action.no'))
680 .ok($translate.instant('action.yes')); 680 .ok($translate.instant('action.yes'));
681 $mdDialog.show(confirm).then(function () { 681 $mdDialog.show(confirm).then(function () {
682 - deviceService.unassignDeviceFromEdge(device.id.id).then(function success() { 682 + deviceService.unassignDeviceFromEdge(edgeId, device.id.id).then(function success() {
683 vm.grid.refreshList(); 683 vm.grid.refreshList();
684 }); 684 });
685 }); 685 });
@@ -688,15 +688,15 @@ export function DeviceController($rootScope, userService, deviceService, custome @@ -688,15 +688,15 @@ export function DeviceController($rootScope, userService, deviceService, custome
688 function unassignDevicesFromEdge($event, items) { 688 function unassignDevicesFromEdge($event, items) {
689 var confirm = $mdDialog.confirm() 689 var confirm = $mdDialog.confirm()
690 .targetEvent($event) 690 .targetEvent($event)
691 - .title($translate.instant('device.unassign-devices-title', {count: items.selectedCount}, 'messageformat'))  
692 - .htmlContent($translate.instant('device.unassign-devices-text'))  
693 - .ariaLabel($translate.instant('device.unassign-device')) 691 + .title($translate.instant('device.unassign-devices-from-edge-title', {count: items.selectedCount}, 'messageformat'))
  692 + .htmlContent($translate.instant('device.unassign-devices-from-edge-text'))
  693 + .ariaLabel($translate.instant('device.unassign-device-from-edge'))
694 .cancel($translate.instant('action.no')) 694 .cancel($translate.instant('action.no'))
695 .ok($translate.instant('action.yes')); 695 .ok($translate.instant('action.yes'));
696 $mdDialog.show(confirm).then(function () { 696 $mdDialog.show(confirm).then(function () {
697 var tasks = []; 697 var tasks = [];
698 for (var id in items.selections) { 698 for (var id in items.selections) {
699 - tasks.push(deviceService.unassignDeviceFromEdge(id)); 699 + tasks.push(deviceService.unassignDeviceFromEdge(edgeId, id));
700 } 700 }
701 $q.all(tasks).then(function () { 701 $q.all(tasks).then(function () {
702 vm.grid.refreshList(); 702 vm.grid.refreshList();
@@ -288,7 +288,7 @@ export function EntityViewController($rootScope, userService, entityViewService, @@ -288,7 +288,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
288 return entityViewService.getEdgeEntityViews(edgeId, pageLink, null, entityViewType); 288 return entityViewService.getEdgeEntityViews(edgeId, pageLink, null, entityViewType);
289 }; 289 };
290 deleteEntityViewFunction = function (entityViewId) { 290 deleteEntityViewFunction = function (entityViewId) {
291 - return entityViewService.unassignEntityViewFromEdge(entityViewId); 291 + return entityViewService.unassignEntityViewFromEdge(edgeId, entityViewId);
292 }; 292 };
293 refreshEntityViewsParamsFunction = function () { 293 refreshEntityViewsParamsFunction = function () {
294 return {"edgeId": edgeId, "topIndex": vm.topIndex}; 294 return {"edgeId": edgeId, "topIndex": vm.topIndex};
@@ -300,10 +300,7 @@ export function EntityViewController($rootScope, userService, entityViewService, @@ -300,10 +300,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
300 }, 300 },
301 name: function() { return $translate.instant('action.unassign') }, 301 name: function() { return $translate.instant('action.unassign') },
302 details: function() { return $translate.instant('entity-view.unassign-from-edge') }, 302 details: function() { return $translate.instant('entity-view.unassign-from-edge') },
303 - icon: "assignment_return",  
304 - isEnabled: function(entityView) {  
305 - return entityView && entityView.edgeId && entityView.edgeId.id !== types.id.nullUid;  
306 - } 303 + icon: "assignment_return"
307 } 304 }
308 ); 305 );
309 306
@@ -314,7 +311,7 @@ export function EntityViewController($rootScope, userService, entityViewService, @@ -314,7 +311,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
314 }, 311 },
315 name: function() { return $translate.instant('entity-view.unassign-entity-views') }, 312 name: function() { return $translate.instant('entity-view.unassign-entity-views') },
316 details: function(selectedCount) { 313 details: function(selectedCount) {
317 - return $translate.instant('entity-view.unassign-entity-views-action-title', {count: selectedCount}, "messageformat"); 314 + return $translate.instant('entity-view.unassign-entity-views-from-edge-action-title', {count: selectedCount}, "messageformat");
318 }, 315 },
319 icon: "assignment_return" 316 icon: "assignment_return"
320 } 317 }
@@ -581,15 +578,15 @@ export function EntityViewController($rootScope, userService, entityViewService, @@ -581,15 +578,15 @@ export function EntityViewController($rootScope, userService, entityViewService,
581 function unassignEntityViewsFromEdge($event, items) { 578 function unassignEntityViewsFromEdge($event, items) {
582 var confirm = $mdDialog.confirm() 579 var confirm = $mdDialog.confirm()
583 .targetEvent($event) 580 .targetEvent($event)
584 - .title($translate.instant('entity-view.unassign-entity-views-title', {count: items.selectedCount}, 'messageformat'))  
585 - .htmlContent($translate.instant('entity-view.unassign-entity-views-text'))  
586 - .ariaLabel($translate.instant('entity-view.unassign-entity-view')) 581 + .title($translate.instant('entity-view.unassign-entity-views-from-edge-title', {count: items.selectedCount}, 'messageformat'))
  582 + .htmlContent($translate.instant('entity-view.unassign-entity-views-from-edge-text'))
  583 + .ariaLabel($translate.instant('entity-view.unassign-entity-view-from-edge'))
587 .cancel($translate.instant('action.no')) 584 .cancel($translate.instant('action.no'))
588 .ok($translate.instant('action.yes')); 585 .ok($translate.instant('action.yes'));
589 $mdDialog.show(confirm).then(function () { 586 $mdDialog.show(confirm).then(function () {
590 var tasks = []; 587 var tasks = [];
591 for (var id in items.selections) { 588 for (var id in items.selections) {
592 - tasks.push(entityViewService.unassignEntityViewFromEdge(id)); 589 + tasks.push(entityViewService.unassignEntityViewFromEdge(edgeId, id));
593 } 590 }
594 $q.all(tasks).then(function () { 591 $q.all(tasks).then(function () {
595 vm.grid.refreshList(); 592 vm.grid.refreshList();
@@ -612,7 +609,7 @@ export function EntityViewController($rootScope, userService, entityViewService, @@ -612,7 +609,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
612 .cancel($translate.instant('action.no')) 609 .cancel($translate.instant('action.no'))
613 .ok($translate.instant('action.yes')); 610 .ok($translate.instant('action.yes'));
614 $mdDialog.show(confirm).then(function () { 611 $mdDialog.show(confirm).then(function () {
615 - entityViewService.unassignEntityViewFromEdge(entityView.id.id).then(function success() { 612 + entityViewService.unassignEntityViewFromEdge(edgeId, entityView.id.id).then(function success() {
616 vm.grid.refreshList(); 613 vm.grid.refreshList();
617 }); 614 });
618 }); 615 });
@@ -291,9 +291,12 @@ @@ -291,9 +291,12 @@
291 "unassign-from-edge": "Unassign from edge", 291 "unassign-from-edge": "Unassign from edge",
292 "assign-to-edge": "Assign to edge", 292 "assign-to-edge": "Assign to edge",
293 "assign-to-edge-text": "Please select the edge to assign the asset(s)", 293 "assign-to-edge-text": "Please select the edge to assign the asset(s)",
  294 + "unassign-asset-from-edge": "Unassign asset",
294 "unassign-asset-from-edge-title": "Are you sure you want to unassign the asset '{{assetName}}'?", 295 "unassign-asset-from-edge-title": "Are you sure you want to unassign the asset '{{assetName}}'?",
295 "unassign-asset-from-edge-text": "After the confirmation the asset will be unassigned and won't be accessible by the edge.", 296 "unassign-asset-from-edge-text": "After the confirmation the asset will be unassigned and won't be accessible by the edge.",
296 - "unassign-assets-from-edge-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from edge" 297 + "unassign-assets-from-edge-action-title": "Unassign { count, plural, 1 {1 asset} other {# assets} } from edge",
  298 + "unassign-assets-from-edge-title": "Are you sure you want to unassign { count, plural, 1 {1 asset} other {# assets} }?",
  299 + "unassign-assets-from-edge-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the edge."
297 }, 300 },
298 "attribute": { 301 "attribute": {
299 "attributes": "Attributes", 302 "attributes": "Attributes",
@@ -748,7 +751,10 @@ @@ -748,7 +751,10 @@
748 "assign-to-edge-text": "Please select the edge to assign the device(s)", 751 "assign-to-edge-text": "Please select the edge to assign the device(s)",
749 "unassign-device-from-edge-title": "Are you sure you want to unassign the device '{{deviceName}}'?", 752 "unassign-device-from-edge-title": "Are you sure you want to unassign the device '{{deviceName}}'?",
750 "unassign-device-from-edge-text": "After the confirmation the device will be unassigned and won't be accessible by the edge.", 753 "unassign-device-from-edge-text": "After the confirmation the device will be unassigned and won't be accessible by the edge.",
751 - "unassign-devices-from-edge-action-title": "Unassign { count, plural, 1 {1 device} other {# devices} } from edge" 754 + "unassign-devices-from-edge-action-title": "Unassign { count, plural, 1 {1 device} other {# devices} } from edge",
  755 + "unassign-device-from-edge": "Unassign device",
  756 + "unassign-devices-from-edge-title": "Are you sure you want to unassign { count, plural, 1 {1 device} other {# devices} }?",
  757 + "unassign-devices-from-edge-text": "After the confirmation all selected devices will be unassigned and won't be accessible by the edge."
752 }, 758 },
753 "dialog": { 759 "dialog": {
754 "close": "Close dialog" 760 "close": "Close dialog"
@@ -1054,7 +1060,10 @@ @@ -1054,7 +1060,10 @@
1054 "assign-to-edge-text": "Please select the edge to assign the entity view(s)", 1060 "assign-to-edge-text": "Please select the edge to assign the entity view(s)",
1055 "unassign-entity-view-from-edge-title": "Are you sure you want to unassign the entity view '{{entityViewName}}'?", 1061 "unassign-entity-view-from-edge-title": "Are you sure you want to unassign the entity view '{{entityViewName}}'?",
1056 "unassign-entity-view-from-edge-text": "After the confirmation the entity view will be unassigned and won't be accessible by the edge.", 1062 "unassign-entity-view-from-edge-text": "After the confirmation the entity view will be unassigned and won't be accessible by the edge.",
1057 - "unassign-entity-views-from-edge-action-title": "Unassign { count, plural, 1 {1 entity view} other {# entity views} } from edge" 1063 + "unassign-entity-views-from-edge-action-title": "Unassign { count, plural, 1 {1 entity view} other {# entity views} } from edge",
  1064 + "unassign-entity-view-from-edge": "Unassign entity view",
  1065 + "unassign-entity-views-from-edge-title": "Are you sure you want to unassign { count, plural, 1 {1 entity view} other {# entity views} }?",
  1066 + "unassign-entity-views-from-edge-text": "After the confirmation all selected entity views will be unassigned and won't be accessible by the edge."
1058 }, 1067 },
1059 "event": { 1068 "event": {
1060 "event-type": "Event type", 1069 "event-type": "Event type",
@@ -1580,7 +1589,7 @@ @@ -1580,7 +1589,7 @@
1580 "invalid-rulechain-type-error": "Unable to import rule chain: Invalid rule chain type. Expected type is {{expectedRuleChainType}}.", 1589 "invalid-rulechain-type-error": "Unable to import rule chain: Invalid rule chain type. Expected type is {{expectedRuleChainType}}.",
1581 "set-default-edge": "Make edge rule chain default", 1590 "set-default-edge": "Make edge rule chain default",
1582 "set-default-edge-title": "Are you sure you want to make the edge rule chain '{{ruleChainName}}' default?", 1591 "set-default-edge-title": "Are you sure you want to make the edge rule chain '{{ruleChainName}}' default?",
1583 - "set-default-edge-text": "After the confirmation the edge rule chain will be added to default list and handle all incoming transport messages.", 1592 + "set-default-edge-text": "After the confirmation the edge rule chain will be added to default list and assigned to newly created edge(s).",
1584 "remove-default-edge": "Remove edge rule chain from defaults", 1593 "remove-default-edge": "Remove edge rule chain from defaults",
1585 "remove-default-edge-title": "Are you sure you want to remove the edge rule chain '{{ruleChainName}}' from default list?", 1594 "remove-default-edge-title": "Are you sure you want to remove the edge rule chain '{{ruleChainName}}' from default list?",
1586 "remove-default-edge-text": "After the confirmation the edge rule chain will stop handling all incoming transport messages." 1595 "remove-default-edge-text": "After the confirmation the edge rule chain will stop handling all incoming transport messages."