Commit 63395fc8e5c98c70b951623db7ad29939301b2b3

Authored by Volodymyr Babak
1 parent 5dc541ea

Added attribute copying on entity view creation

... ... @@ -16,6 +16,7 @@
16 16 package org.thingsboard.server.dao.entityview;
17 17
18 18 import com.google.common.base.Function;
  19 +import com.google.common.util.concurrent.FutureCallback;
19 20 import com.google.common.util.concurrent.Futures;
20 21 import com.google.common.util.concurrent.ListenableFuture;
21 22 import lombok.extern.slf4j.Slf4j;
... ... @@ -28,6 +29,7 @@ import org.springframework.cache.annotation.CachePut;
28 29 import org.springframework.cache.annotation.Cacheable;
29 30 import org.springframework.stereotype.Service;
30 31 import org.thingsboard.server.common.data.Customer;
  32 +import org.thingsboard.server.common.data.DataConstants;
31 33 import org.thingsboard.server.common.data.Device;
32 34 import org.thingsboard.server.common.data.EntitySubtype;
33 35 import org.thingsboard.server.common.data.EntityType;
... ... @@ -40,10 +42,12 @@ import org.thingsboard.server.common.data.id.DeviceId;
40 42 import org.thingsboard.server.common.data.id.EntityId;
41 43 import org.thingsboard.server.common.data.id.EntityViewId;
42 44 import org.thingsboard.server.common.data.id.TenantId;
  45 +import org.thingsboard.server.common.data.kv.AttributeKvEntry;
43 46 import org.thingsboard.server.common.data.page.TextPageData;
44 47 import org.thingsboard.server.common.data.page.TextPageLink;
45 48 import org.thingsboard.server.common.data.relation.EntityRelation;
46 49 import org.thingsboard.server.common.data.relation.EntitySearchDirection;
  50 +import org.thingsboard.server.dao.attributes.AttributesService;
47 51 import org.thingsboard.server.dao.customer.CustomerDao;
48 52 import org.thingsboard.server.dao.entity.AbstractEntityService;
49 53 import org.thingsboard.server.dao.exception.DataValidationException;
... ... @@ -53,6 +57,7 @@ import org.thingsboard.server.dao.tenant.TenantDao;
53 57
54 58 import javax.annotation.Nullable;
55 59 import java.util.ArrayList;
  60 +import java.util.Collection;
56 61 import java.util.Collections;
57 62 import java.util.Comparator;
58 63 import java.util.List;
... ... @@ -87,6 +92,9 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
87 92 private CustomerDao customerDao;
88 93
89 94 @Autowired
  95 + private AttributesService attributesService;
  96 +
  97 + @Autowired
90 98 private CacheManager cacheManager;
91 99
92 100 // @Cacheable(cacheNames = ENTITY_VIEW_CACHE)
... ... @@ -110,7 +118,46 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
110 118 public EntityView saveEntityView(EntityView entityView) {
111 119 log.trace("Executing save entity view [{}]", entityView);
112 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 163 @Override
... ...
... ... @@ -54,7 +54,7 @@ export default function AttributeTableDirective($compile, $templateCache, $rootS
54 54
55 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 58 scope.attributeScopes = types.attributesScope;
59 59 scope.attributeScopeSelectionReadonly = false;
60 60 } else {
... ...