Browse Source

Refactoring of app layer to support tenant level rate limits

pull/1236/head
Andrew Shvayka 8 years ago
parent
commit
a2dd90a4c2
  1. 6
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  2. 10
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java
  3. 4
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
  4. 2
      application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
  5. 5
      application/src/main/java/org/thingsboard/server/controller/AdminController.java
  6. 8
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  7. 10
      application/src/main/java/org/thingsboard/server/controller/AssetController.java
  8. 25
      application/src/main/java/org/thingsboard/server/controller/AuthController.java
  9. 29
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  10. 2
      application/src/main/java/org/thingsboard/server/controller/CustomerController.java
  11. 18
      application/src/main/java/org/thingsboard/server/controller/DashboardController.java
  12. 14
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  13. 24
      application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
  14. 12
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  15. 12
      application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
  16. 67
      application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
  17. 16
      application/src/main/java/org/thingsboard/server/controller/UserController.java
  18. 2
      application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
  19. 6
      application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
  20. 9
      application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java
  21. 4
      application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java
  22. 14
      application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
  23. 5
      application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java
  24. 4
      application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java
  25. 30
      application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
  26. 9
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenAuthenticationProvider.java
  27. 7
      application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationProvider.java
  28. 10
      application/src/main/java/org/thingsboard/server/service/security/device/DefaultDeviceAuthService.java
  29. 3
      application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java
  30. 10
      application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java
  31. 39
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java
  32. 41
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java
  33. 1
      application/src/main/java/org/thingsboard/server/service/telemetry/TelemetrySubscriptionService.java
  34. 2
      application/src/main/java/org/thingsboard/server/service/telemetry/sub/SubscriptionState.java
  35. 7
      application/src/main/java/org/thingsboard/server/service/transport/LocalTransportApiService.java
  36. 11
      application/src/main/proto/cluster.proto
  37. 8
      application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java
  38. 2
      application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java
  39. 3
      common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java
  40. 2
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/auth/DeviceAuthService.java
  41. 2
      dao/src/test/resources/cassandra-test.properties
  42. 14
      rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineTelemetryService.java
  43. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java
  44. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbCopyAttributesToEntityViewNode.java
  45. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java
  46. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java
  47. 4
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbEntityGetAttrNode.java
  48. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java
  49. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java
  50. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java
  51. 6
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesCustomerIdAsyncLoader.java
  52. 28
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java
  53. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoader.java
  54. 2
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoader.java
  55. 12
      rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesTenantIdAsyncLoader.java
  56. 2
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAlarmNodeTest.java
  57. 24
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java
  58. 8
      rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeTest.java

6
application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java

@ -123,7 +123,7 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
} }
private void initAttributes() { private void initAttributes() {
Device device = systemContext.getDeviceService().findDeviceById(deviceId); Device device = systemContext.getDeviceService().findDeviceById(tenantId, deviceId);
this.deviceName = device.getName(); this.deviceName = device.getName();
this.deviceType = device.getType(); this.deviceType = device.getType();
this.defaultMetaData = new TbMsgMetaData(); this.defaultMetaData = new TbMsgMetaData();
@ -290,9 +290,9 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
private ListenableFuture<List<AttributeKvEntry>> getAttributeKvEntries(DeviceId deviceId, String scope, Optional<Set<String>> names) { private ListenableFuture<List<AttributeKvEntry>> getAttributeKvEntries(DeviceId deviceId, String scope, Optional<Set<String>> names) {
if (names.isPresent()) { if (names.isPresent()) {
if (!names.get().isEmpty()) { if (!names.get().isEmpty()) {
return systemContext.getAttributesService().find(deviceId, scope, names.get()); return systemContext.getAttributesService().find(tenantId, deviceId, scope, names.get());
} else { } else {
return systemContext.getAttributesService().findAll(deviceId, scope); return systemContext.getAttributesService().findAll(tenantId, deviceId, scope);
} }
} else { } else {
return Futures.immediateFuture(Collections.emptyList()); return Futures.immediateFuture(Collections.emptyList());

10
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java

@ -90,9 +90,9 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
@Override @Override
public void start(ActorContext context) { public void start(ActorContext context) {
if (!started) { if (!started) {
RuleChain ruleChain = service.findRuleChainById(entityId); RuleChain ruleChain = service.findRuleChainById(tenantId, entityId);
ruleChainName = ruleChain.getName(); ruleChainName = ruleChain.getName();
List<RuleNode> ruleNodeList = service.getRuleChainNodes(entityId); List<RuleNode> ruleNodeList = service.getRuleChainNodes(tenantId, entityId);
log.trace("[{}][{}] Starting rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); log.trace("[{}][{}] Starting rule chain with {} nodes", tenantId, entityId, ruleNodeList.size());
// Creating and starting the actors; // Creating and starting the actors;
for (RuleNode ruleNode : ruleNodeList) { for (RuleNode ruleNode : ruleNodeList) {
@ -109,9 +109,9 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
@Override @Override
public void onUpdate(ActorContext context) { public void onUpdate(ActorContext context) {
RuleChain ruleChain = service.findRuleChainById(entityId); RuleChain ruleChain = service.findRuleChainById(tenantId, entityId);
ruleChainName = ruleChain.getName(); ruleChainName = ruleChain.getName();
List<RuleNode> ruleNodeList = service.getRuleChainNodes(entityId); List<RuleNode> ruleNodeList = service.getRuleChainNodes(tenantId, entityId);
log.trace("[{}][{}] Updating rule chain with {} nodes", tenantId, entityId, ruleNodeList.size()); log.trace("[{}][{}] Updating rule chain with {} nodes", tenantId, entityId, ruleNodeList.size());
for (RuleNode ruleNode : ruleNodeList) { for (RuleNode ruleNode : ruleNodeList) {
RuleNodeCtx existing = nodeActors.get(ruleNode.getId()); RuleNodeCtx existing = nodeActors.get(ruleNode.getId());
@ -164,7 +164,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
nodeRoutes.clear(); nodeRoutes.clear();
// Populating the routes map; // Populating the routes map;
for (RuleNode ruleNode : ruleNodeList) { for (RuleNode ruleNode : ruleNodeList) {
List<EntityRelation> relations = service.getRuleNodeRelations(ruleNode.getId()); List<EntityRelation> relations = service.getRuleNodeRelations(TenantId.SYS_TENANT_ID, ruleNode.getId());
log.trace("[{}][{}][{}] Processing rule node relations [{}]", tenantId, entityId, ruleNode.getId(), relations.size()); log.trace("[{}][{}][{}] Processing rule node relations [{}]", tenantId, entityId, ruleNode.getId(), relations.size());
if (relations.size() == 0) { if (relations.size() == 0) {
nodeRoutes.put(ruleNode.getId(), Collections.emptyList()); nodeRoutes.put(ruleNode.getId(), Collections.emptyList());

4
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java

@ -49,7 +49,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
this.parent = parent; this.parent = parent;
this.self = self; this.self = self;
this.service = systemContext.getRuleChainService(); this.service = systemContext.getRuleChainService();
this.ruleNode = systemContext.getRuleChainService().findRuleNodeById(entityId); this.ruleNode = systemContext.getRuleChainService().findRuleNodeById(tenantId, entityId);
this.defaultCtx = new DefaultTbContext(systemContext, new RuleNodeCtx(tenantId, parent, self, ruleNode)); this.defaultCtx = new DefaultTbContext(systemContext, new RuleNodeCtx(tenantId, parent, self, ruleNode));
} }
@ -61,7 +61,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor<RuleNod
@Override @Override
public void onUpdate(ActorContext context) throws Exception { public void onUpdate(ActorContext context) throws Exception {
RuleNode newRuleNode = systemContext.getRuleChainService().findRuleNodeById(entityId); RuleNode newRuleNode = systemContext.getRuleChainService().findRuleNodeById(tenantId, entityId);
boolean restartRequired = !(ruleNode.getType().equals(newRuleNode.getType()) boolean restartRequired = !(ruleNode.getType().equals(newRuleNode.getType())
&& ruleNode.getConfiguration().equals(newRuleNode.getConfiguration())); && ruleNode.getConfiguration().equals(newRuleNode.getConfiguration()));
this.ruleNode = newRuleNode; this.ruleNode = newRuleNode;

2
application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java

@ -143,7 +143,7 @@ public class TenantActor extends RuleChainManagerActor {
if (target != null) { if (target != null) {
if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) { if (msg.getEntityId().getEntityType() == EntityType.RULE_CHAIN) {
RuleChain ruleChain = systemContext.getRuleChainService(). RuleChain ruleChain = systemContext.getRuleChainService().
findRuleChainById(new RuleChainId(msg.getEntityId().getId())); findRuleChainById(tenantId, new RuleChainId(msg.getEntityId().getId()));
ruleChainManager.visit(ruleChain, target); ruleChainManager.visit(ruleChain, target);
} }
target.tell(msg, ActorRef.noSender()); target.tell(msg, ActorRef.noSender());

5
application/src/main/java/org/thingsboard/server/controller/AdminController.java

@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.service.update.UpdateService; import org.thingsboard.server.service.update.UpdateService;
import org.thingsboard.server.service.update.model.UpdateMessage; import org.thingsboard.server.service.update.model.UpdateMessage;
@ -48,7 +49,7 @@ public class AdminController extends BaseController {
@ResponseBody @ResponseBody
public AdminSettings getAdminSettings(@PathVariable("key") String key) throws ThingsboardException { public AdminSettings getAdminSettings(@PathVariable("key") String key) throws ThingsboardException {
try { try {
return checkNotNull(adminSettingsService.findAdminSettingsByKey(key)); return checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key));
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -59,7 +60,7 @@ public class AdminController extends BaseController {
@ResponseBody @ResponseBody
public AdminSettings saveAdminSettings(@RequestBody AdminSettings adminSettings) throws ThingsboardException { public AdminSettings saveAdminSettings(@RequestBody AdminSettings adminSettings) throws ThingsboardException {
try { try {
adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(adminSettings)); adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings));
if (adminSettings.getKey().equals("mail")) { if (adminSettings.getKey().equals("mail")) {
mailService.updateMailConfiguration(); mailService.updateMailConfiguration();
} }

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

@ -100,7 +100,7 @@ public class AlarmController extends BaseController {
try { try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
Alarm alarm = checkAlarmId(alarmId); Alarm alarm = checkAlarmId(alarmId);
alarmService.ackAlarm(alarmId, System.currentTimeMillis()).get(); alarmService.ackAlarm(getCurrentUser().getTenantId(), alarmId, System.currentTimeMillis()).get();
logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null); logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
@ -115,7 +115,7 @@ public class AlarmController extends BaseController {
try { try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
Alarm alarm = checkAlarmId(alarmId); Alarm alarm = checkAlarmId(alarmId);
alarmService.clearAlarm(alarmId, null, System.currentTimeMillis()).get(); alarmService.clearAlarm(getCurrentUser().getTenantId(), alarmId, null, System.currentTimeMillis()).get();
logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null); logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
@ -149,7 +149,7 @@ public class AlarmController extends BaseController {
checkEntityId(entityId); checkEntityId(entityId);
try { try {
TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset);
return checkNotNull(alarmService.findAlarms(new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator)).get()); return checkNotNull(alarmService.findAlarms(getCurrentUser().getTenantId(), new AlarmQuery(entityId, pageLink, alarmSearchStatus, alarmStatus, fetchOriginator)).get());
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -175,7 +175,7 @@ public class AlarmController extends BaseController {
} }
checkEntityId(entityId); checkEntityId(entityId);
try { try {
return alarmService.findHighestAlarmSeverity(entityId, alarmSearchStatus, alarmStatus); return alarmService.findHighestAlarmSeverity(getCurrentUser().getTenantId(), entityId, alarmSearchStatus, alarmStatus);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }

10
application/src/main/java/org/thingsboard/server/controller/AssetController.java

@ -104,7 +104,7 @@ public class AssetController extends BaseController {
try { try {
AssetId assetId = new AssetId(toUUID(strAssetId)); AssetId assetId = new AssetId(toUUID(strAssetId));
Asset asset = checkAssetId(assetId); Asset asset = checkAssetId(assetId);
assetService.deleteAsset(assetId); assetService.deleteAsset(getTenantId(), assetId);
logEntityAction(assetId, asset, logEntityAction(assetId, asset,
asset.getCustomerId(), asset.getCustomerId(),
@ -133,7 +133,7 @@ public class AssetController extends BaseController {
AssetId assetId = new AssetId(toUUID(strAssetId)); AssetId assetId = new AssetId(toUUID(strAssetId));
checkAssetId(assetId); checkAssetId(assetId);
Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(assetId, customerId)); Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(getTenantId(), assetId, customerId));
logEntityAction(assetId, savedAsset, logEntityAction(assetId, savedAsset,
savedAsset.getCustomerId(), savedAsset.getCustomerId(),
@ -164,7 +164,7 @@ public class AssetController extends BaseController {
Customer customer = checkCustomerId(asset.getCustomerId()); Customer customer = checkCustomerId(asset.getCustomerId());
Asset savedAsset = checkNotNull(assetService.unassignAssetFromCustomer(assetId)); Asset savedAsset = checkNotNull(assetService.unassignAssetFromCustomer(getTenantId(), assetId));
logEntityAction(assetId, asset, logEntityAction(assetId, asset,
asset.getCustomerId(), asset.getCustomerId(),
@ -190,7 +190,7 @@ public class AssetController extends BaseController {
AssetId assetId = new AssetId(toUUID(strAssetId)); AssetId assetId = new AssetId(toUUID(strAssetId));
Asset asset = checkAssetId(assetId); Asset asset = checkAssetId(assetId);
Customer publicCustomer = customerService.findOrCreatePublicCustomer(asset.getTenantId()); Customer publicCustomer = customerService.findOrCreatePublicCustomer(asset.getTenantId());
Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(assetId, publicCustomer.getId())); Asset savedAsset = checkNotNull(assetService.assignAssetToCustomer(getTenantId(), assetId, publicCustomer.getId()));
logEntityAction(assetId, savedAsset, logEntityAction(assetId, savedAsset,
savedAsset.getCustomerId(), savedAsset.getCustomerId(),
@ -303,7 +303,7 @@ public class AssetController extends BaseController {
checkNotNull(query.getAssetTypes()); checkNotNull(query.getAssetTypes());
checkEntityId(query.getParameters().getEntityId()); checkEntityId(query.getParameters().getEntityId());
try { try {
List<Asset> assets = checkNotNull(assetService.findAssetsByQuery(query).get()); List<Asset> assets = checkNotNull(assetService.findAssetsByQuery(getTenantId(), query).get());
assets = assets.stream().filter(asset -> { assets = assets.stream().filter(asset -> {
try { try {
checkAsset(asset); checkAsset(asset);

25
application/src/main/java/org/thingsboard/server/controller/AuthController.java

@ -36,6 +36,7 @@ import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository; import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.SecurityUser;
@ -52,8 +53,6 @@ import java.net.URISyntaxException;
@Slf4j @Slf4j
public class AuthController extends BaseController { public class AuthController extends BaseController {
@Autowired @Autowired
private BCryptPasswordEncoder passwordEncoder; private BCryptPasswordEncoder passwordEncoder;
@ -71,7 +70,7 @@ public class AuthController extends BaseController {
public @ResponseBody User getUser() throws ThingsboardException { public @ResponseBody User getUser() throws ThingsboardException {
try { try {
SecurityUser securityUser = getCurrentUser(); SecurityUser securityUser = getCurrentUser();
return userService.findUserById(securityUser.getId()); return userService.findUserById(securityUser.getTenantId(), securityUser.getId());
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -86,12 +85,12 @@ public class AuthController extends BaseController {
String currentPassword = changePasswordRequest.get("currentPassword").asText(); String currentPassword = changePasswordRequest.get("currentPassword").asText();
String newPassword = changePasswordRequest.get("newPassword").asText(); String newPassword = changePasswordRequest.get("newPassword").asText();
SecurityUser securityUser = getCurrentUser(); SecurityUser securityUser = getCurrentUser();
UserCredentials userCredentials = userService.findUserCredentialsByUserId(securityUser.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, securityUser.getId());
if (!passwordEncoder.matches(currentPassword, userCredentials.getPassword())) { if (!passwordEncoder.matches(currentPassword, userCredentials.getPassword())) {
throw new ThingsboardException("Current password doesn't match!", ThingsboardErrorCode.BAD_REQUEST_PARAMS); throw new ThingsboardException("Current password doesn't match!", ThingsboardErrorCode.BAD_REQUEST_PARAMS);
} }
userCredentials.setPassword(passwordEncoder.encode(newPassword)); userCredentials.setPassword(passwordEncoder.encode(newPassword));
userService.saveUserCredentials(userCredentials); userService.saveUserCredentials(securityUser.getTenantId(), userCredentials);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -102,7 +101,7 @@ public class AuthController extends BaseController {
@RequestParam(value = "activateToken") String activateToken) { @RequestParam(value = "activateToken") String activateToken) {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
HttpStatus responseStatus; HttpStatus responseStatus;
UserCredentials userCredentials = userService.findUserCredentialsByActivateToken(activateToken); UserCredentials userCredentials = userService.findUserCredentialsByActivateToken(TenantId.SYS_TENANT_ID, activateToken);
if (userCredentials != null) { if (userCredentials != null) {
String createURI = "/login/createPassword"; String createURI = "/login/createPassword";
try { try {
@ -126,7 +125,7 @@ public class AuthController extends BaseController {
HttpServletRequest request) throws ThingsboardException { HttpServletRequest request) throws ThingsboardException {
try { try {
String email = resetPasswordByEmailRequest.get("email").asText(); String email = resetPasswordByEmailRequest.get("email").asText();
UserCredentials userCredentials = userService.requestPasswordReset(email); UserCredentials userCredentials = userService.requestPasswordReset(TenantId.SYS_TENANT_ID, email);
String baseUrl = constructBaseUrl(request); String baseUrl = constructBaseUrl(request);
String resetUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl, String resetUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl,
userCredentials.getResetToken()); userCredentials.getResetToken());
@ -143,7 +142,7 @@ public class AuthController extends BaseController {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
HttpStatus responseStatus; HttpStatus responseStatus;
String resetURI = "/login/resetPassword"; String resetURI = "/login/resetPassword";
UserCredentials userCredentials = userService.findUserCredentialsByResetToken(resetToken); UserCredentials userCredentials = userService.findUserCredentialsByResetToken(TenantId.SYS_TENANT_ID, resetToken);
if (userCredentials != null) { if (userCredentials != null) {
try { try {
URI location = new URI(resetURI + "?resetToken=" + resetToken); URI location = new URI(resetURI + "?resetToken=" + resetToken);
@ -169,8 +168,8 @@ public class AuthController extends BaseController {
String activateToken = activateRequest.get("activateToken").asText(); String activateToken = activateRequest.get("activateToken").asText();
String password = activateRequest.get("password").asText(); String password = activateRequest.get("password").asText();
String encodedPassword = passwordEncoder.encode(password); String encodedPassword = passwordEncoder.encode(password);
UserCredentials credentials = userService.activateUserCredentials(activateToken, encodedPassword); UserCredentials credentials = userService.activateUserCredentials(TenantId.SYS_TENANT_ID, activateToken, encodedPassword);
User user = userService.findUserById(credentials.getUserId()); User user = userService.findUserById(TenantId.SYS_TENANT_ID, credentials.getUserId());
UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail()); UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
SecurityUser securityUser = new SecurityUser(user, credentials.isEnabled(), principal); SecurityUser securityUser = new SecurityUser(user, credentials.isEnabled(), principal);
String baseUrl = constructBaseUrl(request); String baseUrl = constructBaseUrl(request);
@ -205,13 +204,13 @@ public class AuthController extends BaseController {
try { try {
String resetToken = resetPasswordRequest.get("resetToken").asText(); String resetToken = resetPasswordRequest.get("resetToken").asText();
String password = resetPasswordRequest.get("password").asText(); String password = resetPasswordRequest.get("password").asText();
UserCredentials userCredentials = userService.findUserCredentialsByResetToken(resetToken); UserCredentials userCredentials = userService.findUserCredentialsByResetToken(TenantId.SYS_TENANT_ID, resetToken);
if (userCredentials != null) { if (userCredentials != null) {
String encodedPassword = passwordEncoder.encode(password); String encodedPassword = passwordEncoder.encode(password);
userCredentials.setPassword(encodedPassword); userCredentials.setPassword(encodedPassword);
userCredentials.setResetToken(null); userCredentials.setResetToken(null);
userCredentials = userService.saveUserCredentials(userCredentials); userCredentials = userService.saveUserCredentials(TenantId.SYS_TENANT_ID, userCredentials);
User user = userService.findUserById(userCredentials.getUserId()); User user = userService.findUserById(TenantId.SYS_TENANT_ID, userCredentials.getUserId());
UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail()); UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
SecurityUser securityUser = new SecurityUser(user, userCredentials.isEnabled(), principal); SecurityUser securityUser = new SecurityUser(user, userCredentials.isEnabled(), principal);
String baseUrl = constructBaseUrl(request); String baseUrl = constructBaseUrl(request);

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

@ -275,7 +275,7 @@ public abstract class BaseController {
ThingsboardErrorCode.PERMISSION_DENIED); ThingsboardErrorCode.PERMISSION_DENIED);
} }
if (customerId != null && !customerId.isNullUid()) { if (customerId != null && !customerId.isNullUid()) {
Customer customer = customerService.findCustomerById(customerId); Customer customer = customerService.findCustomerById(authUser.getTenantId(), customerId);
checkCustomer(customer); checkCustomer(customer);
return customer; return customer;
} else { } else {
@ -294,7 +294,7 @@ public abstract class BaseController {
User checkUserId(UserId userId) throws ThingsboardException { User checkUserId(UserId userId) throws ThingsboardException {
try { try {
validateId(userId, "Incorrect userId " + userId); validateId(userId, "Incorrect userId " + userId);
User user = userService.findUserById(userId); User user = userService.findUserById(getCurrentUser().getTenantId(), userId);
checkUser(user); checkUser(user);
return user; return user;
} catch (Exception e) { } catch (Exception e) {
@ -314,9 +314,10 @@ public abstract class BaseController {
try { try {
checkNotNull(entityId); checkNotNull(entityId);
validateId(entityId.getId(), "Incorrect entityId " + entityId); validateId(entityId.getId(), "Incorrect entityId " + entityId);
SecurityUser authUser = getCurrentUser();
switch (entityId.getEntityType()) { switch (entityId.getEntityType()) {
case DEVICE: case DEVICE:
checkDevice(deviceService.findDeviceById(new DeviceId(entityId.getId()))); checkDevice(deviceService.findDeviceById(authUser.getTenantId(), new DeviceId(entityId.getId())));
return; return;
case CUSTOMER: case CUSTOMER:
checkCustomerId(new CustomerId(entityId.getId())); checkCustomerId(new CustomerId(entityId.getId()));
@ -328,7 +329,7 @@ public abstract class BaseController {
checkRuleChain(new RuleChainId(entityId.getId())); checkRuleChain(new RuleChainId(entityId.getId()));
return; return;
case ASSET: case ASSET:
checkAsset(assetService.findAssetById(new AssetId(entityId.getId()))); checkAsset(assetService.findAssetById(authUser.getTenantId(), new AssetId(entityId.getId())));
return; return;
case DASHBOARD: case DASHBOARD:
checkDashboardId(new DashboardId(entityId.getId())); checkDashboardId(new DashboardId(entityId.getId()));
@ -350,7 +351,7 @@ public abstract class BaseController {
Device checkDeviceId(DeviceId deviceId) throws ThingsboardException { Device checkDeviceId(DeviceId deviceId) throws ThingsboardException {
try { try {
validateId(deviceId, "Incorrect deviceId " + deviceId); validateId(deviceId, "Incorrect deviceId " + deviceId);
Device device = deviceService.findDeviceById(deviceId); Device device = deviceService.findDeviceById(getCurrentUser().getTenantId(), deviceId);
checkDevice(device); checkDevice(device);
return device; return device;
} catch (Exception e) { } catch (Exception e) {
@ -367,7 +368,7 @@ public abstract class BaseController {
protected EntityView checkEntityViewId(EntityViewId entityViewId) throws ThingsboardException { protected EntityView checkEntityViewId(EntityViewId entityViewId) throws ThingsboardException {
try { try {
validateId(entityViewId, "Incorrect entityViewId " + entityViewId); validateId(entityViewId, "Incorrect entityViewId " + entityViewId);
EntityView entityView = entityViewService.findEntityViewById(entityViewId); EntityView entityView = entityViewService.findEntityViewById(getCurrentUser().getTenantId(), entityViewId);
checkEntityView(entityView); checkEntityView(entityView);
return entityView; return entityView;
} catch (Exception e) { } catch (Exception e) {
@ -384,7 +385,7 @@ public abstract class BaseController {
Asset checkAssetId(AssetId assetId) throws ThingsboardException { Asset checkAssetId(AssetId assetId) throws ThingsboardException {
try { try {
validateId(assetId, "Incorrect assetId " + assetId); validateId(assetId, "Incorrect assetId " + assetId);
Asset asset = assetService.findAssetById(assetId); Asset asset = assetService.findAssetById(getCurrentUser().getTenantId(), assetId);
checkAsset(asset); checkAsset(asset);
return asset; return asset;
} catch (Exception e) { } catch (Exception e) {
@ -401,7 +402,7 @@ public abstract class BaseController {
Alarm checkAlarmId(AlarmId alarmId) throws ThingsboardException { Alarm checkAlarmId(AlarmId alarmId) throws ThingsboardException {
try { try {
validateId(alarmId, "Incorrect alarmId " + alarmId); validateId(alarmId, "Incorrect alarmId " + alarmId);
Alarm alarm = alarmService.findAlarmByIdAsync(alarmId).get(); Alarm alarm = alarmService.findAlarmByIdAsync(getCurrentUser().getTenantId(), alarmId).get();
checkAlarm(alarm); checkAlarm(alarm);
return alarm; return alarm;
} catch (Exception e) { } catch (Exception e) {
@ -412,7 +413,7 @@ public abstract class BaseController {
AlarmInfo checkAlarmInfoId(AlarmId alarmId) throws ThingsboardException { AlarmInfo checkAlarmInfoId(AlarmId alarmId) throws ThingsboardException {
try { try {
validateId(alarmId, "Incorrect alarmId " + alarmId); validateId(alarmId, "Incorrect alarmId " + alarmId);
AlarmInfo alarmInfo = alarmService.findAlarmInfoByIdAsync(alarmId).get(); AlarmInfo alarmInfo = alarmService.findAlarmInfoByIdAsync(getCurrentUser().getTenantId(), alarmId).get();
checkAlarm(alarmInfo); checkAlarm(alarmInfo);
return alarmInfo; return alarmInfo;
} catch (Exception e) { } catch (Exception e) {
@ -428,7 +429,7 @@ public abstract class BaseController {
WidgetsBundle checkWidgetsBundleId(WidgetsBundleId widgetsBundleId, boolean modify) throws ThingsboardException { WidgetsBundle checkWidgetsBundleId(WidgetsBundleId widgetsBundleId, boolean modify) throws ThingsboardException {
try { try {
validateId(widgetsBundleId, "Incorrect widgetsBundleId " + widgetsBundleId); validateId(widgetsBundleId, "Incorrect widgetsBundleId " + widgetsBundleId);
WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleById(widgetsBundleId); WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleById(getCurrentUser().getTenantId(), widgetsBundleId);
checkWidgetsBundle(widgetsBundle, modify); checkWidgetsBundle(widgetsBundle, modify);
return widgetsBundle; return widgetsBundle;
} catch (Exception e) { } catch (Exception e) {
@ -449,7 +450,7 @@ public abstract class BaseController {
WidgetType checkWidgetTypeId(WidgetTypeId widgetTypeId, boolean modify) throws ThingsboardException { WidgetType checkWidgetTypeId(WidgetTypeId widgetTypeId, boolean modify) throws ThingsboardException {
try { try {
validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId); validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId);
WidgetType widgetType = widgetTypeService.findWidgetTypeById(widgetTypeId); WidgetType widgetType = widgetTypeService.findWidgetTypeById(getCurrentUser().getTenantId(), widgetTypeId);
checkWidgetType(widgetType, modify); checkWidgetType(widgetType, modify);
return widgetType; return widgetType;
} catch (Exception e) { } catch (Exception e) {
@ -470,7 +471,7 @@ public abstract class BaseController {
Dashboard checkDashboardId(DashboardId dashboardId) throws ThingsboardException { Dashboard checkDashboardId(DashboardId dashboardId) throws ThingsboardException {
try { try {
validateId(dashboardId, "Incorrect dashboardId " + dashboardId); validateId(dashboardId, "Incorrect dashboardId " + dashboardId);
Dashboard dashboard = dashboardService.findDashboardById(dashboardId); Dashboard dashboard = dashboardService.findDashboardById(getCurrentUser().getTenantId(), dashboardId);
checkDashboard(dashboard); checkDashboard(dashboard);
return dashboard; return dashboard;
} catch (Exception e) { } catch (Exception e) {
@ -481,7 +482,7 @@ public abstract class BaseController {
DashboardInfo checkDashboardInfoId(DashboardId dashboardId) throws ThingsboardException { DashboardInfo checkDashboardInfoId(DashboardId dashboardId) throws ThingsboardException {
try { try {
validateId(dashboardId, "Incorrect dashboardId " + dashboardId); validateId(dashboardId, "Incorrect dashboardId " + dashboardId);
DashboardInfo dashboardInfo = dashboardService.findDashboardInfoById(dashboardId); DashboardInfo dashboardInfo = dashboardService.findDashboardInfoById(getCurrentUser().getTenantId(), dashboardId);
checkDashboard(dashboardInfo); checkDashboard(dashboardInfo);
return dashboardInfo; return dashboardInfo;
} catch (Exception e) { } catch (Exception e) {
@ -530,7 +531,7 @@ public abstract class BaseController {
protected RuleChain checkRuleChain(RuleChainId ruleChainId) throws ThingsboardException { protected RuleChain checkRuleChain(RuleChainId ruleChainId) throws ThingsboardException {
checkNotNull(ruleChainId); checkNotNull(ruleChainId);
return checkRuleChain(ruleChainService.findRuleChainById(ruleChainId)); return checkRuleChain(ruleChainService.findRuleChainById(getCurrentUser().getTenantId(), ruleChainId));
} }
protected RuleChain checkRuleChain(RuleChain ruleChain) throws ThingsboardException { protected RuleChain checkRuleChain(RuleChain ruleChain) throws ThingsboardException {

2
application/src/main/java/org/thingsboard/server/controller/CustomerController.java

@ -119,7 +119,7 @@ public class CustomerController extends BaseController {
try { try {
CustomerId customerId = new CustomerId(toUUID(strCustomerId)); CustomerId customerId = new CustomerId(toUUID(strCustomerId));
Customer customer = checkCustomerId(customerId); Customer customer = checkCustomerId(customerId);
customerService.deleteCustomer(customerId); customerService.deleteCustomer(getTenantId(), customerId);
logEntityAction(customerId, customer, logEntityAction(customerId, customer,
customer.getId(), customer.getId(),

18
application/src/main/java/org/thingsboard/server/controller/DashboardController.java

@ -124,7 +124,7 @@ public class DashboardController extends BaseController {
try { try {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
Dashboard dashboard = checkDashboardId(dashboardId); Dashboard dashboard = checkDashboardId(dashboardId);
dashboardService.deleteDashboard(dashboardId); dashboardService.deleteDashboard(getCurrentUser().getTenantId(), dashboardId);
logEntityAction(dashboardId, dashboard, logEntityAction(dashboardId, dashboard,
null, null,
@ -155,7 +155,7 @@ public class DashboardController extends BaseController {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
checkDashboardId(dashboardId); checkDashboardId(dashboardId);
Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(dashboardId, customerId)); Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, customerId));
logEntityAction(dashboardId, savedDashboard, logEntityAction(dashboardId, savedDashboard,
customerId, customerId,
@ -186,7 +186,7 @@ public class DashboardController extends BaseController {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
Dashboard dashboard = checkDashboardId(dashboardId); Dashboard dashboard = checkDashboardId(dashboardId);
Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(dashboardId, customerId)); Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, customerId));
logEntityAction(dashboardId, dashboard, logEntityAction(dashboardId, dashboard,
customerId, customerId,
@ -242,7 +242,7 @@ public class DashboardController extends BaseController {
} else { } else {
Dashboard savedDashboard = null; Dashboard savedDashboard = null;
for (CustomerId customerId : addedCustomerIds) { for (CustomerId customerId : addedCustomerIds) {
savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(dashboardId, customerId)); savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, customerId));
ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId);
logEntityAction(dashboardId, savedDashboard, logEntityAction(dashboardId, savedDashboard,
customerId, customerId,
@ -250,7 +250,7 @@ public class DashboardController extends BaseController {
} }
for (CustomerId customerId : removedCustomerIds) { for (CustomerId customerId : removedCustomerIds) {
ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId);
savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(dashboardId, customerId)); savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, customerId));
logEntityAction(dashboardId, dashboard, logEntityAction(dashboardId, dashboard,
customerId, customerId,
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle());
@ -293,7 +293,7 @@ public class DashboardController extends BaseController {
} else { } else {
Dashboard savedDashboard = null; Dashboard savedDashboard = null;
for (CustomerId customerId : customerIds) { for (CustomerId customerId : customerIds) {
savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(dashboardId, customerId)); savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, customerId));
ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId);
logEntityAction(dashboardId, savedDashboard, logEntityAction(dashboardId, savedDashboard,
customerId, customerId,
@ -337,7 +337,7 @@ public class DashboardController extends BaseController {
Dashboard savedDashboard = null; Dashboard savedDashboard = null;
for (CustomerId customerId : customerIds) { for (CustomerId customerId : customerIds) {
ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId);
savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(dashboardId, customerId)); savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, customerId));
logEntityAction(dashboardId, dashboard, logEntityAction(dashboardId, dashboard,
customerId, customerId,
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle());
@ -364,7 +364,7 @@ public class DashboardController extends BaseController {
DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); DashboardId dashboardId = new DashboardId(toUUID(strDashboardId));
Dashboard dashboard = checkDashboardId(dashboardId); Dashboard dashboard = checkDashboardId(dashboardId);
Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId()); Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId());
Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(dashboardId, publicCustomer.getId())); Dashboard savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(getCurrentUser().getTenantId(), dashboardId, publicCustomer.getId()));
logEntityAction(dashboardId, savedDashboard, logEntityAction(dashboardId, savedDashboard,
publicCustomer.getId(), publicCustomer.getId(),
@ -391,7 +391,7 @@ public class DashboardController extends BaseController {
Dashboard dashboard = checkDashboardId(dashboardId); Dashboard dashboard = checkDashboardId(dashboardId);
Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId()); Customer publicCustomer = customerService.findOrCreatePublicCustomer(dashboard.getTenantId());
Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(dashboardId, publicCustomer.getId())); Dashboard savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(getCurrentUser().getTenantId(), dashboardId, publicCustomer.getId()));
logEntityAction(dashboardId, dashboard, logEntityAction(dashboardId, dashboard,
publicCustomer.getId(), publicCustomer.getId(),

14
application/src/main/java/org/thingsboard/server/controller/DeviceController.java

@ -117,7 +117,7 @@ public class DeviceController extends BaseController {
try { try {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
Device device = checkDeviceId(deviceId); Device device = checkDeviceId(deviceId);
deviceService.deleteDevice(deviceId); deviceService.deleteDevice(getCurrentUser().getTenantId(), deviceId);
logEntityAction(deviceId, device, logEntityAction(deviceId, device,
device.getCustomerId(), device.getCustomerId(),
@ -147,7 +147,7 @@ public class DeviceController extends BaseController {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
checkDeviceId(deviceId); checkDeviceId(deviceId);
Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(deviceId, customerId)); Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(getCurrentUser().getTenantId(), deviceId, customerId));
logEntityAction(deviceId, savedDevice, logEntityAction(deviceId, savedDevice,
savedDevice.getCustomerId(), savedDevice.getCustomerId(),
@ -175,7 +175,7 @@ public class DeviceController extends BaseController {
} }
Customer customer = checkCustomerId(device.getCustomerId()); Customer customer = checkCustomerId(device.getCustomerId());
Device savedDevice = checkNotNull(deviceService.unassignDeviceFromCustomer(deviceId)); Device savedDevice = checkNotNull(deviceService.unassignDeviceFromCustomer(getCurrentUser().getTenantId(), deviceId));
logEntityAction(deviceId, device, logEntityAction(deviceId, device,
device.getCustomerId(), device.getCustomerId(),
@ -199,7 +199,7 @@ public class DeviceController extends BaseController {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
Device device = checkDeviceId(deviceId); Device device = checkDeviceId(deviceId);
Customer publicCustomer = customerService.findOrCreatePublicCustomer(device.getTenantId()); Customer publicCustomer = customerService.findOrCreatePublicCustomer(device.getTenantId());
Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(deviceId, publicCustomer.getId())); Device savedDevice = checkNotNull(deviceService.assignDeviceToCustomer(getCurrentUser().getTenantId(), deviceId, publicCustomer.getId()));
logEntityAction(deviceId, savedDevice, logEntityAction(deviceId, savedDevice,
savedDevice.getCustomerId(), savedDevice.getCustomerId(),
@ -222,7 +222,7 @@ public class DeviceController extends BaseController {
try { try {
DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); DeviceId deviceId = new DeviceId(toUUID(strDeviceId));
Device device = checkDeviceId(deviceId); Device device = checkDeviceId(deviceId);
DeviceCredentials deviceCredentials = checkNotNull(deviceCredentialsService.findDeviceCredentialsByDeviceId(deviceId)); DeviceCredentials deviceCredentials = checkNotNull(deviceCredentialsService.findDeviceCredentialsByDeviceId(getCurrentUser().getTenantId(), deviceId));
logEntityAction(deviceId, device, logEntityAction(deviceId, device,
device.getCustomerId(), device.getCustomerId(),
ActionType.CREDENTIALS_READ, null, strDeviceId); ActionType.CREDENTIALS_READ, null, strDeviceId);
@ -242,7 +242,7 @@ public class DeviceController extends BaseController {
checkNotNull(deviceCredentials); checkNotNull(deviceCredentials);
try { try {
Device device = checkDeviceId(deviceCredentials.getDeviceId()); Device device = checkDeviceId(deviceCredentials.getDeviceId());
DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(deviceCredentials)); DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(getCurrentUser().getTenantId(), deviceCredentials));
actorService.onCredentialsUpdate(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId()); actorService.onCredentialsUpdate(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId());
logEntityAction(device.getId(), device, logEntityAction(device.getId(), device,
device.getCustomerId(), device.getCustomerId(),
@ -352,7 +352,7 @@ public class DeviceController extends BaseController {
checkNotNull(query.getDeviceTypes()); checkNotNull(query.getDeviceTypes());
checkEntityId(query.getParameters().getEntityId()); checkEntityId(query.getParameters().getEntityId());
try { try {
List<Device> devices = checkNotNull(deviceService.findDevicesByQuery(query).get()); List<Device> devices = checkNotNull(deviceService.findDevicesByQuery(getCurrentUser().getTenantId(), query).get());
devices = devices.stream().filter(device -> { devices = devices.stream().filter(device -> {
try { try {
checkDevice(device); checkDevice(device);

24
application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java

@ -60,7 +60,7 @@ public class EntityRelationController extends BaseController {
if (relation.getTypeGroup() == null) { if (relation.getTypeGroup() == null) {
relation.setTypeGroup(RelationTypeGroup.COMMON); relation.setTypeGroup(RelationTypeGroup.COMMON);
} }
relationService.saveRelation(relation); relationService.saveRelation(getTenantId(), relation);
logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_ADD_OR_UPDATE, null, relation); ActionType.RELATION_ADD_OR_UPDATE, null, relation);
logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
@ -94,7 +94,7 @@ public class EntityRelationController extends BaseController {
RelationTypeGroup relationTypeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); RelationTypeGroup relationTypeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
EntityRelation relation = new EntityRelation(fromId, toId, strRelationType, relationTypeGroup); EntityRelation relation = new EntityRelation(fromId, toId, strRelationType, relationTypeGroup);
try { try {
Boolean found = relationService.deleteRelation(fromId, toId, strRelationType, relationTypeGroup); Boolean found = relationService.deleteRelation(getTenantId(), fromId, toId, strRelationType, relationTypeGroup);
if (!found) { if (!found) {
throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND); throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND);
} }
@ -121,7 +121,7 @@ public class EntityRelationController extends BaseController {
EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId); EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId);
checkEntityId(entityId); checkEntityId(entityId);
try { try {
relationService.deleteEntityRelations(entityId); relationService.deleteEntityRelations(getTenantId(), entityId);
logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null); logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null);
} catch (Exception e) { } catch (Exception e) {
logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, e); logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, e);
@ -148,7 +148,7 @@ public class EntityRelationController extends BaseController {
checkEntityId(fromId); checkEntityId(fromId);
checkEntityId(toId); checkEntityId(toId);
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
return checkNotNull(relationService.getRelation(fromId, toId, strRelationType, typeGroup)); return checkNotNull(relationService.getRelation(getTenantId(), fromId, toId, strRelationType, typeGroup));
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -166,7 +166,7 @@ public class EntityRelationController extends BaseController {
checkEntityId(entityId); checkEntityId(entityId);
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
try { try {
return checkNotNull(relationService.findByFrom(entityId, typeGroup)); return checkNotNull(relationService.findByFrom(getTenantId(), entityId, typeGroup));
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -184,7 +184,7 @@ public class EntityRelationController extends BaseController {
checkEntityId(entityId); checkEntityId(entityId);
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
try { try {
return checkNotNull(relationService.findInfoByFrom(entityId, typeGroup).get()); return checkNotNull(relationService.findInfoByFrom(getTenantId(), entityId, typeGroup).get());
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -204,7 +204,7 @@ public class EntityRelationController extends BaseController {
checkEntityId(entityId); checkEntityId(entityId);
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
try { try {
return checkNotNull(relationService.findByFromAndType(entityId, strRelationType, typeGroup)); return checkNotNull(relationService.findByFromAndType(getTenantId(), entityId, strRelationType, typeGroup));
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -222,7 +222,7 @@ public class EntityRelationController extends BaseController {
checkEntityId(entityId); checkEntityId(entityId);
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
try { try {
return checkNotNull(relationService.findByTo(entityId, typeGroup)); return checkNotNull(relationService.findByTo(getTenantId(), entityId, typeGroup));
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -240,7 +240,7 @@ public class EntityRelationController extends BaseController {
checkEntityId(entityId); checkEntityId(entityId);
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
try { try {
return checkNotNull(relationService.findInfoByTo(entityId, typeGroup).get()); return checkNotNull(relationService.findInfoByTo(getTenantId(), entityId, typeGroup).get());
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -260,7 +260,7 @@ public class EntityRelationController extends BaseController {
checkEntityId(entityId); checkEntityId(entityId);
RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
try { try {
return checkNotNull(relationService.findByToAndType(entityId, strRelationType, typeGroup)); return checkNotNull(relationService.findByToAndType(getTenantId(), entityId, strRelationType, typeGroup));
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -275,7 +275,7 @@ public class EntityRelationController extends BaseController {
checkNotNull(query.getFilters()); checkNotNull(query.getFilters());
checkEntityId(query.getParameters().getEntityId()); checkEntityId(query.getParameters().getEntityId());
try { try {
return checkNotNull(relationService.findByQuery(query).get()); return checkNotNull(relationService.findByQuery(getTenantId(), query).get());
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -290,7 +290,7 @@ public class EntityRelationController extends BaseController {
checkNotNull(query.getFilters()); checkNotNull(query.getFilters());
checkEntityId(query.getParameters().getEntityId()); checkEntityId(query.getParameters().getEntityId());
try { try {
return checkNotNull(relationService.findInfoByQuery(query).get()); return checkNotNull(relationService.findInfoByQuery(getTenantId(), query).get());
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }

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

@ -114,7 +114,7 @@ public class EntityViewController extends BaseController {
private ListenableFuture<List<Void>> copyAttributesFromEntityToEntityView(EntityView entityView, String scope, Collection<String> keys, SecurityUser user) throws ThingsboardException { private ListenableFuture<List<Void>> copyAttributesFromEntityToEntityView(EntityView entityView, String scope, Collection<String> keys, SecurityUser user) throws ThingsboardException {
EntityViewId entityId = entityView.getId(); EntityViewId entityId = entityView.getId();
if (keys != null && !keys.isEmpty()) { if (keys != null && !keys.isEmpty()) {
ListenableFuture<List<AttributeKvEntry>> getAttrFuture = attributesService.find(entityView.getEntityId(), scope, keys); ListenableFuture<List<AttributeKvEntry>> getAttrFuture = attributesService.find(getTenantId(), entityView.getEntityId(), scope, keys);
return Futures.transform(getAttrFuture, attributeKvEntries -> { return Futures.transform(getAttrFuture, attributeKvEntries -> {
List<AttributeKvEntry> attributes; List<AttributeKvEntry> attributes;
if (attributeKvEntries != null && !attributeKvEntries.isEmpty()) { if (attributeKvEntries != null && !attributeKvEntries.isEmpty()) {
@ -129,7 +129,7 @@ public class EntityViewController extends BaseController {
(startTime == 0 && endTime > lastUpdateTs) (startTime == 0 && endTime > lastUpdateTs)
? true : startTime < lastUpdateTs && endTime > lastUpdateTs; ? true : startTime < lastUpdateTs && endTime > lastUpdateTs;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
tsSubService.saveAndNotify(entityId, scope, attributes, new FutureCallback<Void>() { tsSubService.saveAndNotify(entityView.getTenantId(), entityId, scope, attributes, new FutureCallback<Void>() {
@Override @Override
public void onSuccess(@Nullable Void tmp) { public void onSuccess(@Nullable Void tmp) {
try { try {
@ -169,7 +169,7 @@ public class EntityViewController extends BaseController {
try { try {
EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
EntityView entityView = checkEntityViewId(entityViewId); EntityView entityView = checkEntityViewId(entityViewId);
entityViewService.deleteEntityView(entityViewId); entityViewService.deleteEntityView(getTenantId(), entityViewId);
logEntityAction(entityViewId, entityView, entityView.getCustomerId(), logEntityAction(entityViewId, entityView, entityView.getCustomerId(),
ActionType.DELETED, null, strEntityViewId); ActionType.DELETED, null, strEntityViewId);
} catch (Exception e) { } catch (Exception e) {
@ -208,7 +208,7 @@ public class EntityViewController extends BaseController {
EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId));
checkEntityViewId(entityViewId); checkEntityViewId(entityViewId);
EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToCustomer(entityViewId, customerId)); EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToCustomer(getTenantId(), entityViewId, customerId));
logEntityAction(entityViewId, savedEntityView, logEntityAction(entityViewId, savedEntityView,
savedEntityView.getCustomerId(), savedEntityView.getCustomerId(),
ActionType.ASSIGNED_TO_CUSTOMER, null, strEntityViewId, strCustomerId, customer.getName()); ActionType.ASSIGNED_TO_CUSTOMER, null, strEntityViewId, strCustomerId, customer.getName());
@ -233,7 +233,7 @@ public class EntityViewController extends BaseController {
throw new IncorrectParameterException("Entity View isn't assigned to any customer!"); throw new IncorrectParameterException("Entity View isn't assigned to any customer!");
} }
Customer customer = checkCustomerId(entityView.getCustomerId()); Customer customer = checkCustomerId(entityView.getCustomerId());
EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromCustomer(entityViewId)); EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromCustomer(getTenantId(), entityViewId));
logEntityAction(entityViewId, entityView, logEntityAction(entityViewId, entityView,
entityView.getCustomerId(), entityView.getCustomerId(),
ActionType.UNASSIGNED_FROM_CUSTOMER, null, strEntityViewId, customer.getId().toString(), customer.getName()); ActionType.UNASSIGNED_FROM_CUSTOMER, null, strEntityViewId, customer.getId().toString(), customer.getName());
@ -305,7 +305,7 @@ public class EntityViewController extends BaseController {
checkNotNull(query.getEntityViewTypes()); checkNotNull(query.getEntityViewTypes());
checkEntityId(query.getParameters().getEntityId()); checkEntityId(query.getParameters().getEntityId());
try { try {
List<EntityView> entityViews = checkNotNull(entityViewService.findEntityViewsByQuery(query).get()); List<EntityView> entityViews = checkNotNull(entityViewService.findEntityViewsByQuery(getTenantId(), query).get());
entityViews = entityViews.stream().filter(entityView -> { entityViews = entityViews.stream().filter(entityView -> {
try { try {
checkEntityView(entityView); checkEntityView(entityView);

12
application/src/main/java/org/thingsboard/server/controller/RuleChainController.java

@ -94,7 +94,7 @@ public class RuleChainController extends BaseController {
try { try {
RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId));
checkRuleChain(ruleChainId); checkRuleChain(ruleChainId);
return ruleChainService.loadRuleChainMetaData(ruleChainId); return ruleChainService.loadRuleChainMetaData(getTenantId(), ruleChainId);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -137,9 +137,9 @@ public class RuleChainController extends BaseController {
RuleChain ruleChain = checkRuleChain(ruleChainId); RuleChain ruleChain = checkRuleChain(ruleChainId);
TenantId tenantId = getCurrentUser().getTenantId(); TenantId tenantId = getCurrentUser().getTenantId();
RuleChain previousRootRuleChain = ruleChainService.getRootTenantRuleChain(tenantId); RuleChain previousRootRuleChain = ruleChainService.getRootTenantRuleChain(tenantId);
if (ruleChainService.setRootRuleChain(ruleChainId)) { if (ruleChainService.setRootRuleChain(getTenantId(), ruleChainId)) {
previousRootRuleChain = ruleChainService.findRuleChainById(previousRootRuleChain.getId()); previousRootRuleChain = ruleChainService.findRuleChainById(getTenantId(), previousRootRuleChain.getId());
actorService.onEntityStateChange(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(), actorService.onEntityStateChange(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(),
ComponentLifecycleEvent.UPDATED); ComponentLifecycleEvent.UPDATED);
@ -147,7 +147,7 @@ public class RuleChainController extends BaseController {
logEntityAction(previousRootRuleChain.getId(), previousRootRuleChain, logEntityAction(previousRootRuleChain.getId(), previousRootRuleChain,
null, ActionType.UPDATED, null); null, ActionType.UPDATED, null);
ruleChain = ruleChainService.findRuleChainById(ruleChainId); ruleChain = ruleChainService.findRuleChainById(getTenantId(), ruleChainId);
actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(),
ComponentLifecycleEvent.UPDATED); ComponentLifecycleEvent.UPDATED);
@ -172,7 +172,7 @@ public class RuleChainController extends BaseController {
public RuleChainMetaData saveRuleChainMetaData(@RequestBody RuleChainMetaData ruleChainMetaData) throws ThingsboardException { public RuleChainMetaData saveRuleChainMetaData(@RequestBody RuleChainMetaData ruleChainMetaData) throws ThingsboardException {
try { try {
RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId()); RuleChain ruleChain = checkRuleChain(ruleChainMetaData.getRuleChainId());
RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.saveRuleChainMetaData(ruleChainMetaData)); RuleChainMetaData savedRuleChainMetaData = checkNotNull(ruleChainService.saveRuleChainMetaData(getTenantId(), ruleChainMetaData));
actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED); actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.UPDATED);
@ -216,7 +216,7 @@ public class RuleChainController extends BaseController {
RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId)); RuleChainId ruleChainId = new RuleChainId(toUUID(strRuleChainId));
RuleChain ruleChain = checkRuleChain(ruleChainId); RuleChain ruleChain = checkRuleChain(ruleChainId);
ruleChainService.deleteRuleChainById(ruleChainId); ruleChainService.deleteRuleChainById(getTenantId(), ruleChainId);
actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.DELETED); actorService.onEntityStateChange(ruleChain.getTenantId(), ruleChain.getId(), ComponentLifecycleEvent.DELETED);

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

@ -44,6 +44,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.kv.Aggregation; import org.thingsboard.server.common.data.kv.Aggregation;
import org.thingsboard.server.common.data.kv.AttributeKey; import org.thingsboard.server.common.data.kv.AttributeKey;
@ -127,7 +128,7 @@ public class TelemetryController extends BaseController {
@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr
, @PathVariable("scope") String scope) throws ThingsboardException { , @PathVariable("scope") String scope) throws ThingsboardException {
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr,
(result, entityId) -> getAttributeKeysCallback(result, entityId, scope)); (result, tenantId, entityId) -> getAttributeKeysCallback(result, tenantId, entityId, scope));
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -138,7 +139,7 @@ public class TelemetryController extends BaseController {
@RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException {
SecurityUser user = getCurrentUser(); SecurityUser user = getCurrentUser();
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr,
(result, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr)); (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, null, keysStr));
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -150,7 +151,7 @@ public class TelemetryController extends BaseController {
@RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException { @RequestParam(name = "keys", required = false) String keysStr) throws ThingsboardException {
SecurityUser user = getCurrentUser(); SecurityUser user = getCurrentUser();
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr,
(result, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr)); (result, tenantId, entityId) -> getAttributeValuesCallback(result, user, entityId, scope, keysStr));
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -159,9 +160,7 @@ public class TelemetryController extends BaseController {
public DeferredResult<ResponseEntity> getTimeseriesKeys( public DeferredResult<ResponseEntity> getTimeseriesKeys(
@PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException { @PathVariable("entityType") String entityType, @PathVariable("entityId") String entityIdStr) throws ThingsboardException {
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr,
(result, entityId) -> { (result, tenantId, entityId) -> Futures.addCallback(tsService.findAllLatest(tenantId, entityId), getTsKeysToResponseCallback(result)));
Futures.addCallback(tsService.findAllLatest(entityId), getTsKeysToResponseCallback(result));
});
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -173,7 +172,7 @@ public class TelemetryController extends BaseController {
SecurityUser user = getCurrentUser(); SecurityUser user = getCurrentUser();
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr,
(result, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keysStr)); (result, tenantId, entityId) -> getLatestTimeseriesValuesCallback(result, user, entityId, keysStr));
} }
@ -190,13 +189,13 @@ public class TelemetryController extends BaseController {
@RequestParam(name = "agg", defaultValue = "NONE") String aggStr @RequestParam(name = "agg", defaultValue = "NONE") String aggStr
) throws ThingsboardException { ) throws ThingsboardException {
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr, return accessValidator.validateEntityAndCallback(getCurrentUser(), entityType, entityIdStr,
(result, entityId) -> { (result, tenantId, entityId) -> {
// If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted // If interval is 0, convert this to a NONE aggregation, which is probably what the user really wanted
Aggregation agg = interval == 0L ? Aggregation.valueOf(Aggregation.NONE.name()) : Aggregation.valueOf(aggStr); Aggregation agg = interval == 0L ? Aggregation.valueOf(Aggregation.NONE.name()) : Aggregation.valueOf(aggStr);
List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg)) List<ReadTsKvQuery> queries = toKeysList(keys).stream().map(key -> new BaseReadTsKvQuery(key, startTs, endTs, interval, limit, agg))
.collect(Collectors.toList()); .collect(Collectors.toList());
Futures.addCallback(tsService.findAll(entityId, queries), getTsKvListCallback(result)); Futures.addCallback(tsService.findAll(tenantId, entityId, queries), getTsKvListCallback(result));
}); });
} }
@ -206,7 +205,7 @@ public class TelemetryController extends BaseController {
public DeferredResult<ResponseEntity> saveDeviceAttributes(@PathVariable("deviceId") String deviceIdStr, @PathVariable("scope") String scope, public DeferredResult<ResponseEntity> saveDeviceAttributes(@PathVariable("deviceId") String deviceIdStr, @PathVariable("scope") String scope,
@RequestBody JsonNode request) throws ThingsboardException { @RequestBody JsonNode request) throws ThingsboardException {
EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr); EntityId entityId = EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE, deviceIdStr);
return saveAttributes(entityId, scope, request); return saveAttributes(getTenantId(), entityId, scope, request);
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -216,7 +215,7 @@ public class TelemetryController extends BaseController {
@PathVariable("scope") String scope, @PathVariable("scope") String scope,
@RequestBody JsonNode request) throws ThingsboardException { @RequestBody JsonNode request) throws ThingsboardException {
EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
return saveAttributes(entityId, scope, request); return saveAttributes(getTenantId(), entityId, scope, request);
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -226,7 +225,7 @@ public class TelemetryController extends BaseController {
@PathVariable("scope") String scope, @PathVariable("scope") String scope,
@RequestBody JsonNode request) throws ThingsboardException { @RequestBody JsonNode request) throws ThingsboardException {
EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
return saveAttributes(entityId, scope, request); return saveAttributes(getTenantId(), entityId, scope, request);
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -236,7 +235,7 @@ public class TelemetryController extends BaseController {
@PathVariable("scope") String scope, @PathVariable("scope") String scope,
@RequestBody String requestBody) throws ThingsboardException { @RequestBody String requestBody) throws ThingsboardException {
EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
return saveTelemetry(entityId, requestBody, 0L); return saveTelemetry(getTenantId(), entityId, requestBody, 0L);
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -246,7 +245,7 @@ public class TelemetryController extends BaseController {
@PathVariable("scope") String scope, @PathVariable("ttl") Long ttl, @PathVariable("scope") String scope, @PathVariable("ttl") Long ttl,
@RequestBody String requestBody) throws ThingsboardException { @RequestBody String requestBody) throws ThingsboardException {
EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr);
return saveTelemetry(entityId, requestBody, ttl); return saveTelemetry(getTenantId(), entityId, requestBody, ttl);
} }
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
@ -280,13 +279,13 @@ public class TelemetryController extends BaseController {
deleteToTs = endTs; deleteToTs = endTs;
} }
return accessValidator.validateEntityAndCallback(user, entityIdStr, (result, entityId) -> { return accessValidator.validateEntityAndCallback(user, entityIdStr, (result, tenantId, entityId) -> {
List<DeleteTsKvQuery> deleteTsKvQueries = new ArrayList<>(); List<DeleteTsKvQuery> deleteTsKvQueries = new ArrayList<>();
for (String key : keys) { for (String key : keys) {
deleteTsKvQueries.add(new BaseDeleteTsKvQuery(key, deleteFromTs, deleteToTs, rewriteLatestIfDeleted)); deleteTsKvQueries.add(new BaseDeleteTsKvQuery(key, deleteFromTs, deleteToTs, rewriteLatestIfDeleted));
} }
ListenableFuture<List<Void>> future = tsService.remove(entityId, deleteTsKvQueries); ListenableFuture<List<Void>> future = tsService.remove(user.getTenantId(), entityId, deleteTsKvQueries);
Futures.addCallback(future, new FutureCallback<List<Void>>() { Futures.addCallback(future, new FutureCallback<List<Void>>() {
@Override @Override
public void onSuccess(@Nullable List<Void> tmp) { public void onSuccess(@Nullable List<Void> tmp) {
@ -333,8 +332,8 @@ public class TelemetryController extends BaseController {
if (DataConstants.SERVER_SCOPE.equals(scope) || if (DataConstants.SERVER_SCOPE.equals(scope) ||
DataConstants.SHARED_SCOPE.equals(scope) || DataConstants.SHARED_SCOPE.equals(scope) ||
DataConstants.CLIENT_SCOPE.equals(scope)) { DataConstants.CLIENT_SCOPE.equals(scope)) {
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdStr, (result, entityId) -> { return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdStr, (result, tenantId, entityId) -> {
ListenableFuture<List<Void>> future = attributesService.removeAll(entityId, scope, keys); ListenableFuture<List<Void>> future = attributesService.removeAll(user.getTenantId(), entityId, scope, keys);
Futures.addCallback(future, new FutureCallback<List<Void>>() { Futures.addCallback(future, new FutureCallback<List<Void>>() {
@Override @Override
public void onSuccess(@Nullable List<Void> tmp) { public void onSuccess(@Nullable List<Void> tmp) {
@ -362,7 +361,7 @@ public class TelemetryController extends BaseController {
} }
} }
private DeferredResult<ResponseEntity> saveAttributes(EntityId entityIdSrc, String scope, JsonNode json) throws ThingsboardException { private DeferredResult<ResponseEntity> saveAttributes(TenantId srcTenantId, EntityId entityIdSrc, String scope, JsonNode json) throws ThingsboardException {
if (!DataConstants.SERVER_SCOPE.equals(scope) && !DataConstants.SHARED_SCOPE.equals(scope)) { if (!DataConstants.SERVER_SCOPE.equals(scope) && !DataConstants.SHARED_SCOPE.equals(scope)) {
return getImmediateDeferredResult("Invalid scope: " + scope, HttpStatus.BAD_REQUEST); return getImmediateDeferredResult("Invalid scope: " + scope, HttpStatus.BAD_REQUEST);
} }
@ -372,8 +371,8 @@ public class TelemetryController extends BaseController {
return getImmediateDeferredResult("No attributes data found in request body!", HttpStatus.BAD_REQUEST); return getImmediateDeferredResult("No attributes data found in request body!", HttpStatus.BAD_REQUEST);
} }
SecurityUser user = getCurrentUser(); SecurityUser user = getCurrentUser();
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdSrc, (result, entityId) -> { return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdSrc, (result, tenantId, entityId) -> {
tsSubService.saveAndNotify(entityId, scope, attributes, new FutureCallback<Void>() { tsSubService.saveAndNotify(tenantId, entityId, scope, attributes, new FutureCallback<Void>() {
@Override @Override
public void onSuccess(@Nullable Void tmp) { public void onSuccess(@Nullable Void tmp) {
logAttributesUpdated(user, entityId, scope, attributes, null); logAttributesUpdated(user, entityId, scope, attributes, null);
@ -398,7 +397,7 @@ public class TelemetryController extends BaseController {
} }
} }
private DeferredResult<ResponseEntity> saveTelemetry(EntityId entityIdSrc, String requestBody, long ttl) throws ThingsboardException { private DeferredResult<ResponseEntity> saveTelemetry(TenantId curTenantId, EntityId entityIdSrc, String requestBody, long ttl) throws ThingsboardException {
Map<Long, List<KvEntry>> telemetryRequest; Map<Long, List<KvEntry>> telemetryRequest;
JsonElement telemetryJson; JsonElement telemetryJson;
try { try {
@ -421,8 +420,8 @@ public class TelemetryController extends BaseController {
return getImmediateDeferredResult("No timeseries data found in request body!", HttpStatus.BAD_REQUEST); return getImmediateDeferredResult("No timeseries data found in request body!", HttpStatus.BAD_REQUEST);
} }
SecurityUser user = getCurrentUser(); SecurityUser user = getCurrentUser();
return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdSrc, (result, entityId) -> { return accessValidator.validateEntityAndCallback(getCurrentUser(), entityIdSrc, (result, tenantId, entityId) -> {
tsSubService.saveAndNotify(entityId, entries, ttl, new FutureCallback<Void>() { tsSubService.saveAndNotify(tenantId, entityId, entries, ttl, new FutureCallback<Void>() {
@Override @Override
public void onSuccess(@Nullable Void tmp) { public void onSuccess(@Nullable Void tmp) {
result.setResult(new ResponseEntity(HttpStatus.OK)); result.setResult(new ResponseEntity(HttpStatus.OK));
@ -439,9 +438,9 @@ public class TelemetryController extends BaseController {
private void getLatestTimeseriesValuesCallback(@Nullable DeferredResult<ResponseEntity> result, SecurityUser user, EntityId entityId, String keys) { private void getLatestTimeseriesValuesCallback(@Nullable DeferredResult<ResponseEntity> result, SecurityUser user, EntityId entityId, String keys) {
ListenableFuture<List<TsKvEntry>> future; ListenableFuture<List<TsKvEntry>> future;
if (StringUtils.isEmpty(keys)) { if (StringUtils.isEmpty(keys)) {
future = tsService.findAllLatest(entityId); future = tsService.findAllLatest(user.getTenantId(), entityId);
} else { } else {
future = tsService.findLatest(entityId, toKeysList(keys)); future = tsService.findLatest(user.getTenantId(), entityId, toKeysList(keys));
} }
Futures.addCallback(future, getTsKvListCallback(result)); Futures.addCallback(future, getTsKvListCallback(result));
} }
@ -451,17 +450,17 @@ public class TelemetryController extends BaseController {
FutureCallback<List<AttributeKvEntry>> callback = getAttributeValuesToResponseCallback(result, user, scope, entityId, keyList); FutureCallback<List<AttributeKvEntry>> callback = getAttributeValuesToResponseCallback(result, user, scope, entityId, keyList);
if (!StringUtils.isEmpty(scope)) { if (!StringUtils.isEmpty(scope)) {
if (keyList != null && !keyList.isEmpty()) { if (keyList != null && !keyList.isEmpty()) {
Futures.addCallback(attributesService.find(entityId, scope, keyList), callback); Futures.addCallback(attributesService.find(user.getTenantId(), entityId, scope, keyList), callback);
} else { } else {
Futures.addCallback(attributesService.findAll(entityId, scope), callback); Futures.addCallback(attributesService.findAll(user.getTenantId(), entityId, scope), callback);
} }
} else { } else {
List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>(); List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>();
for (String tmpScope : DataConstants.allScopes()) { for (String tmpScope : DataConstants.allScopes()) {
if (keyList != null && !keyList.isEmpty()) { if (keyList != null && !keyList.isEmpty()) {
futures.add(attributesService.find(entityId, tmpScope, keyList)); futures.add(attributesService.find(user.getTenantId(), entityId, tmpScope, keyList));
} else { } else {
futures.add(attributesService.findAll(entityId, tmpScope)); futures.add(attributesService.findAll(user.getTenantId(), entityId, tmpScope));
} }
} }
@ -471,14 +470,14 @@ public class TelemetryController extends BaseController {
} }
} }
private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, EntityId entityId, String scope) { private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, TenantId tenantId, EntityId entityId, String scope) {
Futures.addCallback(attributesService.findAll(entityId, scope), getAttributeKeysToResponseCallback(result)); Futures.addCallback(attributesService.findAll(tenantId, entityId, scope), getAttributeKeysToResponseCallback(result));
} }
private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, EntityId entityId) { private void getAttributeKeysCallback(@Nullable DeferredResult<ResponseEntity> result, TenantId tenantId, EntityId entityId) {
List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>(); List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>();
for (String scope : DataConstants.allScopes()) { for (String scope : DataConstants.allScopes()) {
futures.add(attributesService.findAll(entityId, scope)); futures.add(attributesService.findAll(tenantId, entityId, scope));
} }
ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures); ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);

16
application/src/main/java/org/thingsboard/server/controller/UserController.java

@ -107,14 +107,14 @@ public class UserController extends BaseController {
try { try {
UserId userId = new UserId(toUUID(strUserId)); UserId userId = new UserId(toUUID(strUserId));
SecurityUser authUser = getCurrentUser(); SecurityUser authUser = getCurrentUser();
User user = userService.findUserById(userId); User user = userService.findUserById(authUser.getTenantId(), userId);
if (!userTokenAccessEnabled || (authUser.getAuthority() == Authority.SYS_ADMIN && user.getAuthority() != Authority.TENANT_ADMIN) if (!userTokenAccessEnabled || (authUser.getAuthority() == Authority.SYS_ADMIN && user.getAuthority() != Authority.TENANT_ADMIN)
|| (authUser.getAuthority() == Authority.TENANT_ADMIN && !authUser.getTenantId().equals(user.getTenantId()))) { || (authUser.getAuthority() == Authority.TENANT_ADMIN && !authUser.getTenantId().equals(user.getTenantId()))) {
throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION,
ThingsboardErrorCode.PERMISSION_DENIED); ThingsboardErrorCode.PERMISSION_DENIED);
} }
UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail()); UserPrincipal principal = new UserPrincipal(UserPrincipal.Type.USER_NAME, user.getEmail());
UserCredentials credentials = userService.findUserCredentialsByUserId(userId); UserCredentials credentials = userService.findUserCredentialsByUserId(authUser.getTenantId(), userId);
SecurityUser securityUser = new SecurityUser(user, credentials.isEnabled(), principal); SecurityUser securityUser = new SecurityUser(user, credentials.isEnabled(), principal);
JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser); JwtToken accessToken = tokenFactory.createAccessJwtToken(securityUser);
JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser); JwtToken refreshToken = refreshTokenRepository.requestRefreshToken(securityUser);
@ -146,7 +146,7 @@ public class UserController extends BaseController {
} }
User savedUser = checkNotNull(userService.saveUser(user)); User savedUser = checkNotNull(userService.saveUser(user));
if (sendEmail) { if (sendEmail) {
UserCredentials userCredentials = userService.findUserCredentialsByUserId(savedUser.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(authUser.getTenantId(), savedUser.getId());
String baseUrl = constructBaseUrl(request); String baseUrl = constructBaseUrl(request);
String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl,
userCredentials.getActivateToken()); userCredentials.getActivateToken());
@ -154,7 +154,7 @@ public class UserController extends BaseController {
try { try {
mailService.sendActivationEmail(activateUrl, email); mailService.sendActivationEmail(activateUrl, email);
} catch (ThingsboardException e) { } catch (ThingsboardException e) {
userService.deleteUser(savedUser.getId()); userService.deleteUser(authUser.getTenantId(), savedUser.getId());
throw e; throw e;
} }
} }
@ -180,8 +180,8 @@ public class UserController extends BaseController {
@RequestParam(value = "email") String email, @RequestParam(value = "email") String email,
HttpServletRequest request) throws ThingsboardException { HttpServletRequest request) throws ThingsboardException {
try { try {
User user = checkNotNull(userService.findUserByEmail(email)); User user = checkNotNull(userService.findUserByEmail(getCurrentUser().getTenantId(), email));
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(getCurrentUser().getTenantId(), user.getId());
if (!userCredentials.isEnabled()) { if (!userCredentials.isEnabled()) {
String baseUrl = constructBaseUrl(request); String baseUrl = constructBaseUrl(request);
String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl,
@ -210,7 +210,7 @@ public class UserController extends BaseController {
ThingsboardErrorCode.PERMISSION_DENIED); ThingsboardErrorCode.PERMISSION_DENIED);
} }
User user = checkUserId(userId); User user = checkUserId(userId);
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(getCurrentUser().getTenantId(), user.getId());
if (!userCredentials.isEnabled()) { if (!userCredentials.isEnabled()) {
String baseUrl = constructBaseUrl(request); String baseUrl = constructBaseUrl(request);
String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl,
@ -232,7 +232,7 @@ public class UserController extends BaseController {
try { try {
UserId userId = new UserId(toUUID(strUserId)); UserId userId = new UserId(toUUID(strUserId));
User user = checkUserId(userId); User user = checkUserId(userId);
userService.deleteUser(userId); userService.deleteUser(getCurrentUser().getTenantId(), userId);
logEntityAction(userId, user, logEntityAction(userId, user,
user.getCustomerId(), user.getCustomerId(),

2
application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java

@ -75,7 +75,7 @@ public class WidgetTypeController extends BaseController {
try { try {
WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId));
checkWidgetTypeId(widgetTypeId, true); checkWidgetTypeId(widgetTypeId, true);
widgetTypeService.deleteWidgetType(widgetTypeId); widgetTypeService.deleteWidgetType(getCurrentUser().getTenantId(), widgetTypeId);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }

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

@ -77,7 +77,7 @@ public class WidgetsBundleController extends BaseController {
try { try {
WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId));
checkWidgetsBundleId(widgetsBundleId, true); checkWidgetsBundleId(widgetsBundleId, true);
widgetsBundleService.deleteWidgetsBundle(widgetsBundleId); widgetsBundleService.deleteWidgetsBundle(getTenantId(), widgetsBundleId);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -94,7 +94,7 @@ public class WidgetsBundleController extends BaseController {
try { try {
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) { if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) {
return checkNotNull(widgetsBundleService.findSystemWidgetsBundlesByPageLink(pageLink)); return checkNotNull(widgetsBundleService.findSystemWidgetsBundlesByPageLink(getTenantId(), pageLink));
} else { } else {
TenantId tenantId = getCurrentUser().getTenantId(); TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink)); return checkNotNull(widgetsBundleService.findAllTenantWidgetsBundlesByTenantIdAndPageLink(tenantId, pageLink));
@ -110,7 +110,7 @@ public class WidgetsBundleController extends BaseController {
public List<WidgetsBundle> getWidgetsBundles() throws ThingsboardException { public List<WidgetsBundle> getWidgetsBundles() throws ThingsboardException {
try { try {
if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) { if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) {
return checkNotNull(widgetsBundleService.findSystemWidgetsBundles()); return checkNotNull(widgetsBundleService.findSystemWidgetsBundles(getTenantId()));
} else { } else {
TenantId tenantId = getCurrentUser().getTenantId(); TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(widgetsBundleService.findAllTenantWidgetsBundlesByTenantId(tenantId)); return checkNotNull(widgetsBundleService.findAllTenantWidgetsBundlesByTenantId(tenantId));

9
application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java

@ -30,6 +30,7 @@ import org.thingsboard.rule.engine.api.NodeConfiguration;
import org.thingsboard.rule.engine.api.NodeDefinition; import org.thingsboard.rule.engine.api.NodeDefinition;
import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.rule.engine.api.TbRelationTypes; import org.thingsboard.rule.engine.api.TbRelationTypes;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.dao.component.ComponentDescriptorService; import org.thingsboard.server.dao.component.ComponentDescriptorService;
@ -159,18 +160,18 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
log.error("Can't initialize component {}, due to {}", def.getBeanClassName(), e.getMessage(), e); log.error("Can't initialize component {}, due to {}", def.getBeanClassName(), e.getMessage(), e);
throw new RuntimeException(e); throw new RuntimeException(e);
} }
ComponentDescriptor persistedComponent = componentDescriptorService.findByClazz(clazzName); ComponentDescriptor persistedComponent = componentDescriptorService.findByClazz(TenantId.SYS_TENANT_ID, clazzName);
if (persistedComponent == null) { if (persistedComponent == null) {
log.info("Persisting new component: {}", scannedComponent); log.info("Persisting new component: {}", scannedComponent);
scannedComponent = componentDescriptorService.saveComponent(scannedComponent); scannedComponent = componentDescriptorService.saveComponent(TenantId.SYS_TENANT_ID, scannedComponent);
} else if (scannedComponent.equals(persistedComponent)) { } else if (scannedComponent.equals(persistedComponent)) {
log.info("Component is already persisted: {}", persistedComponent); log.info("Component is already persisted: {}", persistedComponent);
scannedComponent = persistedComponent; scannedComponent = persistedComponent;
} else { } else {
log.info("Component {} will be updated to {}", persistedComponent, scannedComponent); log.info("Component {} will be updated to {}", persistedComponent, scannedComponent);
componentDescriptorService.deleteByClazz(persistedComponent.getClazz()); componentDescriptorService.deleteByClazz(TenantId.SYS_TENANT_ID, persistedComponent.getClazz());
scannedComponent.setId(persistedComponent.getId()); scannedComponent.setId(persistedComponent.getId());
scannedComponent = componentDescriptorService.saveComponent(scannedComponent); scannedComponent = componentDescriptorService.saveComponent(TenantId.SYS_TENANT_ID, scannedComponent);
} }
return scannedComponent; return scannedComponent;
} }

4
application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java

@ -25,6 +25,8 @@ import org.thingsboard.server.common.data.ShortCustomerInfo;
import org.thingsboard.server.common.data.UUIDConverter; import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.dashboard.DashboardService;
import java.io.IOException; import java.io.IOException;
@ -96,7 +98,7 @@ public class DatabaseHelper {
} }
} }
for (CustomerId customerId : customerIds) { for (CustomerId customerId : customerIds) {
dashboardService.assignDashboardToCustomer(dashboardId, customerId); dashboardService.assignDashboardToCustomer(new TenantId(EntityId.NULL_UUID), dashboardId, customerId);
} }
}); });
} }

14
application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java

@ -96,7 +96,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
ObjectNode node = objectMapper.createObjectNode(); ObjectNode node = objectMapper.createObjectNode();
node.put("baseUrl", "http://localhost:8080"); node.put("baseUrl", "http://localhost:8080");
generalSettings.setJsonValue(node); generalSettings.setJsonValue(node);
adminSettingsService.saveAdminSettings(generalSettings); adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, generalSettings);
AdminSettings mailSettings = new AdminSettings(); AdminSettings mailSettings = new AdminSettings();
mailSettings.setKey("mail"); mailSettings.setKey("mail");
@ -110,7 +110,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
node.put("username", ""); node.put("username", "");
node.put("password", ""); //NOSONAR, key used to identify password field (not password value itself) node.put("password", ""); //NOSONAR, key used to identify password field (not password value itself)
mailSettings.setJsonValue(node); mailSettings.setJsonValue(node);
adminSettingsService.saveAdminSettings(mailSettings); adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, mailSettings);
} }
@Override @Override
@ -158,7 +158,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
public void deleteSystemWidgetBundle(String bundleAlias) throws Exception { public void deleteSystemWidgetBundle(String bundleAlias) throws Exception {
WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(new TenantId(ModelConstants.NULL_UUID), bundleAlias); WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(new TenantId(ModelConstants.NULL_UUID), bundleAlias);
if (widgetsBundle != null) { if (widgetsBundle != null) {
widgetsBundleService.deleteWidgetsBundle(widgetsBundle.getId()); widgetsBundleService.deleteWidgetsBundle(TenantId.SYS_TENANT_ID, widgetsBundle.getId());
} }
} }
@ -178,11 +178,11 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
user.setTenantId(tenantId); user.setTenantId(tenantId);
user.setCustomerId(customerId); user.setCustomerId(customerId);
user = userService.saveUser(user); user = userService.saveUser(user);
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, user.getId());
userCredentials.setPassword(passwordEncoder.encode(password)); userCredentials.setPassword(passwordEncoder.encode(password));
userCredentials.setEnabled(true); userCredentials.setEnabled(true);
userCredentials.setActivateToken(null); userCredentials.setActivateToken(null);
userService.saveUserCredentials(userCredentials); userService.saveUserCredentials(TenantId.SYS_TENANT_ID, userCredentials);
return user; return user;
} }
@ -203,9 +203,9 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
device.setAdditionalInfo(additionalInfo); device.setAdditionalInfo(additionalInfo);
} }
device = deviceService.saveDevice(device); device = deviceService.saveDevice(device);
DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(device.getId()); DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(TenantId.SYS_TENANT_ID, device.getId());
deviceCredentials.setCredentialsId(accessToken); deviceCredentials.setCredentialsId(accessToken);
deviceCredentialsService.updateDeviceCredentials(deviceCredentials); deviceCredentialsService.updateDeviceCredentials(TenantId.SYS_TENANT_ID, deviceCredentials);
return device; return device;
} }

5
application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java

@ -23,6 +23,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainMetaData;
@ -116,7 +117,7 @@ public class InstallScripts {
ruleChain = ruleChainService.saveRuleChain(ruleChain); ruleChain = ruleChainService.saveRuleChain(ruleChain);
ruleChainMetaData.setRuleChainId(ruleChain.getId()); ruleChainMetaData.setRuleChainId(ruleChain.getId());
ruleChainService.saveRuleChainMetaData(ruleChainMetaData); ruleChainService.saveRuleChainMetaData(new TenantId(EntityId.NULL_UUID), ruleChainMetaData);
} catch (Exception e) { } catch (Exception e) {
log.error("Unable to load rule chain from json: [{}]", path.toString()); log.error("Unable to load rule chain from json: [{}]", path.toString());
throw new RuntimeException("Unable to load rule chain from json", e); throw new RuntimeException("Unable to load rule chain from json", e);
@ -169,7 +170,7 @@ public class InstallScripts {
dashboard.setTenantId(tenantId); dashboard.setTenantId(tenantId);
Dashboard savedDashboard = dashboardService.saveDashboard(dashboard); Dashboard savedDashboard = dashboardService.saveDashboard(dashboard);
if (customerId != null && !customerId.isNullUid()) { if (customerId != null && !customerId.isNullUid()) {
dashboardService.assignDashboardToCustomer(savedDashboard.getId(), customerId); dashboardService.assignDashboardToCustomer(new TenantId(EntityId.NULL_UUID), savedDashboard.getId(), customerId);
} }
} catch (Exception e) { } catch (Exception e) {
log.error("Unable to load dashboard from json: [{}]", path.toString()); log.error("Unable to load dashboard from json: [{}]", path.toString());

4
application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java

@ -31,6 +31,8 @@ import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.exception.IncorrectParameterException; import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.dao.settings.AdminSettingsService;
@ -70,7 +72,7 @@ public class DefaultMailService implements MailService {
@Override @Override
public void updateMailConfiguration() { public void updateMailConfiguration() {
AdminSettings settings = adminSettingsService.findAdminSettingsByKey("mail"); AdminSettings settings = adminSettingsService.findAdminSettingsByKey(new TenantId(EntityId.NULL_UUID), "mail");
if (settings != null) { if (settings != null) {
JsonNode jsonConfig = settings.getJsonValue(); JsonNode jsonConfig = settings.getJsonValue();
mailSender = createMailSender(jsonConfig); mailSender = createMailSender(jsonConfig);

30
application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java

@ -110,24 +110,24 @@ public class AccessValidator {
} }
public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, String entityType, String entityIdStr, public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, String entityType, String entityIdStr,
BiConsumer<DeferredResult<ResponseEntity>, EntityId> onSuccess) throws ThingsboardException { ThreeConsumer<DeferredResult<ResponseEntity>, TenantId, EntityId> onSuccess) throws ThingsboardException {
return validateEntityAndCallback(currentUser, entityType, entityIdStr, onSuccess, (result, t) -> handleError(t, result, HttpStatus.INTERNAL_SERVER_ERROR)); return validateEntityAndCallback(currentUser, entityType, entityIdStr, onSuccess, (result, t) -> handleError(t, result, HttpStatus.INTERNAL_SERVER_ERROR));
} }
public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, String entityType, String entityIdStr, public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, String entityType, String entityIdStr,
BiConsumer<DeferredResult<ResponseEntity>, EntityId> onSuccess, ThreeConsumer<DeferredResult<ResponseEntity>, TenantId, EntityId> onSuccess,
BiConsumer<DeferredResult<ResponseEntity>, Throwable> onFailure) throws ThingsboardException { BiConsumer<DeferredResult<ResponseEntity>, Throwable> onFailure) throws ThingsboardException {
return validateEntityAndCallback(currentUser, EntityIdFactory.getByTypeAndId(entityType, entityIdStr), return validateEntityAndCallback(currentUser, EntityIdFactory.getByTypeAndId(entityType, entityIdStr),
onSuccess, onFailure); onSuccess, onFailure);
} }
public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, EntityId entityId, public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, EntityId entityId,
BiConsumer<DeferredResult<ResponseEntity>, EntityId> onSuccess) throws ThingsboardException { ThreeConsumer<DeferredResult<ResponseEntity>, TenantId, EntityId> onSuccess) throws ThingsboardException {
return validateEntityAndCallback(currentUser, entityId, onSuccess, (result, t) -> handleError(t, result, HttpStatus.INTERNAL_SERVER_ERROR)); return validateEntityAndCallback(currentUser, entityId, onSuccess, (result, t) -> handleError(t, result, HttpStatus.INTERNAL_SERVER_ERROR));
} }
public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, EntityId entityId, public DeferredResult<ResponseEntity> validateEntityAndCallback(SecurityUser currentUser, EntityId entityId,
BiConsumer<DeferredResult<ResponseEntity>, EntityId> onSuccess, ThreeConsumer<DeferredResult<ResponseEntity>, TenantId, EntityId> onSuccess,
BiConsumer<DeferredResult<ResponseEntity>, Throwable> onFailure) throws ThingsboardException { BiConsumer<DeferredResult<ResponseEntity>, Throwable> onFailure) throws ThingsboardException {
final DeferredResult<ResponseEntity> response = new DeferredResult<>(); final DeferredResult<ResponseEntity> response = new DeferredResult<>();
@ -136,7 +136,7 @@ public class AccessValidator {
new FutureCallback<DeferredResult<ResponseEntity>>() { new FutureCallback<DeferredResult<ResponseEntity>>() {
@Override @Override
public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) { public void onSuccess(@Nullable DeferredResult<ResponseEntity> result) {
onSuccess.accept(response, entityId); onSuccess.accept(response, currentUser.getTenantId(), entityId);
} }
@Override @Override
@ -178,7 +178,7 @@ public class AccessValidator {
if (currentUser.isSystemAdmin()) { if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else { } else {
ListenableFuture<Device> deviceFuture = deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); ListenableFuture<Device> deviceFuture = deviceService.findDeviceByIdAsync(currentUser.getTenantId(), new DeviceId(entityId.getId()));
Futures.addCallback(deviceFuture, getCallback(callback, device -> { Futures.addCallback(deviceFuture, getCallback(callback, device -> {
if (device == null) { if (device == null) {
return ValidationResult.entityNotFound(DEVICE_WITH_REQUESTED_ID_NOT_FOUND); return ValidationResult.entityNotFound(DEVICE_WITH_REQUESTED_ID_NOT_FOUND);
@ -199,7 +199,7 @@ public class AccessValidator {
if (currentUser.isSystemAdmin()) { if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else { } else {
ListenableFuture<Asset> assetFuture = assetService.findAssetByIdAsync(new AssetId(entityId.getId())); ListenableFuture<Asset> assetFuture = assetService.findAssetByIdAsync(currentUser.getTenantId(), new AssetId(entityId.getId()));
Futures.addCallback(assetFuture, getCallback(callback, asset -> { Futures.addCallback(assetFuture, getCallback(callback, asset -> {
if (asset == null) { if (asset == null) {
return ValidationResult.entityNotFound("Asset with requested id wasn't found!"); return ValidationResult.entityNotFound("Asset with requested id wasn't found!");
@ -220,7 +220,7 @@ public class AccessValidator {
if (currentUser.isCustomerUser()) { if (currentUser.isCustomerUser()) {
callback.onSuccess(ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); callback.onSuccess(ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else { } else {
ListenableFuture<RuleChain> ruleChainFuture = ruleChainService.findRuleChainByIdAsync(new RuleChainId(entityId.getId())); ListenableFuture<RuleChain> ruleChainFuture = ruleChainService.findRuleChainByIdAsync(currentUser.getTenantId(), new RuleChainId(entityId.getId()));
Futures.addCallback(ruleChainFuture, getCallback(callback, ruleChain -> { Futures.addCallback(ruleChainFuture, getCallback(callback, ruleChain -> {
if (ruleChain == null) { if (ruleChain == null) {
return ValidationResult.entityNotFound("Rule chain with requested id wasn't found!"); return ValidationResult.entityNotFound("Rule chain with requested id wasn't found!");
@ -241,7 +241,7 @@ public class AccessValidator {
if (currentUser.isCustomerUser()) { if (currentUser.isCustomerUser()) {
callback.onSuccess(ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); callback.onSuccess(ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else { } else {
ListenableFuture<RuleNode> ruleNodeFuture = ruleChainService.findRuleNodeByIdAsync(new RuleNodeId(entityId.getId())); ListenableFuture<RuleNode> ruleNodeFuture = ruleChainService.findRuleNodeByIdAsync(currentUser.getTenantId(), new RuleNodeId(entityId.getId()));
Futures.addCallback(ruleNodeFuture, getCallback(callback, ruleNodeTmp -> { Futures.addCallback(ruleNodeFuture, getCallback(callback, ruleNodeTmp -> {
RuleNode ruleNode = ruleNodeTmp; RuleNode ruleNode = ruleNodeTmp;
if (ruleNode == null) { if (ruleNode == null) {
@ -250,7 +250,7 @@ public class AccessValidator {
return ValidationResult.entityNotFound("Rule chain with requested node id wasn't found!"); return ValidationResult.entityNotFound("Rule chain with requested node id wasn't found!");
} else { } else {
//TODO: make async //TODO: make async
RuleChain ruleChain = ruleChainService.findRuleChainById(ruleNode.getRuleChainId()); RuleChain ruleChain = ruleChainService.findRuleChainById(currentUser.getTenantId(), ruleNode.getRuleChainId());
if (currentUser.isTenantAdmin() && !ruleChain.getTenantId().equals(currentUser.getTenantId())) { if (currentUser.isTenantAdmin() && !ruleChain.getTenantId().equals(currentUser.getTenantId())) {
return ValidationResult.accessDenied("Rule chain doesn't belong to the current Tenant!"); return ValidationResult.accessDenied("Rule chain doesn't belong to the current Tenant!");
} else if (currentUser.isSystemAdmin() && !ruleChain.getTenantId().isNullUid()) { } else if (currentUser.isSystemAdmin() && !ruleChain.getTenantId().isNullUid()) {
@ -267,7 +267,7 @@ public class AccessValidator {
if (currentUser.isSystemAdmin()) { if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else { } else {
ListenableFuture<Customer> customerFuture = customerService.findCustomerByIdAsync(new CustomerId(entityId.getId())); ListenableFuture<Customer> customerFuture = customerService.findCustomerByIdAsync(currentUser.getTenantId(), new CustomerId(entityId.getId()));
Futures.addCallback(customerFuture, getCallback(callback, customer -> { Futures.addCallback(customerFuture, getCallback(callback, customer -> {
if (customer == null) { if (customer == null) {
return ValidationResult.entityNotFound("Customer with requested id wasn't found!"); return ValidationResult.entityNotFound("Customer with requested id wasn't found!");
@ -290,7 +290,7 @@ public class AccessValidator {
} else if (currentUser.isSystemAdmin()) { } else if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.ok(null)); callback.onSuccess(ValidationResult.ok(null));
} else { } else {
ListenableFuture<Tenant> tenantFuture = tenantService.findTenantByIdAsync(new TenantId(entityId.getId())); ListenableFuture<Tenant> tenantFuture = tenantService.findTenantByIdAsync(currentUser.getTenantId(), new TenantId(entityId.getId()));
Futures.addCallback(tenantFuture, getCallback(callback, tenant -> { Futures.addCallback(tenantFuture, getCallback(callback, tenant -> {
if (tenant == null) { if (tenant == null) {
return ValidationResult.entityNotFound("Tenant with requested id wasn't found!"); return ValidationResult.entityNotFound("Tenant with requested id wasn't found!");
@ -307,7 +307,7 @@ public class AccessValidator {
if (currentUser.isSystemAdmin()) { if (currentUser.isSystemAdmin()) {
callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION)); callback.onSuccess(ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else { } else {
ListenableFuture<EntityView> entityViewFuture = entityViewService.findEntityViewByIdAsync(new EntityViewId(entityId.getId())); ListenableFuture<EntityView> entityViewFuture = entityViewService.findEntityViewByIdAsync(currentUser.getTenantId(), new EntityViewId(entityId.getId()));
Futures.addCallback(entityViewFuture, getCallback(callback, entityView -> { Futures.addCallback(entityViewFuture, getCallback(callback, entityView -> {
if (entityView == null) { if (entityView == null) {
return ValidationResult.entityNotFound(ENTITY_VIEW_WITH_REQUESTED_ID_NOT_FOUND); return ValidationResult.entityNotFound(ENTITY_VIEW_WITH_REQUESTED_ID_NOT_FOUND);
@ -349,4 +349,8 @@ public class AccessValidator {
} }
response.setResult(responseEntity); response.setResult(responseEntity);
} }
public interface ThreeConsumer<A, B, C> {
void accept(A a, B b, C c);
}
} }

9
application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenAuthenticationProvider.java

@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserCredentials;
@ -72,12 +73,13 @@ public class RefreshTokenAuthenticationProvider implements AuthenticationProvide
} }
private SecurityUser authenticateByUserId(UserId userId) { private SecurityUser authenticateByUserId(UserId userId) {
User user = userService.findUserById(userId); TenantId systemId = new TenantId(EntityId.NULL_UUID);
User user = userService.findUserById(systemId, userId);
if (user == null) { if (user == null) {
throw new UsernameNotFoundException("User not found by refresh token"); throw new UsernameNotFoundException("User not found by refresh token");
} }
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(systemId, user.getId());
if (userCredentials == null) { if (userCredentials == null) {
throw new UsernameNotFoundException("User credentials not found"); throw new UsernameNotFoundException("User credentials not found");
} }
@ -96,13 +98,14 @@ public class RefreshTokenAuthenticationProvider implements AuthenticationProvide
} }
private SecurityUser authenticateByPublicId(String publicId) { private SecurityUser authenticateByPublicId(String publicId) {
TenantId systemId = new TenantId(EntityId.NULL_UUID);
CustomerId customerId; CustomerId customerId;
try { try {
customerId = new CustomerId(UUID.fromString(publicId)); customerId = new CustomerId(UUID.fromString(publicId));
} catch (Exception e) { } catch (Exception e) {
throw new BadCredentialsException("Refresh token is not valid"); throw new BadCredentialsException("Refresh token is not valid");
} }
Customer publicCustomer = customerService.findCustomerById(customerId); Customer publicCustomer = customerService.findCustomerById(systemId, customerId);
if (publicCustomer == null) { if (publicCustomer == null) {
throw new UsernameNotFoundException("Public entity not found by refresh token"); throw new UsernameNotFoundException("Public entity not found by refresh token");
} }

7
application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAuthenticationProvider.java

@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserCredentials;
@ -76,12 +77,12 @@ public class RestAuthenticationProvider implements AuthenticationProvider {
} }
private Authentication authenticateByUsernameAndPassword(UserPrincipal userPrincipal, String username, String password) { private Authentication authenticateByUsernameAndPassword(UserPrincipal userPrincipal, String username, String password) {
User user = userService.findUserByEmail(username); User user = userService.findUserByEmail(TenantId.SYS_TENANT_ID, username);
if (user == null) { if (user == null) {
throw new UsernameNotFoundException("User not found: " + username); throw new UsernameNotFoundException("User not found: " + username);
} }
UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId()); UserCredentials userCredentials = userService.findUserCredentialsByUserId(TenantId.SYS_TENANT_ID, user.getId());
if (userCredentials == null) { if (userCredentials == null) {
throw new UsernameNotFoundException("User credentials not found"); throw new UsernameNotFoundException("User credentials not found");
} }
@ -108,7 +109,7 @@ public class RestAuthenticationProvider implements AuthenticationProvider {
} catch (Exception e) { } catch (Exception e) {
throw new BadCredentialsException("Authentication Failed. Public Id is not valid."); throw new BadCredentialsException("Authentication Failed. Public Id is not valid.");
} }
Customer publicCustomer = customerService.findCustomerById(customerId); Customer publicCustomer = customerService.findCustomerById(TenantId.SYS_TENANT_ID, customerId);
if (publicCustomer == null) { if (publicCustomer == null) {
throw new UsernameNotFoundException("Public entity not found: " + publicId); throw new UsernameNotFoundException("Public entity not found: " + publicId);
} }

10
application/src/main/java/org/thingsboard/server/service/security/device/DefaultDeviceAuthService.java

@ -18,8 +18,6 @@ package org.thingsboard.server.service.security.device;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsFilter; import org.thingsboard.server.common.data.security.DeviceCredentialsFilter;
import org.thingsboard.server.common.transport.auth.DeviceAuthResult; import org.thingsboard.server.common.transport.auth.DeviceAuthResult;
@ -27,8 +25,6 @@ import org.thingsboard.server.common.transport.auth.DeviceAuthService;
import org.thingsboard.server.dao.device.DeviceCredentialsService; import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.device.DeviceService;
import java.util.Optional;
@Service @Service
@Slf4j @Slf4j
public class DefaultDeviceAuthService implements DeviceAuthService { public class DefaultDeviceAuthService implements DeviceAuthService {
@ -65,8 +61,4 @@ public class DefaultDeviceAuthService implements DeviceAuthService {
} }
} }
@Override }
public Optional<Device> findDeviceById(DeviceId deviceId) {
return Optional.ofNullable(deviceService.findDeviceById(deviceId));
}
}

3
application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java

@ -21,6 +21,7 @@ import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantId;
@ -69,7 +70,7 @@ public class JwtTokenFactory {
UserPrincipal principal = securityUser.getUserPrincipal(); UserPrincipal principal = securityUser.getUserPrincipal();
String subject = principal.getValue(); String subject = principal.getValue();
Claims claims = Jwts.claims().setSubject(subject); Claims claims = Jwts.claims().setSubject(subject);
claims.put(SCOPES, securityUser.getAuthorities().stream().map(s -> s.getAuthority()).collect(Collectors.toList())); claims.put(SCOPES, securityUser.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()));
claims.put(USER_ID, securityUser.getId().getId().toString()); claims.put(USER_ID, securityUser.getId().getId().toString());
claims.put(FIRST_NAME, securityUser.getFirstName()); claims.put(FIRST_NAME, securityUser.getFirstName());
claims.put(LAST_NAME, securityUser.getLastName()); claims.put(LAST_NAME, securityUser.getLastName());

10
application/src/main/java/org/thingsboard/server/service/state/DefaultDeviceStateService.java

@ -207,7 +207,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
if (proto.getDeleted()) { if (proto.getDeleted()) {
queueExecutor.submit(() -> onDeviceDeleted(tenantId, deviceId)); queueExecutor.submit(() -> onDeviceDeleted(tenantId, deviceId));
} else { } else {
Device device = deviceService.findDeviceById(deviceId); Device device = deviceService.findDeviceById(TenantId.SYS_TENANT_ID, deviceId);
if (device != null) { if (device != null) {
if (proto.getAdded()) { if (proto.getAdded()) {
onDeviceAdded(device); onDeviceAdded(device);
@ -320,7 +320,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
DeviceStateData deviceStateData = deviceStates.get(deviceId); DeviceStateData deviceStateData = deviceStates.get(deviceId);
if (deviceStateData == null) { if (deviceStateData == null) {
if (!routingService.resolveById(deviceId).isPresent()) { if (!routingService.resolveById(deviceId).isPresent()) {
Device device = deviceService.findDeviceById(deviceId); Device device = deviceService.findDeviceById(TenantId.SYS_TENANT_ID, deviceId);
if (device != null) { if (device != null) {
try { try {
deviceStateData = fetchDeviceState(device).get(); deviceStateData = fetchDeviceState(device).get();
@ -414,7 +414,7 @@ public class DefaultDeviceStateService implements DeviceStateService {
} }
private ListenableFuture<DeviceStateData> fetchDeviceState(Device device) { private ListenableFuture<DeviceStateData> fetchDeviceState(Device device) {
ListenableFuture<List<AttributeKvEntry>> attributes = attributesService.find(device.getId(), DataConstants.SERVER_SCOPE, PERSISTENT_ATTRIBUTES); ListenableFuture<List<AttributeKvEntry>> attributes = attributesService.find(TenantId.SYS_TENANT_ID, device.getId(), DataConstants.SERVER_SCOPE, PERSISTENT_ATTRIBUTES);
return Futures.transform(attributes, new Function<List<AttributeKvEntry>, DeviceStateData>() { return Futures.transform(attributes, new Function<List<AttributeKvEntry>, DeviceStateData>() {
@Nullable @Nullable
@Override @Override
@ -465,11 +465,11 @@ public class DefaultDeviceStateService implements DeviceStateService {
} }
private void saveAttribute(DeviceId deviceId, String key, long value) { private void saveAttribute(DeviceId deviceId, String key, long value) {
tsSubService.saveAttrAndNotify(deviceId, DataConstants.SERVER_SCOPE, key, value, new AttributeSaveCallback(deviceId, key, value)); tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, key, value, new AttributeSaveCallback(deviceId, key, value));
} }
private void saveAttribute(DeviceId deviceId, String key, boolean value) { private void saveAttribute(DeviceId deviceId, String key, boolean value) {
tsSubService.saveAttrAndNotify(deviceId, DataConstants.SERVER_SCOPE, key, value, new AttributeSaveCallback(deviceId, key, value)); tsSubService.saveAttrAndNotify(TenantId.SYS_TENANT_ID, deviceId, DataConstants.SERVER_SCOPE, key, value, new AttributeSaveCallback(deviceId, key, value));
} }
private class AttributeSaveCallback implements FutureCallback<Void> { private class AttributeSaveCallback implements FutureCallback<Void> {

39
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java

@ -63,6 +63,7 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -131,7 +132,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
long startTime = 0L; long startTime = 0L;
long endTime = 0L; long endTime = 0L;
if (entityId.getEntityType().equals(EntityType.ENTITY_VIEW) && TelemetryFeature.TIMESERIES.equals(sub.getType())) { if (entityId.getEntityType().equals(EntityType.ENTITY_VIEW) && TelemetryFeature.TIMESERIES.equals(sub.getType())) {
EntityView entityView = entityViewService.findEntityViewById(new EntityViewId(entityId.getId())); EntityView entityView = entityViewService.findEntityViewById(TenantId.SYS_TENANT_ID, new EntityViewId(entityId.getId()));
entityId = entityView.getEntityId(); entityId = entityView.getEntityId();
startTime = entityView.getStartTimeMs(); startTime = entityView.getStartTimeMs();
endTime = entityView.getEndTimeMs(); endTime = entityView.getEndTimeMs();
@ -160,7 +161,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
.stream().filter(entry -> entityView.getKeys().getTimeseries().contains(entry.getKey())) .stream().filter(entry -> entityView.getKeys().getTimeseries().contains(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
} }
return new SubscriptionState(sub.getWsSessionId(), sub.getSubscriptionId(), entityId, sub.getType(), false, keyStates, sub.getScope()); return new SubscriptionState(sub.getWsSessionId(), sub.getSubscriptionId(), sub.getTenantId(), entityId, sub.getType(), false, keyStates, sub.getScope());
} }
@Override @Override
@ -185,45 +186,45 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
} }
@Override @Override
public void saveAndNotify(EntityId entityId, List<TsKvEntry> ts, FutureCallback<Void> callback) { public void saveAndNotify(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, FutureCallback<Void> callback) {
saveAndNotify(entityId, ts, 0L, callback); saveAndNotify(tenantId, entityId, ts, 0L, callback);
} }
@Override @Override
public void saveAndNotify(EntityId entityId, List<TsKvEntry> ts, long ttl, FutureCallback<Void> callback) { public void saveAndNotify(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, long ttl, FutureCallback<Void> callback) {
ListenableFuture<List<Void>> saveFuture = tsService.save(entityId, ts, ttl); ListenableFuture<List<Void>> saveFuture = tsService.save(tenantId, entityId, ts, ttl);
addMainCallback(saveFuture, callback); addMainCallback(saveFuture, callback);
addWsCallback(saveFuture, success -> onTimeseriesUpdate(entityId, ts)); addWsCallback(saveFuture, success -> onTimeseriesUpdate(entityId, ts));
} }
@Override @Override
public void saveAndNotify(EntityId entityId, String scope, List<AttributeKvEntry> attributes, FutureCallback<Void> callback) { public void saveAndNotify(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, FutureCallback<Void> callback) {
ListenableFuture<List<Void>> saveFuture = attrService.save(entityId, scope, attributes); ListenableFuture<List<Void>> saveFuture = attrService.save(tenantId, entityId, scope, attributes);
addMainCallback(saveFuture, callback); addMainCallback(saveFuture, callback);
addWsCallback(saveFuture, success -> onAttributesUpdate(entityId, scope, attributes)); addWsCallback(saveFuture, success -> onAttributesUpdate(entityId, scope, attributes));
} }
@Override @Override
public void saveAttrAndNotify(EntityId entityId, String scope, String key, long value, FutureCallback<Void> callback) { public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, long value, FutureCallback<Void> callback) {
saveAndNotify(entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new LongDataEntry(key, value) saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new LongDataEntry(key, value)
, System.currentTimeMillis())), callback); , System.currentTimeMillis())), callback);
} }
@Override @Override
public void saveAttrAndNotify(EntityId entityId, String scope, String key, String value, FutureCallback<Void> callback) { public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, String value, FutureCallback<Void> callback) {
saveAndNotify(entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry(key, value) saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry(key, value)
, System.currentTimeMillis())), callback); , System.currentTimeMillis())), callback);
} }
@Override @Override
public void saveAttrAndNotify(EntityId entityId, String scope, String key, double value, FutureCallback<Void> callback) { public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, double value, FutureCallback<Void> callback) {
saveAndNotify(entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new DoubleDataEntry(key, value) saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new DoubleDataEntry(key, value)
, System.currentTimeMillis())), callback); , System.currentTimeMillis())), callback);
} }
@Override @Override
public void saveAttrAndNotify(EntityId entityId, String scope, String key, boolean value, FutureCallback<Void> callback) { public void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, boolean value, FutureCallback<Void> callback) {
saveAndNotify(entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new BooleanDataEntry(key, value) saveAndNotify(tenantId, entityId, scope, Collections.singletonList(new BaseAttributeKvEntry(new BooleanDataEntry(key, value)
, System.currentTimeMillis())), callback); , System.currentTimeMillis())), callback);
} }
@ -246,6 +247,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
Collectors.toMap(ClusterAPIProtos.SubscriptionKetStateProto::getKey, ClusterAPIProtos.SubscriptionKetStateProto::getTs)); Collectors.toMap(ClusterAPIProtos.SubscriptionKetStateProto::getKey, ClusterAPIProtos.SubscriptionKetStateProto::getTs));
Subscription subscription = new Subscription( Subscription subscription = new Subscription(
new SubscriptionState(proto.getSessionId(), proto.getSubscriptionId(), new SubscriptionState(proto.getSessionId(), proto.getSubscriptionId(),
new TenantId(UUID.fromString(proto.getTenantId())),
EntityIdFactory.getByTypeAndId(proto.getEntityType(), proto.getEntityId()), EntityIdFactory.getByTypeAndId(proto.getEntityType(), proto.getEntityId()),
TelemetryFeature.valueOf(proto.getType()), proto.getAllKeys(), statesMap, proto.getScope()), TelemetryFeature.valueOf(proto.getType()), proto.getAllKeys(), statesMap, proto.getScope()),
false, new ServerAddress(serverAddress.getHost(), serverAddress.getPort(), serverAddress.getServerType())); false, new ServerAddress(serverAddress.getHost(), serverAddress.getPort(), serverAddress.getServerType()));
@ -372,7 +374,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
registerSubscription(sessionId, entityId, subscription); registerSubscription(sessionId, entityId, subscription);
if (subscription.getType() == TelemetryFeature.ATTRIBUTES) { if (subscription.getType() == TelemetryFeature.ATTRIBUTES) {
final Map<String, Long> keyStates = subscription.getKeyStates(); final Map<String, Long> keyStates = subscription.getKeyStates();
DonAsynchron.withCallback(attrService.find(entityId, DataConstants.CLIENT_SCOPE, keyStates.keySet()), values -> { DonAsynchron.withCallback(attrService.find(subscription.getSub().getTenantId(), entityId, DataConstants.CLIENT_SCOPE, keyStates.keySet()), values -> {
List<TsKvEntry> missedUpdates = new ArrayList<>(); List<TsKvEntry> missedUpdates = new ArrayList<>();
values.forEach(latestEntry -> { values.forEach(latestEntry -> {
if (latestEntry.getLastUpdateTs() > keyStates.get(latestEntry.getKey())) { if (latestEntry.getLastUpdateTs() > keyStates.get(latestEntry.getKey())) {
@ -395,7 +397,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
} }
}); });
if (!queries.isEmpty()) { if (!queries.isEmpty()) {
DonAsynchron.withCallback(tsService.findAll(entityId, queries), DonAsynchron.withCallback(tsService.findAll(subscription.getSub().getTenantId(), entityId, queries),
missedUpdates -> { missedUpdates -> {
if (missedUpdates != null && !missedUpdates.isEmpty()) { if (missedUpdates != null && !missedUpdates.isEmpty()) {
tellRemoteSubUpdate(address, sessionId, new SubscriptionUpdate(subscription.getSubscriptionId(), missedUpdates)); tellRemoteSubUpdate(address, sessionId, new SubscriptionUpdate(subscription.getSubscriptionId(), missedUpdates));
@ -606,6 +608,7 @@ public class DefaultTelemetrySubscriptionService implements TelemetrySubscriptio
ClusterAPIProtos.SubscriptionProto.Builder builder = ClusterAPIProtos.SubscriptionProto.newBuilder(); ClusterAPIProtos.SubscriptionProto.Builder builder = ClusterAPIProtos.SubscriptionProto.newBuilder();
builder.setSessionId(sessionId); builder.setSessionId(sessionId);
builder.setSubscriptionId(sub.getSubscriptionId()); builder.setSubscriptionId(sub.getSubscriptionId());
builder.setTenantId(sub.getSub().getTenantId().getId().toString());
builder.setEntityType(sub.getEntityId().getEntityType().name()); builder.setEntityType(sub.getEntityId().getEntityType().name());
builder.setEntityId(sub.getEntityId().getId().toString()); builder.setEntityId(sub.getEntityId().getId().toString());
builder.setType(sub.getType().name()); builder.setType(sub.getType().name());

41
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetryWebSocketService.java

@ -28,6 +28,7 @@ import org.springframework.util.StringUtils;
import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.kv.Aggregation; import org.thingsboard.server.common.data.kv.Aggregation;
import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery; import org.thingsboard.server.common.data.kv.BaseReadTsKvQuery;
@ -206,7 +207,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
keys.forEach(key -> subState.put(key, 0L)); keys.forEach(key -> subState.put(key, 0L));
attributesData.forEach(v -> subState.put(v.getKey(), v.getTs())); attributesData.forEach(v -> subState.put(v.getKey(), v.getTs()));
SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, TelemetryFeature.ATTRIBUTES, false, subState, cmd.getScope()); SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), sessionRef.getSecurityCtx().getTenantId(), entityId, TelemetryFeature.ATTRIBUTES, false, subState, cmd.getScope());
subscriptionManager.addLocalWsSubscription(sessionId, entityId, sub); subscriptionManager.addLocalWsSubscription(sessionId, entityId, sub);
} }
@ -226,9 +227,9 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
}; };
if (StringUtils.isEmpty(cmd.getScope())) { if (StringUtils.isEmpty(cmd.getScope())) {
accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(entityId, keys, callback)); accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, keys, callback));
} else { } else {
accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(entityId, cmd.getScope(), keys, callback)); accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, cmd.getScope(), keys, callback));
} }
} }
@ -279,7 +280,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
} }
}; };
accessValidator.validate(sessionRef.getSecurityCtx(), entityId, accessValidator.validate(sessionRef.getSecurityCtx(), entityId,
on(r -> Futures.addCallback(tsService.findAll(entityId, queries), callback, executor), callback::onFailure)); on(r -> Futures.addCallback(tsService.findAll(sessionRef.getSecurityCtx().getTenantId(), entityId, queries), callback, executor), callback::onFailure));
} }
private void handleWsAttributesSubscription(TelemetryWebSocketSessionRef sessionRef, private void handleWsAttributesSubscription(TelemetryWebSocketSessionRef sessionRef,
@ -293,7 +294,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
Map<String, Long> subState = new HashMap<>(attributesData.size()); Map<String, Long> subState = new HashMap<>(attributesData.size());
attributesData.forEach(v -> subState.put(v.getKey(), v.getTs())); attributesData.forEach(v -> subState.put(v.getKey(), v.getTs()));
SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, TelemetryFeature.ATTRIBUTES, true, subState, cmd.getScope()); SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), sessionRef.getSecurityCtx().getTenantId(), entityId, TelemetryFeature.ATTRIBUTES, true, subState, cmd.getScope());
subscriptionManager.addLocalWsSubscription(sessionId, entityId, sub); subscriptionManager.addLocalWsSubscription(sessionId, entityId, sub);
} }
@ -308,9 +309,9 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
if (StringUtils.isEmpty(cmd.getScope())) { if (StringUtils.isEmpty(cmd.getScope())) {
accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(entityId, callback)); accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, callback));
} else { } else {
accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(entityId, cmd.getScope(), callback)); accessValidator.validate(sessionRef.getSecurityCtx(), entityId, getAttributesFetchCallback(sessionRef.getSecurityCtx().getTenantId(), entityId, cmd.getScope(), callback));
} }
} }
@ -347,14 +348,14 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
final FutureCallback<List<TsKvEntry>> callback = getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys); final FutureCallback<List<TsKvEntry>> callback = getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys);
accessValidator.validate(sessionRef.getSecurityCtx(), entityId, accessValidator.validate(sessionRef.getSecurityCtx(), entityId,
on(r -> Futures.addCallback(tsService.findAll(entityId, queries), callback, executor), callback::onFailure)); on(r -> Futures.addCallback(tsService.findAll(sessionRef.getSecurityCtx().getTenantId(), entityId, queries), callback, executor), callback::onFailure));
} else { } else {
List<String> keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); List<String> keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet()));
startTs = System.currentTimeMillis(); startTs = System.currentTimeMillis();
log.debug("[{}] fetching latest timeseries data for keys: ({}) for device : {}", sessionId, cmd.getKeys(), entityId); log.debug("[{}] fetching latest timeseries data for keys: ({}) for device : {}", sessionId, cmd.getKeys(), entityId);
final FutureCallback<List<TsKvEntry>> callback = getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys); final FutureCallback<List<TsKvEntry>> callback = getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys);
accessValidator.validate(sessionRef.getSecurityCtx(), entityId, accessValidator.validate(sessionRef.getSecurityCtx(), entityId,
on(r -> Futures.addCallback(tsService.findLatest(entityId, keys), callback, executor), callback::onFailure)); on(r -> Futures.addCallback(tsService.findLatest(sessionRef.getSecurityCtx().getTenantId(), entityId, keys), callback, executor), callback::onFailure));
} }
} }
@ -366,7 +367,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
sendWsMsg(sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data)); sendWsMsg(sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data));
Map<String, Long> subState = new HashMap<>(data.size()); Map<String, Long> subState = new HashMap<>(data.size());
data.forEach(v -> subState.put(v.getKey(), v.getTs())); data.forEach(v -> subState.put(v.getKey(), v.getTs()));
SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, TelemetryFeature.TIMESERIES, true, subState, cmd.getScope()); SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), sessionRef.getSecurityCtx().getTenantId(), entityId, TelemetryFeature.TIMESERIES, true, subState, cmd.getScope());
subscriptionManager.addLocalWsSubscription(sessionId, entityId, sub); subscriptionManager.addLocalWsSubscription(sessionId, entityId, sub);
} }
@ -384,7 +385,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
} }
}; };
accessValidator.validate(sessionRef.getSecurityCtx(), entityId, accessValidator.validate(sessionRef.getSecurityCtx(), entityId,
on(r -> Futures.addCallback(tsService.findAllLatest(entityId), callback, executor), callback::onFailure)); on(r -> Futures.addCallback(tsService.findAllLatest(sessionRef.getSecurityCtx().getTenantId(), entityId), callback, executor), callback::onFailure));
} }
private FutureCallback<List<TsKvEntry>> getSubscriptionCallback(final TelemetryWebSocketSessionRef sessionRef, final TimeseriesSubscriptionCmd cmd, final String sessionId, final EntityId entityId, final long startTs, final List<String> keys) { private FutureCallback<List<TsKvEntry>> getSubscriptionCallback(final TelemetryWebSocketSessionRef sessionRef, final TimeseriesSubscriptionCmd cmd, final String sessionId, final EntityId entityId, final long startTs, final List<String> keys) {
@ -396,7 +397,7 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
Map<String, Long> subState = new HashMap<>(keys.size()); Map<String, Long> subState = new HashMap<>(keys.size());
keys.forEach(key -> subState.put(key, startTs)); keys.forEach(key -> subState.put(key, startTs));
data.forEach(v -> subState.put(v.getKey(), v.getTs())); data.forEach(v -> subState.put(v.getKey(), v.getTs()));
SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, TelemetryFeature.TIMESERIES, false, subState, cmd.getScope()); SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), sessionRef.getSecurityCtx().getTenantId(), entityId, TelemetryFeature.TIMESERIES, false, subState, cmd.getScope());
subscriptionManager.addLocalWsSubscription(sessionId, entityId, sub); subscriptionManager.addLocalWsSubscription(sessionId, entityId, sub);
} }
@ -472,13 +473,13 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
}, executor); }, executor);
} }
private <T> FutureCallback<ValidationResult> getAttributesFetchCallback(final EntityId entityId, final List<String> keys, final FutureCallback<List<AttributeKvEntry>> callback) { private <T> FutureCallback<ValidationResult> getAttributesFetchCallback(final TenantId tenantId, final EntityId entityId, final List<String> keys, final FutureCallback<List<AttributeKvEntry>> callback) {
return new FutureCallback<ValidationResult>() { return new FutureCallback<ValidationResult>() {
@Override @Override
public void onSuccess(@Nullable ValidationResult result) { public void onSuccess(@Nullable ValidationResult result) {
List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>(); List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>();
for (String scope : DataConstants.allScopes()) { for (String scope : DataConstants.allScopes()) {
futures.add(attributesService.find(entityId, scope, keys)); futures.add(attributesService.find(tenantId, entityId, scope, keys));
} }
ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures); ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);
@ -492,11 +493,11 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
}; };
} }
private <T> FutureCallback<ValidationResult> getAttributesFetchCallback(final EntityId entityId, final String scope, final List<String> keys, final FutureCallback<List<AttributeKvEntry>> callback) { private <T> FutureCallback<ValidationResult> getAttributesFetchCallback(final TenantId tenantId, final EntityId entityId, final String scope, final List<String> keys, final FutureCallback<List<AttributeKvEntry>> callback) {
return new FutureCallback<ValidationResult>() { return new FutureCallback<ValidationResult>() {
@Override @Override
public void onSuccess(@Nullable ValidationResult result) { public void onSuccess(@Nullable ValidationResult result) {
Futures.addCallback(attributesService.find(entityId, scope, keys), callback); Futures.addCallback(attributesService.find(tenantId, entityId, scope, keys), callback);
} }
@Override @Override
@ -506,13 +507,13 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
}; };
} }
private <T> FutureCallback<ValidationResult> getAttributesFetchCallback(final EntityId entityId, final FutureCallback<List<AttributeKvEntry>> callback) { private <T> FutureCallback<ValidationResult> getAttributesFetchCallback(final TenantId tenantId, final EntityId entityId, final FutureCallback<List<AttributeKvEntry>> callback) {
return new FutureCallback<ValidationResult>() { return new FutureCallback<ValidationResult>() {
@Override @Override
public void onSuccess(@Nullable ValidationResult result) { public void onSuccess(@Nullable ValidationResult result) {
List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>(); List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>();
for (String scope : DataConstants.allScopes()) { for (String scope : DataConstants.allScopes()) {
futures.add(attributesService.findAll(entityId, scope)); futures.add(attributesService.findAll(tenantId, entityId, scope));
} }
ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures); ListenableFuture<List<AttributeKvEntry>> future = mergeAllAttributesFutures(futures);
@ -526,11 +527,11 @@ public class DefaultTelemetryWebSocketService implements TelemetryWebSocketServi
}; };
} }
private <T> FutureCallback<ValidationResult> getAttributesFetchCallback(final EntityId entityId, final String scope, final FutureCallback<List<AttributeKvEntry>> callback) { private <T> FutureCallback<ValidationResult> getAttributesFetchCallback(final TenantId tenantId, final EntityId entityId, final String scope, final FutureCallback<List<AttributeKvEntry>> callback) {
return new FutureCallback<ValidationResult>() { return new FutureCallback<ValidationResult>() {
@Override @Override
public void onSuccess(@Nullable ValidationResult result) { public void onSuccess(@Nullable ValidationResult result) {
Futures.addCallback(attributesService.findAll(entityId, scope), callback); Futures.addCallback(attributesService.findAll(tenantId, entityId, scope), callback);
} }
@Override @Override

1
application/src/main/java/org/thingsboard/server/service/telemetry/TelemetrySubscriptionService.java

@ -17,6 +17,7 @@ package org.thingsboard.server.service.telemetry;
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService; import org.thingsboard.rule.engine.api.RuleEngineTelemetryService;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.cluster.ServerAddress; import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.service.telemetry.sub.SubscriptionState; import org.thingsboard.server.service.telemetry.sub.SubscriptionState;

2
application/src/main/java/org/thingsboard/server/service/telemetry/sub/SubscriptionState.java

@ -18,6 +18,7 @@ package org.thingsboard.server.service.telemetry.sub;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.service.telemetry.TelemetryFeature; import org.thingsboard.server.service.telemetry.TelemetryFeature;
import java.util.Map; import java.util.Map;
@ -30,6 +31,7 @@ public class SubscriptionState {
@Getter private final String wsSessionId; @Getter private final String wsSessionId;
@Getter private final int subscriptionId; @Getter private final int subscriptionId;
@Getter private final TenantId tenantId;
@Getter private final EntityId entityId; @Getter private final EntityId entityId;
@Getter private final TelemetryFeature type; @Getter private final TelemetryFeature type;
@Getter private final boolean allKeys; @Getter private final boolean allKeys;

7
application/src/main/java/org/thingsboard/server/service/transport/LocalTransportApiService.java

@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.common.data.security.DeviceCredentialsType;
@ -107,7 +108,7 @@ public class LocalTransportApiService implements TransportApiService {
private ListenableFuture<TransportApiResponseMsg> handle(GetOrCreateDeviceFromGatewayRequestMsg requestMsg) { private ListenableFuture<TransportApiResponseMsg> handle(GetOrCreateDeviceFromGatewayRequestMsg requestMsg) {
DeviceId gatewayId = new DeviceId(new UUID(requestMsg.getGatewayIdMSB(), requestMsg.getGatewayIdLSB())); DeviceId gatewayId = new DeviceId(new UUID(requestMsg.getGatewayIdMSB(), requestMsg.getGatewayIdLSB()));
ListenableFuture<Device> gatewayFuture = deviceService.findDeviceByIdAsync(gatewayId); ListenableFuture<Device> gatewayFuture = deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, gatewayId);
return Futures.transform(gatewayFuture, gateway -> { return Futures.transform(gatewayFuture, gateway -> {
deviceCreationLock.lock(); deviceCreationLock.lock();
try { try {
@ -119,7 +120,7 @@ public class LocalTransportApiService implements TransportApiService {
device.setType(requestMsg.getDeviceType()); device.setType(requestMsg.getDeviceType());
device.setCustomerId(gateway.getCustomerId()); device.setCustomerId(gateway.getCustomerId());
device = deviceService.saveDevice(device); device = deviceService.saveDevice(device);
relationService.saveRelationAsync(new EntityRelation(gateway.getId(), device.getId(), "Created")); relationService.saveRelationAsync(TenantId.SYS_TENANT_ID, new EntityRelation(gateway.getId(), device.getId(), "Created"));
deviceStateService.onDeviceAdded(device); deviceStateService.onDeviceAdded(device);
} }
return TransportApiResponseMsg.newBuilder() return TransportApiResponseMsg.newBuilder()
@ -135,7 +136,7 @@ public class LocalTransportApiService implements TransportApiService {
private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId) { private ListenableFuture<TransportApiResponseMsg> getDeviceInfo(DeviceId deviceId) {
return Futures.transform(deviceService.findDeviceByIdAsync(deviceId), device -> { return Futures.transform(deviceService.findDeviceByIdAsync(TenantId.SYS_TENANT_ID, deviceId), device -> {
if (device == null) { if (device == null) {
log.trace("[{}] Failed to lookup device by id", deviceId); log.trace("[{}] Failed to lookup device by id", deviceId);
return getEmptyTransportApiResponse(); return getEmptyTransportApiResponse();

11
application/src/main/proto/cluster.proto

@ -67,11 +67,12 @@ message SubscriptionProto {
string sessionId = 1; string sessionId = 1;
int32 subscriptionId = 2; int32 subscriptionId = 2;
string entityType = 3; string entityType = 3;
string entityId = 4; string tenantId = 4;
string type = 5; string entityId = 5;
bool allKeys = 6; string type = 6;
repeated SubscriptionKetStateProto keyStates = 7; bool allKeys = 7;
string scope = 8; repeated SubscriptionKetStateProto keyStates = 8;
string scope = 9;
} }
message SubscriptionUpdateProto { message SubscriptionUpdateProto {

8
application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java

@ -142,9 +142,9 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
device.setType("default"); device.setType("default");
device = doPost("/api/device", device, Device.class); device = doPost("/api/device", device, Device.class);
attributesService.save(device.getId(), DataConstants.SERVER_SCOPE, attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE,
Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey1", "serverAttributeValue1"), System.currentTimeMillis()))); Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey1", "serverAttributeValue1"), System.currentTimeMillis())));
attributesService.save(device.getId(), DataConstants.SERVER_SCOPE, attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE,
Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey2", "serverAttributeValue2"), System.currentTimeMillis()))); Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey2", "serverAttributeValue2"), System.currentTimeMillis())));
@ -257,9 +257,9 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
device.setType("default"); device.setType("default");
device = doPost("/api/device", device, Device.class); device = doPost("/api/device", device, Device.class);
attributesService.save(device.getId(), DataConstants.SERVER_SCOPE, attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE,
Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey1", "serverAttributeValue1"), System.currentTimeMillis()))); Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey1", "serverAttributeValue1"), System.currentTimeMillis())));
attributesService.save(device.getId(), DataConstants.SERVER_SCOPE, attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE,
Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey2", "serverAttributeValue2"), System.currentTimeMillis()))); Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey2", "serverAttributeValue2"), System.currentTimeMillis())));

2
application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java

@ -131,7 +131,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac
device.setType("default"); device.setType("default");
device = doPost("/api/device", device, Device.class); device = doPost("/api/device", device, Device.class);
attributesService.save(device.getId(), DataConstants.SERVER_SCOPE, attributesService.save(device.getTenantId(), device.getId(), DataConstants.SERVER_SCOPE,
Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey", "serverAttributeValue"), System.currentTimeMillis()))); Collections.singletonList(new BaseAttributeKvEntry(new StringDataEntry("serverAttributeKey", "serverAttributeValue"), System.currentTimeMillis())));
Thread.sleep(1000); Thread.sleep(1000);

3
common/data/src/main/java/org/thingsboard/server/common/data/id/TenantId.java

@ -24,6 +24,9 @@ import org.thingsboard.server.common.data.EntityType;
public final class TenantId extends UUIDBased implements EntityId { public final class TenantId extends UUIDBased implements EntityId {
@JsonIgnore
public static final TenantId SYS_TENANT_ID = new TenantId(EntityId.NULL_UUID);
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@JsonCreator @JsonCreator

2
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/auth/DeviceAuthService.java

@ -25,6 +25,4 @@ public interface DeviceAuthService {
DeviceAuthResult process(DeviceCredentialsFilter credentials); DeviceAuthResult process(DeviceCredentialsFilter credentials);
Optional<Device> findDeviceById(DeviceId deviceId);
} }

2
dao/src/test/resources/cassandra-test.properties

@ -53,6 +53,6 @@ cassandra.query.buffer_size=100000
cassandra.query.concurrent_limit=1000 cassandra.query.concurrent_limit=1000
cassandra.query.permit_max_wait_time=20000 cassandra.query.permit_max_wait_time=20000
cassandra.query.rate_limit_print_interval_ms=30000 cassandra.query.rate_limit_print_interval_ms=30000
cassandra.query.tenant_rate_limits.enabled=true cassandra.query.tenant_rate_limits.enabled=false
cassandra.query.tenant_rate_limits.configuration=5000:1,100000:60 cassandra.query.tenant_rate_limits.configuration=5000:1,100000:60

14
rule-engine/rule-engine-api/src/main/java/org/thingsboard/rule/engine/api/RuleEngineTelemetryService.java

@ -30,19 +30,19 @@ import java.util.Set;
*/ */
public interface RuleEngineTelemetryService { public interface RuleEngineTelemetryService {
void saveAndNotify(EntityId entityId, List<TsKvEntry> ts, FutureCallback<Void> callback); void saveAndNotify(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, FutureCallback<Void> callback);
void saveAndNotify(EntityId entityId, List<TsKvEntry> ts, long ttl, FutureCallback<Void> callback); void saveAndNotify(TenantId tenantId, EntityId entityId, List<TsKvEntry> ts, long ttl, FutureCallback<Void> callback);
void saveAndNotify(EntityId entityId, String scope, List<AttributeKvEntry> attributes, FutureCallback<Void> callback); void saveAndNotify(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, FutureCallback<Void> callback);
void saveAttrAndNotify(EntityId entityId, String scope, String key, long value, FutureCallback<Void> callback); void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, long value, FutureCallback<Void> callback);
void saveAttrAndNotify(EntityId entityId, String scope, String key, String value, FutureCallback<Void> callback); void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, String value, FutureCallback<Void> callback);
void saveAttrAndNotify(EntityId entityId, String scope, String key, double value, FutureCallback<Void> callback); void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, double value, FutureCallback<Void> callback);
void saveAttrAndNotify(EntityId entityId, String scope, String key, boolean value, FutureCallback<Void> callback); void saveAttrAndNotify(TenantId tenantId, EntityId entityId, String scope, String key, boolean value, FutureCallback<Void> callback);
void onSharedAttributesUpdate(TenantId tenantId, DeviceId deviceId, Set<AttributeKvEntry> attributes); void onSharedAttributesUpdate(TenantId tenantId, DeviceId deviceId, Set<AttributeKvEntry> attributes);

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/action/TbClearAlarmNode.java

@ -66,7 +66,7 @@ public class TbClearAlarmNode extends TbAbstractAlarmNode<TbClearAlarmNodeConfig
private ListenableFuture<AlarmResult> clearAlarm(TbContext ctx, TbMsg msg, Alarm alarm) { private ListenableFuture<AlarmResult> clearAlarm(TbContext ctx, TbMsg msg, Alarm alarm) {
ListenableFuture<JsonNode> asyncDetails = buildAlarmDetails(ctx, msg, alarm.getDetails()); ListenableFuture<JsonNode> asyncDetails = buildAlarmDetails(ctx, msg, alarm.getDetails());
return Futures.transformAsync(asyncDetails, details -> { return Futures.transformAsync(asyncDetails, details -> {
ListenableFuture<Boolean> clearFuture = ctx.getAlarmService().clearAlarm(alarm.getId(), details, System.currentTimeMillis()); ListenableFuture<Boolean> clearFuture = ctx.getAlarmService().clearAlarm(ctx.getTenantId(), alarm.getId(), details, System.currentTimeMillis());
return Futures.transformAsync(clearFuture, cleared -> { return Futures.transformAsync(clearFuture, cleared -> {
if (cleared && details != null) { if (cleared && details != null) {
alarm.setDetails(details); alarm.setDetails(details);

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

@ -91,7 +91,7 @@ public class TbCopyAttributesToEntityViewNode implements TbNode {
Set<AttributeKvEntry> attributes = JsonConverter.convertToAttributes(new JsonParser().parse(msg.getData())); Set<AttributeKvEntry> attributes = JsonConverter.convertToAttributes(new JsonParser().parse(msg.getData()));
List<AttributeKvEntry> filteredAttributes = List<AttributeKvEntry> filteredAttributes =
attributes.stream().filter(attr -> attributeContainsInEntityView(scope, attr.getKey(), entityView)).collect(Collectors.toList()); attributes.stream().filter(attr -> attributeContainsInEntityView(scope, attr.getKey(), entityView)).collect(Collectors.toList());
ctx.getTelemetryService().saveAndNotify(entityView.getId(), scope, filteredAttributes, ctx.getTelemetryService().saveAndNotify(ctx.getTenantId(), entityView.getId(), scope, filteredAttributes,
new FutureCallback<Void>() { new FutureCallback<Void>() {
@Override @Override
public void onSuccess(@Nullable Void result) { public void onSuccess(@Nullable Void result) {
@ -116,7 +116,7 @@ public class TbCopyAttributesToEntityViewNode implements TbNode {
List<String> filteredAttributes = List<String> filteredAttributes =
attributes.stream().filter(attr -> attributeContainsInEntityView(scope, attr, entityView)).collect(Collectors.toList()); attributes.stream().filter(attr -> attributeContainsInEntityView(scope, attr, entityView)).collect(Collectors.toList());
if (filteredAttributes != null && !filteredAttributes.isEmpty()) { if (filteredAttributes != null && !filteredAttributes.isEmpty()) {
ctx.getAttributesService().removeAll(entityView.getId(), scope, filteredAttributes); ctx.getAttributesService().removeAll(ctx.getTenantId(), entityView.getId(), scope, filteredAttributes);
transformAndTellNext(ctx, msg, entityView); transformAndTellNext(ctx, msg, entityView);
} }
} }

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/filter/TbCheckRelationNode.java

@ -67,7 +67,7 @@ public class TbCheckRelationNode implements TbNode {
to = EntityIdFactory.getByTypeAndId(config.getEntityType(), config.getEntityId()); to = EntityIdFactory.getByTypeAndId(config.getEntityType(), config.getEntityId());
from = msg.getOriginator(); from = msg.getOriginator();
} }
withCallback(ctx.getRelationService().checkRelation(from, to, config.getRelationType(), RelationTypeGroup.COMMON), withCallback(ctx.getRelationService().checkRelation(ctx.getTenantId(), from, to, config.getRelationType(), RelationTypeGroup.COMMON),
filterResult -> ctx.tellNext(msg, filterResult ? "True" : "False"), t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor()); filterResult -> ctx.tellNext(msg, filterResult ? "True" : "False"), t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor());
} }

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbAbstractGetAttributesNode.java

@ -77,7 +77,7 @@ public abstract class TbAbstractGetAttributesNode<C extends TbGetAttributesNodeC
if (CollectionUtils.isEmpty(keys)) { if (CollectionUtils.isEmpty(keys)) {
return Futures.immediateFuture(null); return Futures.immediateFuture(null);
} }
ListenableFuture<List<AttributeKvEntry>> latest = ctx.getAttributesService().find(entityId, scope, keys); ListenableFuture<List<AttributeKvEntry>> latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, scope, keys);
return Futures.transform(latest, l -> { return Futures.transform(latest, l -> {
l.forEach(r -> { l.forEach(r -> {
if (r.getValue() != null) { if (r.getValue() != null) {
@ -94,7 +94,7 @@ public abstract class TbAbstractGetAttributesNode<C extends TbGetAttributesNodeC
if (CollectionUtils.isEmpty(keys)) { if (CollectionUtils.isEmpty(keys)) {
return Futures.immediateFuture(null); return Futures.immediateFuture(null);
} }
ListenableFuture<List<TsKvEntry>> latest = ctx.getTimeseriesService().findLatest(entityId, keys); ListenableFuture<List<TsKvEntry>> latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, keys);
return Futures.transform(latest, l -> { return Futures.transform(latest, l -> {
l.forEach(r -> { l.forEach(r -> {
if (r.getValue() != null) { if (r.getValue() != null) {

4
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbEntityGetAttrNode.java

@ -71,13 +71,13 @@ public abstract class TbEntityGetAttrNode<T extends EntityId> implements TbNode
} }
private ListenableFuture<List<KvEntry>> getAttributesAsync(TbContext ctx, EntityId entityId) { private ListenableFuture<List<KvEntry>> getAttributesAsync(TbContext ctx, EntityId entityId) {
ListenableFuture<List<AttributeKvEntry>> latest = ctx.getAttributesService().find(entityId, SERVER_SCOPE, config.getAttrMapping().keySet()); ListenableFuture<List<AttributeKvEntry>> latest = ctx.getAttributesService().find(ctx.getTenantId(), entityId, SERVER_SCOPE, config.getAttrMapping().keySet());
return Futures.transform(latest, l -> return Futures.transform(latest, l ->
l.stream().map(i -> (KvEntry) i).collect(Collectors.toList())); l.stream().map(i -> (KvEntry) i).collect(Collectors.toList()));
} }
private ListenableFuture<List<KvEntry>> getLatestTelemetry(TbContext ctx, EntityId entityId) { private ListenableFuture<List<KvEntry>> getLatestTelemetry(TbContext ctx, EntityId entityId) {
ListenableFuture<List<TsKvEntry>> latest = ctx.getTimeseriesService().findLatest(entityId, config.getAttrMapping().keySet()); ListenableFuture<List<TsKvEntry>> latest = ctx.getTimeseriesService().findLatest(ctx.getTenantId(), entityId, config.getAttrMapping().keySet());
return Futures.transform(latest, l -> return Futures.transform(latest, l ->
l.stream().map(i -> (KvEntry) i).collect(Collectors.toList())); l.stream().map(i -> (KvEntry) i).collect(Collectors.toList()));
} }

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetTelemetryNode.java

@ -83,7 +83,7 @@ public class TbGetTelemetryNode implements TbNode {
} else { } else {
try { try {
List<ReadTsKvQuery> queries = buildQueries(); List<ReadTsKvQuery> queries = buildQueries();
ListenableFuture<List<TsKvEntry>> list = ctx.getTimeseriesService().findAll(msg.getOriginator(), queries); ListenableFuture<List<TsKvEntry>> list = ctx.getTimeseriesService().findAll(ctx.getTenantId(), msg.getOriginator(), queries);
DonAsynchron.withCallback(list, data -> { DonAsynchron.withCallback(list, data -> {
process(data, msg); process(data, msg);
TbMsg newMsg = ctx.newMsg(msg.getType(), msg.getOriginator(), msg.getMetaData(), msg.getData()); TbMsg newMsg = ctx.newMsg(msg.getType(), msg.getOriginator(), msg.getMetaData(), msg.getData());

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgAttributesNode.java

@ -64,7 +64,7 @@ public class TbMsgAttributesNode implements TbNode {
String src = msg.getData(); String src = msg.getData();
Set<AttributeKvEntry> attributes = JsonConverter.convertToAttributes(new JsonParser().parse(src)); Set<AttributeKvEntry> attributes = JsonConverter.convertToAttributes(new JsonParser().parse(src));
ctx.getTelemetryService().saveAndNotify(msg.getOriginator(), config.getScope(), new ArrayList<>(attributes), new TelemetryNodeCallback(ctx, msg)); ctx.getTelemetryService().saveAndNotify(ctx.getTenantId(), msg.getOriginator(), config.getScope(), new ArrayList<>(attributes), new TelemetryNodeCallback(ctx, msg));
if (msg.getOriginator().getEntityType() == EntityType.DEVICE && DataConstants.SHARED_SCOPE.equals(config.getScope())) { if (msg.getOriginator().getEntityType() == EntityType.DEVICE && DataConstants.SHARED_SCOPE.equals(config.getScope())) {
ctx.getTelemetryService().onSharedAttributesUpdate(ctx.getTenantId(), new DeviceId(msg.getOriginator().getId()), attributes); ctx.getTelemetryService().onSharedAttributesUpdate(ctx.getTenantId(), new DeviceId(msg.getOriginator().getId()), attributes);
} }

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/telemetry/TbMsgTimeseriesNode.java

@ -86,7 +86,7 @@ public class TbMsgTimeseriesNode implements TbNode {
} }
String ttlValue = msg.getMetaData().getValue("TTL"); String ttlValue = msg.getMetaData().getValue("TTL");
long ttl = !StringUtils.isEmpty(ttlValue) ? Long.valueOf(ttlValue) : config.getDefaultTTL(); long ttl = !StringUtils.isEmpty(ttlValue) ? Long.valueOf(ttlValue) : config.getDefaultTTL();
ctx.getTelemetryService().saveAndNotify(msg.getOriginator(), tsKvEntryList, ttl, new TelemetryNodeCallback(ctx, msg)); ctx.getTelemetryService().saveAndNotify(ctx.getTenantId(), msg.getOriginator(), tsKvEntryList, ttl, new TelemetryNodeCallback(ctx, msg));
} }
@Override @Override

6
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesCustomerIdAsyncLoader.java

@ -32,11 +32,11 @@ public class EntitiesCustomerIdAsyncLoader {
case CUSTOMER: case CUSTOMER:
return Futures.immediateFuture((CustomerId) original); return Futures.immediateFuture((CustomerId) original);
case USER: case USER:
return getCustomerAsync(ctx.getUserService().findUserByIdAsync((UserId) original)); return getCustomerAsync(ctx.getUserService().findUserByIdAsync(ctx.getTenantId(), (UserId) original));
case ASSET: case ASSET:
return getCustomerAsync(ctx.getAssetService().findAssetByIdAsync((AssetId) original)); return getCustomerAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), (AssetId) original));
case DEVICE: case DEVICE:
return getCustomerAsync(ctx.getDeviceService().findDeviceByIdAsync((DeviceId) original)); return getCustomerAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), (DeviceId) original));
default: default:
return Futures.immediateFailedFuture(new TbNodeException("Unexpected original EntityType " + original)); return Futures.immediateFailedFuture(new TbNodeException("Unexpected original EntityType " + original));
} }

28
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesFieldsAsyncLoader.java

@ -37,26 +37,26 @@ public class EntitiesFieldsAsyncLoader {
public static ListenableFuture<EntityFieldsData> findAsync(TbContext ctx, EntityId original) { public static ListenableFuture<EntityFieldsData> findAsync(TbContext ctx, EntityId original) {
switch (original.getEntityType()) { switch (original.getEntityType()) {
case TENANT: case TENANT:
return getAsync(ctx.getTenantService().findTenantByIdAsync((TenantId) original), return getAsync(ctx.getTenantService().findTenantByIdAsync(ctx.getTenantId(), (TenantId) original),
t -> new EntityFieldsData(t)); EntityFieldsData::new);
case CUSTOMER: case CUSTOMER:
return getAsync(ctx.getCustomerService().findCustomerByIdAsync((CustomerId) original), return getAsync(ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), (CustomerId) original),
t -> new EntityFieldsData(t)); EntityFieldsData::new);
case USER: case USER:
return getAsync(ctx.getUserService().findUserByIdAsync((UserId) original), return getAsync(ctx.getUserService().findUserByIdAsync(ctx.getTenantId(), (UserId) original),
t -> new EntityFieldsData(t)); EntityFieldsData::new);
case ASSET: case ASSET:
return getAsync(ctx.getAssetService().findAssetByIdAsync((AssetId) original), return getAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), (AssetId) original),
t -> new EntityFieldsData(t)); EntityFieldsData::new);
case DEVICE: case DEVICE:
return getAsync(ctx.getDeviceService().findDeviceByIdAsync((DeviceId) original), return getAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), (DeviceId) original),
t -> new EntityFieldsData(t)); EntityFieldsData::new);
case ALARM: case ALARM:
return getAsync(ctx.getAlarmService().findAlarmByIdAsync((AlarmId) original), return getAsync(ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), (AlarmId) original),
t -> new EntityFieldsData(t)); EntityFieldsData::new);
case RULE_CHAIN: case RULE_CHAIN:
return getAsync(ctx.getRuleChainService().findRuleChainByIdAsync((RuleChainId) original), return getAsync(ctx.getRuleChainService().findRuleChainByIdAsync(ctx.getTenantId(), (RuleChainId) original),
t -> new EntityFieldsData(t)); EntityFieldsData::new);
default: default:
return Futures.immediateFailedFuture(new TbNodeException("Unexpected original EntityType " + original)); return Futures.immediateFailedFuture(new TbNodeException("Unexpected original EntityType " + original));
} }

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesRelatedDeviceIdAsyncLoader.java

@ -37,7 +37,7 @@ public class EntitiesRelatedDeviceIdAsyncLoader {
DeviceService deviceService = ctx.getDeviceService(); DeviceService deviceService = ctx.getDeviceService();
DeviceSearchQuery query = buildQuery(originator, deviceRelationsQuery); DeviceSearchQuery query = buildQuery(originator, deviceRelationsQuery);
ListenableFuture<List<Device>> asyncDevices = deviceService.findDevicesByQuery(query); ListenableFuture<List<Device>> asyncDevices = deviceService.findDevicesByQuery(ctx.getTenantId(), query);
return Futures.transformAsync(asyncDevices, d -> CollectionUtils.isNotEmpty(d) ? Futures.immediateFuture(d.get(0).getId()) return Futures.transformAsync(asyncDevices, d -> CollectionUtils.isNotEmpty(d) ? Futures.immediateFuture(d.get(0).getId())
: Futures.immediateFuture(null)); : Futures.immediateFuture(null));

2
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesRelatedEntityIdAsyncLoader.java

@ -36,7 +36,7 @@ public class EntitiesRelatedEntityIdAsyncLoader {
RelationsQuery relationsQuery) { RelationsQuery relationsQuery) {
RelationService relationService = ctx.getRelationService(); RelationService relationService = ctx.getRelationService();
EntityRelationsQuery query = buildQuery(originator, relationsQuery); EntityRelationsQuery query = buildQuery(originator, relationsQuery);
ListenableFuture<List<EntityRelation>> asyncRelation = relationService.findByQuery(query); ListenableFuture<List<EntityRelation>> asyncRelation = relationService.findByQuery(ctx.getTenantId(), query);
if (relationsQuery.getDirection() == EntitySearchDirection.FROM) { if (relationsQuery.getDirection() == EntitySearchDirection.FROM) {
return Futures.transformAsync(asyncRelation, r -> CollectionUtils.isNotEmpty(r) ? Futures.immediateFuture(r.get(0).getTo()) return Futures.transformAsync(asyncRelation, r -> CollectionUtils.isNotEmpty(r) ? Futures.immediateFuture(r.get(0).getTo())
: Futures.immediateFuture(null)); : Futures.immediateFuture(null));

12
rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/util/EntitiesTenantIdAsyncLoader.java

@ -32,17 +32,17 @@ public class EntitiesTenantIdAsyncLoader {
case TENANT: case TENANT:
return Futures.immediateFuture((TenantId) original); return Futures.immediateFuture((TenantId) original);
case CUSTOMER: case CUSTOMER:
return getTenantAsync(ctx.getCustomerService().findCustomerByIdAsync((CustomerId) original)); return getTenantAsync(ctx.getCustomerService().findCustomerByIdAsync(ctx.getTenantId(), (CustomerId) original));
case USER: case USER:
return getTenantAsync(ctx.getUserService().findUserByIdAsync((UserId) original)); return getTenantAsync(ctx.getUserService().findUserByIdAsync(ctx.getTenantId(), (UserId) original));
case ASSET: case ASSET:
return getTenantAsync(ctx.getAssetService().findAssetByIdAsync((AssetId) original)); return getTenantAsync(ctx.getAssetService().findAssetByIdAsync(ctx.getTenantId(), (AssetId) original));
case DEVICE: case DEVICE:
return getTenantAsync(ctx.getDeviceService().findDeviceByIdAsync((DeviceId) original)); return getTenantAsync(ctx.getDeviceService().findDeviceByIdAsync(ctx.getTenantId(), (DeviceId) original));
case ALARM: case ALARM:
return getTenantAsync(ctx.getAlarmService().findAlarmByIdAsync((AlarmId) original)); return getTenantAsync(ctx.getAlarmService().findAlarmByIdAsync(ctx.getTenantId(), (AlarmId) original));
case RULE_CHAIN: case RULE_CHAIN:
return getTenantAsync(ctx.getRuleChainService().findRuleChainByIdAsync((RuleChainId) original)); return getTenantAsync(ctx.getRuleChainService().findRuleChainByIdAsync(ctx.getTenantId(), (RuleChainId) original));
default: default:
return Futures.immediateFailedFuture(new TbNodeException("Unexpected original EntityType " + original)); return Futures.immediateFailedFuture(new TbNodeException("Unexpected original EntityType " + original));
} }

2
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/action/TbAlarmNodeTest.java

@ -269,7 +269,7 @@ public class TbAlarmNodeTest {
// when(detailsJs.executeJson(msg)).thenReturn(null); // when(detailsJs.executeJson(msg)).thenReturn(null);
when(alarmService.findLatestByOriginatorAndType(tenantId, originator, "SomeType")).thenReturn(Futures.immediateFuture(activeAlarm)); when(alarmService.findLatestByOriginatorAndType(tenantId, originator, "SomeType")).thenReturn(Futures.immediateFuture(activeAlarm));
when(alarmService.clearAlarm(eq(activeAlarm.getId()), org.mockito.Mockito.any(JsonNode.class), anyLong())).thenReturn(Futures.immediateFuture(true)); when(alarmService.clearAlarm(eq(activeAlarm.getTenantId()), eq(activeAlarm.getId()), org.mockito.Mockito.any(JsonNode.class), anyLong())).thenReturn(Futures.immediateFuture(true));
// doAnswer((Answer<Alarm>) invocationOnMock -> (Alarm) (invocationOnMock.getArguments())[0]).when(alarmService).createOrUpdateAlarm(activeAlarm); // doAnswer((Answer<Alarm>) invocationOnMock -> (Alarm) (invocationOnMock.getArguments())[0]).when(alarmService).createOrUpdateAlarm(activeAlarm);
node.onMsg(ctx, msg); node.onMsg(ctx, msg);

24
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/metadata/TbGetCustomerAttributeNodeTest.java

@ -48,6 +48,8 @@ import java.util.Map;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.same; import static org.mockito.Matchers.same;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -103,10 +105,10 @@ public class TbGetCustomerAttributeNodeTest {
msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getUserService()).thenReturn(userService); when(ctx.getUserService()).thenReturn(userService);
when(userService.findUserByIdAsync(userId)).thenReturn(Futures.immediateFuture(user)); when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user));
when(ctx.getAttributesService()).thenReturn(attributesService); when(ctx.getAttributesService()).thenReturn(attributesService);
when(attributesService.find(customerId, SERVER_SCOPE, Collections.singleton("temperature"))) when(attributesService.find(any(), eq(customerId), eq(SERVER_SCOPE), eq(Collections.singleton("temperature"))))
.thenThrow(new IllegalStateException("something wrong")); .thenThrow(new IllegalStateException("something wrong"));
node.onMsg(ctx, msg); node.onMsg(ctx, msg);
@ -128,10 +130,10 @@ public class TbGetCustomerAttributeNodeTest {
msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getUserService()).thenReturn(userService); when(ctx.getUserService()).thenReturn(userService);
when(userService.findUserByIdAsync(userId)).thenReturn(Futures.immediateFuture(user)); when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user));
when(ctx.getAttributesService()).thenReturn(attributesService); when(ctx.getAttributesService()).thenReturn(attributesService);
when(attributesService.find(customerId, SERVER_SCOPE, Collections.singleton("temperature"))) when(attributesService.find(any(), eq(customerId), eq(SERVER_SCOPE), eq(Collections.singleton("temperature"))))
.thenReturn(Futures.immediateFailedFuture(new IllegalStateException("something wrong"))); .thenReturn(Futures.immediateFailedFuture(new IllegalStateException("something wrong")));
node.onMsg(ctx, msg); node.onMsg(ctx, msg);
@ -153,7 +155,7 @@ public class TbGetCustomerAttributeNodeTest {
msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getUserService()).thenReturn(userService); when(ctx.getUserService()).thenReturn(userService);
when(userService.findUserByIdAsync(userId)).thenReturn(Futures.immediateFuture(null)); when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(null));
node.onMsg(ctx, msg); node.onMsg(ctx, msg);
@ -178,7 +180,7 @@ public class TbGetCustomerAttributeNodeTest {
msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", userId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getUserService()).thenReturn(userService); when(ctx.getUserService()).thenReturn(userService);
when(userService.findUserByIdAsync(userId)).thenReturn(Futures.immediateFuture(user)); when(userService.findUserByIdAsync(any(), eq(userId))).thenReturn(Futures.immediateFuture(user));
entityAttributeFetched(customerId); entityAttributeFetched(customerId);
} }
@ -193,7 +195,7 @@ public class TbGetCustomerAttributeNodeTest {
msg = new TbMsg(UUIDs.timeBased(), "USER", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getAssetService()).thenReturn(assetService); when(ctx.getAssetService()).thenReturn(assetService);
when(assetService.findAssetByIdAsync(assetId)).thenReturn(Futures.immediateFuture(asset)); when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(asset));
entityAttributeFetched(customerId); entityAttributeFetched(customerId);
} }
@ -208,7 +210,7 @@ public class TbGetCustomerAttributeNodeTest {
msg = new TbMsg(UUIDs.timeBased(), "USER", deviceId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", deviceId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getDeviceService()).thenReturn(deviceService); when(ctx.getDeviceService()).thenReturn(deviceService);
when(deviceService.findDeviceByIdAsync(deviceId)).thenReturn(Futures.immediateFuture(device)); when(deviceService.findDeviceByIdAsync(any(), eq(deviceId))).thenReturn(Futures.immediateFuture(device));
entityAttributeFetched(customerId); entityAttributeFetched(customerId);
} }
@ -235,12 +237,12 @@ public class TbGetCustomerAttributeNodeTest {
msg = new TbMsg(UUIDs.timeBased(), "USER", deviceId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); msg = new TbMsg(UUIDs.timeBased(), "USER", deviceId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getDeviceService()).thenReturn(deviceService); when(ctx.getDeviceService()).thenReturn(deviceService);
when(deviceService.findDeviceByIdAsync(deviceId)).thenReturn(Futures.immediateFuture(device)); when(deviceService.findDeviceByIdAsync(any(), eq(deviceId))).thenReturn(Futures.immediateFuture(device));
List<TsKvEntry> timeseries = Lists.newArrayList(new BasicTsKvEntry(1L, new StringDataEntry("temperature", "highest"))); List<TsKvEntry> timeseries = Lists.newArrayList(new BasicTsKvEntry(1L, new StringDataEntry("temperature", "highest")));
when(ctx.getTimeseriesService()).thenReturn(timeseriesService); when(ctx.getTimeseriesService()).thenReturn(timeseriesService);
when(timeseriesService.findLatest(customerId, Collections.singleton("temperature"))) when(timeseriesService.findLatest(any(), eq(customerId), eq(Collections.singleton("temperature"))))
.thenReturn(Futures.immediateFuture(timeseries)); .thenReturn(Futures.immediateFuture(timeseries));
node.onMsg(ctx, msg); node.onMsg(ctx, msg);
@ -252,7 +254,7 @@ public class TbGetCustomerAttributeNodeTest {
List<AttributeKvEntry> attributes = Lists.newArrayList(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L)); List<AttributeKvEntry> attributes = Lists.newArrayList(new BaseAttributeKvEntry(new StringDataEntry("temperature", "high"), 1L));
when(ctx.getAttributesService()).thenReturn(attributesService); when(ctx.getAttributesService()).thenReturn(attributesService);
when(attributesService.find(customerId, SERVER_SCOPE, Collections.singleton("temperature"))) when(attributesService.find(any(), eq(customerId), eq(SERVER_SCOPE), eq(Collections.singleton("temperature"))))
.thenReturn(Futures.immediateFuture(attributes)); .thenReturn(Futures.immediateFuture(attributes));
node.onMsg(ctx, msg); node.onMsg(ctx, msg);

8
rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/transform/TbChangeOriginatorNodeTest.java

@ -42,6 +42,8 @@ import org.thingsboard.server.dao.asset.AssetService;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.same; import static org.mockito.Matchers.same;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -92,7 +94,7 @@ public class TbChangeOriginatorNodeTest {
TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getAssetService()).thenReturn(assetService); when(ctx.getAssetService()).thenReturn(assetService);
when(assetService.findAssetByIdAsync(assetId)).thenReturn(Futures.immediateFuture(asset)); when(assetService.findAssetByIdAsync(any(),eq( assetId))).thenReturn(Futures.immediateFuture(asset));
node.onMsg(ctx, msg); node.onMsg(ctx, msg);
@ -120,7 +122,7 @@ public class TbChangeOriginatorNodeTest {
TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getAssetService()).thenReturn(assetService); when(ctx.getAssetService()).thenReturn(assetService);
when(assetService.findAssetByIdAsync(assetId)).thenReturn(Futures.immediateFuture(asset)); when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(asset));
node.onMsg(ctx, msg); node.onMsg(ctx, msg);
ArgumentCaptor<TbMsg> msgCaptor = ArgumentCaptor.forClass(TbMsg.class); ArgumentCaptor<TbMsg> msgCaptor = ArgumentCaptor.forClass(TbMsg.class);
@ -147,7 +149,7 @@ public class TbChangeOriginatorNodeTest {
TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L); TbMsg msg = new TbMsg(UUIDs.timeBased(), "ASSET", assetId, new TbMsgMetaData(), "{}", ruleChainId, ruleNodeId, 0L);
when(ctx.getAssetService()).thenReturn(assetService); when(ctx.getAssetService()).thenReturn(assetService);
when(assetService.findAssetByIdAsync(assetId)).thenReturn(Futures.immediateFuture(null)); when(assetService.findAssetByIdAsync(any(), eq(assetId))).thenReturn(Futures.immediateFuture(null));
node.onMsg(ctx, msg); node.onMsg(ctx, msg);
verify(ctx).tellNext(same(msg), same(FAILURE)); verify(ctx).tellNext(same(msg), same(FAILURE));

Loading…
Cancel
Save