Browse Source

Fixed for entity view afte testing

pull/1151/head
Volodymyr Babak 8 years ago
parent
commit
8b1a9351f3
  1. 8
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  2. 85
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  3. 6
      application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
  4. 7
      dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java
  5. 45
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
  6. 16
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java
  7. 27
      ui/src/app/api/entity-view.service.js
  8. 4
      ui/src/app/api/entity.service.js

8
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -51,6 +51,7 @@ import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService;
@ -70,6 +71,7 @@ import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.state.DeviceStateService;
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
@ -143,6 +145,12 @@ public abstract class BaseController {
@Autowired
protected EntityViewService entityViewService;
@Autowired
protected TelemetrySubscriptionService tsSubService;
@Autowired
protected AttributesService attributesService;
@ExceptionHandler(ThingsboardException.class)
public void handleThingsboardException(ThingsboardException ex, HttpServletResponse response) {
errorResponseHandler.handle(ex, response);

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

@ -15,7 +15,10 @@
*/
package org.thingsboard.server.controller;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
@ -26,7 +29,9 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
@ -34,15 +39,24 @@ import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.service.security.model.SecurityUser;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;
@ -52,6 +66,7 @@ import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;
*/
@RestController
@RequestMapping("/api")
@Slf4j
public class EntityViewController extends BaseController {
public static final String ENTITY_VIEW_ID = "entityViewId";
@ -75,6 +90,20 @@ public class EntityViewController extends BaseController {
try {
entityView.setTenantId(getCurrentUser().getTenantId());
EntityView savedEntityView = checkNotNull(entityViewService.saveEntityView(entityView));
List<ListenableFuture<List<Void>>> futures = new ArrayList<>();
if (savedEntityView.getKeys() != null && savedEntityView.getKeys().getAttributes() != null) {
futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.CLIENT_SCOPE, savedEntityView.getKeys().getAttributes().getCs(), getCurrentUser()));
futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.SERVER_SCOPE, savedEntityView.getKeys().getAttributes().getSs(), getCurrentUser()));
futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.SHARED_SCOPE, savedEntityView.getKeys().getAttributes().getSh(), getCurrentUser()));
}
for (ListenableFuture<List<Void>> future : futures) {
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Failed to copy attributes to entity view", e);
}
}
logEntityAction(savedEntityView.getId(), savedEntityView, null,
entityView.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
return savedEntityView;
@ -85,6 +114,62 @@ public class EntityViewController extends BaseController {
}
}
private ListenableFuture<List<Void>> copyAttributesFromEntityToEntityView(EntityView entityView, String scope, Collection<String> keys, SecurityUser user) throws ThingsboardException {
EntityViewId entityId = entityView.getId();
if (keys != null && !keys.isEmpty()) {
ListenableFuture<List<AttributeKvEntry>> getAttrFuture = attributesService.find(entityView.getEntityId(), scope, keys);
return Futures.transform(getAttrFuture, attributeKvEntries -> {
List<AttributeKvEntry> attributes;
if (attributeKvEntries != null && !attributeKvEntries.isEmpty()) {
attributes =
attributeKvEntries.stream()
.filter(attributeKvEntry -> {
long startTime = entityView.getStartTimeMs();
long endTime = entityView.getEndTimeMs();
long lastUpdateTs = attributeKvEntry.getLastUpdateTs();
return startTime == 0 && endTime == 0 ||
(endTime == 0 && startTime < lastUpdateTs) ||
(startTime == 0 && endTime > lastUpdateTs)
? true : startTime < lastUpdateTs && endTime > lastUpdateTs;
}).collect(Collectors.toList());
tsSubService.saveAndNotify(entityId, scope, attributes, new FutureCallback<Void>() {
@Override
public void onSuccess(@Nullable Void tmp) {
try {
logAttributesUpdated(user, entityId, scope, attributes, null);
} catch (ThingsboardException e) {
log.error("Failed to log attribute updates", e);
}
if (entityId.getEntityType() == EntityType.ENTITY_VIEW) {
DeviceId deviceId = new DeviceId(entityId.getId());
DeviceAttributesEventNotificationMsg notificationMsg = DeviceAttributesEventNotificationMsg.onUpdate(
user.getTenantId(), deviceId, scope, attributes);
actorService.onMsg(new SendToClusterMsg(deviceId, notificationMsg));
}
}
@Override
public void onFailure(Throwable t) {
try {
logAttributesUpdated(user, entityId, scope, attributes, t);
} catch (ThingsboardException e) {
log.error("Failed to log attribute updates", e);
}
}
});
}
return null;
});
} else {
return Futures.immediateFuture(null);
}
}
private void logAttributesUpdated(SecurityUser user, EntityId entityId, String scope, List<AttributeKvEntry> attributes, Throwable e) throws ThingsboardException {
logEntityAction(user, (UUIDBased & EntityId) entityId, null, null, ActionType.ATTRIBUTES_UPDATED, toException(e),
scope, attributes);
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/entityView/{entityViewId}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)

6
application/src/main/java/org/thingsboard/server/controller/TelemetryController.java

@ -93,15 +93,9 @@ import java.util.stream.Collectors;
@Slf4j
public class TelemetryController extends BaseController {
@Autowired
private AttributesService attributesService;
@Autowired
private TimeseriesService tsService;
@Autowired
private TelemetrySubscriptionService tsSubService;
@Autowired
private AccessValidator accessValidator;

7
dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java

@ -29,6 +29,7 @@ import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.entityview.EntityViewService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
@ -46,6 +47,9 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
@Autowired
private DeviceService deviceService;
@Autowired
private EntityViewService entityViewService;
@Autowired
private TenantService tenantService;
@ -81,6 +85,9 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
case DEVICE:
hasName = deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId()));
break;
case ENTITY_VIEW:
hasName = entityViewService.findEntityViewByIdAsync(new EntityViewId(entityId.getId()));
break;
case TENANT:
hasName = tenantService.findTenantByIdAsync(new TenantId(entityId.getId()));
break;

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

@ -105,21 +105,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
log.trace("Executing save entity view [{}]", entityView);
entityViewValidator.validate(entityView);
EntityView savedEntityView = entityViewDao.save(entityView);
List<ListenableFuture<List<Void>>> futures = new ArrayList<>();
if (savedEntityView.getKeys() != null && savedEntityView.getKeys().getAttributes() != null) {
futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.CLIENT_SCOPE, savedEntityView.getKeys().getAttributes().getCs()));
futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.SERVER_SCOPE, savedEntityView.getKeys().getAttributes().getSs()));
futures.add(copyAttributesFromEntityToEntityView(savedEntityView, DataConstants.SHARED_SCOPE, savedEntityView.getKeys().getAttributes().getSh()));
}
for (ListenableFuture<List<Void>> future : futures) {
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
log.error("Failed to copy attributes to entity view", e);
throw new RuntimeException("Failed to copy attributes to entity view", e);
}
}
return savedEntityView;
}
@ -294,36 +279,6 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
});
}
private ListenableFuture<List<Void>> copyAttributesFromEntityToEntityView(EntityView entityView, String scope, Collection<String> keys) {
if (keys != null && !keys.isEmpty()) {
ListenableFuture<List<AttributeKvEntry>> getAttrFuture = attributesService.find(entityView.getEntityId(), scope, keys);
return Futures.transform(getAttrFuture, attributeKvEntries -> {
List<AttributeKvEntry> filteredAttributes = new ArrayList<>();
if (attributeKvEntries != null && !attributeKvEntries.isEmpty()) {
filteredAttributes =
attributeKvEntries.stream()
.filter(attributeKvEntry -> {
long startTime = entityView.getStartTimeMs();
long endTime = entityView.getEndTimeMs();
long lastUpdateTs = attributeKvEntry.getLastUpdateTs();
return startTime == 0 && endTime == 0 ||
(endTime == 0 && startTime < lastUpdateTs) ||
(startTime == 0 && endTime > lastUpdateTs)
? true : startTime < lastUpdateTs && endTime > lastUpdateTs;
}).collect(Collectors.toList());
}
try {
return attributesService.save(entityView.getId(), scope, filteredAttributes).get();
} catch (InterruptedException | ExecutionException e) {
log.error("Failed to copy attributes to entity view", e);
throw new RuntimeException("Failed to copy attributes to entity view", e);
}
});
} else {
return Futures.immediateFuture(null);
}
}
private DataValidator<EntityView> entityViewValidator =
new DataValidator<EntityView>() {

16
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java

@ -116,8 +116,10 @@ public class TbCopyAttributesToEntityViewNode implements TbNode {
}
List<String> filteredAttributes =
attributes.stream().filter(attr -> attributeContainsInEntityView(scope, attr, entityView)).collect(Collectors.toList());
ctx.getAttributesService().removeAll(entityView.getId(), scope, filteredAttributes);
transformAndTellNext(ctx, msg, entityView);
if (filteredAttributes != null && !filteredAttributes.isEmpty()) {
ctx.getAttributesService().removeAll(entityView.getId(), scope, filteredAttributes);
transformAndTellNext(ctx, msg, entityView);
}
}
}
}
@ -139,19 +141,10 @@ public class TbCopyAttributesToEntityViewNode implements TbNode {
private boolean attributeContainsInEntityView(String scope, String attrKey, EntityView entityView) {
switch (scope) {
case DataConstants.CLIENT_SCOPE:
if (entityView.getKeys().getAttributes().getCs().isEmpty()) {
return true;
}
return entityView.getKeys().getAttributes().getCs().contains(attrKey);
case DataConstants.SERVER_SCOPE:
if (entityView.getKeys().getAttributes().getSs().isEmpty()) {
return true;
}
return entityView.getKeys().getAttributes().getSs().contains(attrKey);
case DataConstants.SHARED_SCOPE:
if (entityView.getKeys().getAttributes().getSh().isEmpty()) {
return true;
}
return entityView.getKeys().getAttributes().getSh().contains(attrKey);
}
return false;
@ -159,6 +152,5 @@ public class TbCopyAttributesToEntityViewNode implements TbNode {
@Override
public void destroy() {
}
}

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

@ -27,7 +27,6 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu
deleteEntityView: deleteEntityView,
getCustomerEntityViews: getCustomerEntityViews,
getEntityView: getEntityView,
getEntityViews: getEntityViews,
getTenantEntityViews: getTenantEntityViews,
saveEntityView: saveEntityView,
unassignEntityViewFromCustomer: unassignEntityViewFromCustomer,
@ -126,32 +125,6 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu
return deferred.promise;
}
function getEntityViews(entityViewIds, config) {
var deferred = $q.defer();
var ids = '';
for (var i=0;i<entityViewIds.length;i++) {
if (i>0) {
ids += ',';
}
ids += entityViewIds[i];
}
var url = '/api/entityViews?entityViewIds=' + ids;
$http.get(url, config).then(function success(response) {
var entityViews = response.data;
entityViews.sort(function (entityView1, entityView2) {
var id1 = entityView1.id.id;
var id2 = entityView2.id.id;
var index1 = entityViewIds.indexOf(id1);
var index2 = entityViewIds.indexOf(id2);
return index1 - index2;
});
deferred.resolve(entityViews);
}, function fail(response) {
deferred.reject(response.data);
});
return deferred.promise;
}
function saveEntityView(entityView) {
var deferred = $q.defer();
var url = '/api/entityView';

4
ui/src/app/api/entity.service.js

@ -135,6 +135,10 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device
case types.entityType.asset:
promise = assetService.getAssets(entityIds, config);
break;
case types.entityType.entityView:
promise = getEntitiesByIdsPromise(
(id) => entityViewService.getEntityView(id, config), entityIds);
break;
case types.entityType.tenant:
promise = getEntitiesByIdsPromise(
(id) => tenantService.getTenant(id, config), entityIds);

Loading…
Cancel
Save