Commit 63395fc8e5c98c70b951623db7ad29939301b2b3

Authored by Volodymyr Babak
1 parent 5dc541ea

Added attribute copying on entity view creation

@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.entityview; 16 package org.thingsboard.server.dao.entityview;
17 17
18 import com.google.common.base.Function; 18 import com.google.common.base.Function;
  19 +import com.google.common.util.concurrent.FutureCallback;
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 lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
@@ -28,6 +29,7 @@ import org.springframework.cache.annotation.CachePut; @@ -28,6 +29,7 @@ import org.springframework.cache.annotation.CachePut;
28 import org.springframework.cache.annotation.Cacheable; 29 import org.springframework.cache.annotation.Cacheable;
29 import org.springframework.stereotype.Service; 30 import org.springframework.stereotype.Service;
30 import org.thingsboard.server.common.data.Customer; 31 import org.thingsboard.server.common.data.Customer;
  32 +import org.thingsboard.server.common.data.DataConstants;
31 import org.thingsboard.server.common.data.Device; 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;
@@ -40,10 +42,12 @@ import org.thingsboard.server.common.data.id.DeviceId; @@ -40,10 +42,12 @@ import org.thingsboard.server.common.data.id.DeviceId;
40 import org.thingsboard.server.common.data.id.EntityId; 42 import org.thingsboard.server.common.data.id.EntityId;
41 import org.thingsboard.server.common.data.id.EntityViewId; 43 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;
  45 +import org.thingsboard.server.common.data.kv.AttributeKvEntry;
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;
45 import org.thingsboard.server.common.data.relation.EntityRelation; 48 import org.thingsboard.server.common.data.relation.EntityRelation;
46 import org.thingsboard.server.common.data.relation.EntitySearchDirection; 49 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
  50 +import org.thingsboard.server.dao.attributes.AttributesService;
47 import org.thingsboard.server.dao.customer.CustomerDao; 51 import org.thingsboard.server.dao.customer.CustomerDao;
48 import org.thingsboard.server.dao.entity.AbstractEntityService; 52 import org.thingsboard.server.dao.entity.AbstractEntityService;
49 import org.thingsboard.server.dao.exception.DataValidationException; 53 import org.thingsboard.server.dao.exception.DataValidationException;
@@ -53,6 +57,7 @@ import org.thingsboard.server.dao.tenant.TenantDao; @@ -53,6 +57,7 @@ import org.thingsboard.server.dao.tenant.TenantDao;
53 57
54 import javax.annotation.Nullable; 58 import javax.annotation.Nullable;
55 import java.util.ArrayList; 59 import java.util.ArrayList;
  60 +import java.util.Collection;
56 import java.util.Collections; 61 import java.util.Collections;
57 import java.util.Comparator; 62 import java.util.Comparator;
58 import java.util.List; 63 import java.util.List;
@@ -87,6 +92,9 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -87,6 +92,9 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
87 private CustomerDao customerDao; 92 private CustomerDao customerDao;
88 93
89 @Autowired 94 @Autowired
  95 + private AttributesService attributesService;
  96 +
  97 + @Autowired
90 private CacheManager cacheManager; 98 private CacheManager cacheManager;
91 99
92 // @Cacheable(cacheNames = ENTITY_VIEW_CACHE) 100 // @Cacheable(cacheNames = ENTITY_VIEW_CACHE)
@@ -110,7 +118,46 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -110,7 +118,46 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
110 public EntityView saveEntityView(EntityView entityView) { 118 public EntityView saveEntityView(EntityView entityView) {
111 log.trace("Executing save entity view [{}]", entityView); 119 log.trace("Executing save entity view [{}]", entityView);
112 entityViewValidator.validate(entityView); 120 entityViewValidator.validate(entityView);
113 - return entityViewDao.save(entityView); 121 + EntityView savedEntityView = entityViewDao.save(entityView);
  122 + copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.CLIENT_SCOPE, savedEntityView.getKeys().getAttributes().getCs());
  123 + copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.SERVER_SCOPE, savedEntityView.getKeys().getAttributes().getSs());
  124 + copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.SHARED_SCOPE, savedEntityView.getKeys().getAttributes().getSh());
  125 + return savedEntityView;
  126 + }
  127 +
  128 + private void copyAttributesFromEntityToEntityView(EntityView entityView, String scope, Collection<String> keys) {
  129 + if (!keys.isEmpty()) {
  130 + ListenableFuture<List<AttributeKvEntry>> getAttrFuture = attributesService.find(entityView.getEntityId(), scope, keys);
  131 + Futures.addCallback(getAttrFuture, new FutureCallback<List<AttributeKvEntry>>() {
  132 + @Override
  133 + public void onSuccess(@Nullable List<AttributeKvEntry> attributeKvEntries) {
  134 + if (attributeKvEntries != null && !attributeKvEntries.isEmpty()) {
  135 + List<AttributeKvEntry> filteredAttributes =
  136 + attributeKvEntries.stream()
  137 + .filter(attributeKvEntry -> {
  138 + if (entityView.getStartTs() == 0 && entityView.getEndTs() == 0) {
  139 + return true;
  140 + }
  141 + if (entityView.getEndTs() == 0 && entityView.getStartTs() < attributeKvEntry.getLastUpdateTs()) {
  142 + return true;
  143 + }
  144 + if (entityView.getStartTs() == 0 && entityView.getEndTs() > attributeKvEntry.getLastUpdateTs()) {
  145 + return true;
  146 + }
  147 + return entityView.getStartTs() < attributeKvEntry.getLastUpdateTs()
  148 + && entityView.getEndTs() > attributeKvEntry.getLastUpdateTs();
  149 + }).collect(Collectors.toList());
  150 + attributesService.save(entityView.getId(), scope, filteredAttributes);
  151 + }
  152 + }
  153 +
  154 + @Override
  155 + public void onFailure(Throwable throwable) {
  156 + log.error("Failed to fetch [{}] attributes [{}] for [{}] entity [{}]",
  157 + scope, keys, entityView.getEntityId().getEntityType().name(), entityView.getEntityId().getId().toString(), throwable);
  158 + }
  159 + });
  160 + }
114 } 161 }
115 162
116 @Override 163 @Override
@@ -54,7 +54,7 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS @@ -54,7 +54,7 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS
54 54
55 scope.entityType = attrs.entityType; 55 scope.entityType = attrs.entityType;
56 56
57 - if (scope.entityType === types.entityType.device) { 57 + if (scope.entityType === types.entityType.device || scope.entityType === types.entityType.entityView) {
58 scope.attributeScopes = types.attributesScope; 58 scope.attributeScopes = types.attributesScope;
59 scope.attributeScopeSelectionReadonly = false; 59 scope.attributeScopeSelectionReadonly = false;
60 } else { 60 } else {