Commit 63395fc8e5c98c70b951623db7ad29939301b2b3
1 parent
5dc541ea
Added attribute copying on entity view creation
Showing
2 changed files
with
49 additions
and
2 deletions
... | ... | @@ -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 { | ... | ... |