Commit 104450c10276ba45ffd651e9a55a54288c71a107

Authored by Andrew Shvayka
1 parent c84bcd51

Refactoring of DAO layer to support rate limiting by tenant

Showing 68 changed files with 860 additions and 828 deletions

Too many changes to show.

To preserve performance only 68 of 140 files are displayed.

@@ -143,6 +143,9 @@ cassandra: @@ -143,6 +143,9 @@ cassandra:
143 concurrent_limit: "${CASSANDRA_QUERY_CONCURRENT_LIMIT:1000}" 143 concurrent_limit: "${CASSANDRA_QUERY_CONCURRENT_LIMIT:1000}"
144 permit_max_wait_time: "${PERMIT_MAX_WAIT_TIME:120000}" 144 permit_max_wait_time: "${PERMIT_MAX_WAIT_TIME:120000}"
145 rate_limit_print_interval_ms: "${CASSANDRA_QUERY_RATE_LIMIT_PRINT_MS:10000}" 145 rate_limit_print_interval_ms: "${CASSANDRA_QUERY_RATE_LIMIT_PRINT_MS:10000}"
  146 + tenant_rate_limits:
  147 + enabled: "${CASSANDRA_QUERY_TENANT_RATE_LIMITS_ENABLED:false}"
  148 + configuration: "${CASSANDRA_QUERY_TENANT_RATE_LIMITS_VALUE:1000:1,30000:60}"
146 149
147 # SQL configuration parameters 150 # SQL configuration parameters
148 sql: 151 sql:
@@ -61,6 +61,10 @@ @@ -61,6 +61,10 @@
61 <artifactId>logback-classic</artifactId> 61 <artifactId>logback-classic</artifactId>
62 </dependency> 62 </dependency>
63 <dependency> 63 <dependency>
  64 + <groupId>com.github.vladimir-bukhtoyarov</groupId>
  65 + <artifactId>bucket4j-core</artifactId>
  66 + </dependency>
  67 + <dependency>
64 <groupId>com.google.protobuf</groupId> 68 <groupId>com.google.protobuf</groupId>
65 <artifactId>protobuf-java</artifactId> 69 <artifactId>protobuf-java</artifactId>
66 <scope>provided</scope> 70 <scope>provided</scope>
common/message/src/main/java/org/thingsboard/server/common/msg/tools/TbRateLimits.java renamed from common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/TbTransportRateLimits.java
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.thingsboard.server.common.transport.service; 16 +package org.thingsboard.server.common.msg.tools;
17 17
18 import io.github.bucket4j.Bandwidth; 18 import io.github.bucket4j.Bandwidth;
19 import io.github.bucket4j.Bucket4j; 19 import io.github.bucket4j.Bucket4j;
@@ -25,10 +25,10 @@ import java.time.Duration; @@ -25,10 +25,10 @@ import java.time.Duration;
25 /** 25 /**
26 * Created by ashvayka on 22.10.18. 26 * Created by ashvayka on 22.10.18.
27 */ 27 */
28 -class TbTransportRateLimits { 28 +public class TbRateLimits {
29 private final LocalBucket bucket; 29 private final LocalBucket bucket;
30 30
31 - public TbTransportRateLimits(String limitsConfiguration) { 31 + public TbRateLimits(String limitsConfiguration) {
32 LocalBucketBuilder builder = Bucket4j.builder(); 32 LocalBucketBuilder builder = Bucket4j.builder();
33 boolean initialized = false; 33 boolean initialized = false;
34 for (String limitSrc : limitsConfiguration.split(",")) { 34 for (String limitSrc : limitsConfiguration.split(",")) {
@@ -46,7 +46,7 @@ class TbTransportRateLimits { @@ -46,7 +46,7 @@ class TbTransportRateLimits {
46 46
47 } 47 }
48 48
49 - boolean tryConsume() { 49 + public boolean tryConsume() {
50 return bucket.tryConsume(1); 50 return bucket.tryConsume(1);
51 } 51 }
52 52
@@ -99,10 +99,6 @@ @@ -99,10 +99,6 @@
99 <groupId>com.google.protobuf</groupId> 99 <groupId>com.google.protobuf</groupId>
100 <artifactId>protobuf-java</artifactId> 100 <artifactId>protobuf-java</artifactId>
101 </dependency> 101 </dependency>
102 - <dependency>  
103 - <groupId>com.github.vladimir-bukhtoyarov</groupId>  
104 - <artifactId>bucket4j-core</artifactId>  
105 - </dependency>  
106 </dependencies> 102 </dependencies>
107 103
108 <build> 104 <build>
@@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Value; @@ -20,6 +20,7 @@ import org.springframework.beans.factory.annotation.Value;
20 import org.thingsboard.server.common.data.EntityType; 20 import org.thingsboard.server.common.data.EntityType;
21 import org.thingsboard.server.common.data.id.DeviceId; 21 import org.thingsboard.server.common.data.id.DeviceId;
22 import org.thingsboard.server.common.data.id.TenantId; 22 import org.thingsboard.server.common.data.id.TenantId;
  23 +import org.thingsboard.server.common.msg.tools.TbRateLimits;
23 import org.thingsboard.server.common.transport.SessionMsgListener; 24 import org.thingsboard.server.common.transport.SessionMsgListener;
24 import org.thingsboard.server.common.transport.TransportService; 25 import org.thingsboard.server.common.transport.TransportService;
25 import org.thingsboard.server.common.transport.TransportServiceCallback; 26 import org.thingsboard.server.common.transport.TransportServiceCallback;
@@ -58,8 +59,8 @@ public abstract class AbstractTransportService implements TransportService { @@ -58,8 +59,8 @@ public abstract class AbstractTransportService implements TransportService {
58 private ConcurrentMap<UUID, SessionMetaData> sessions = new ConcurrentHashMap<>(); 59 private ConcurrentMap<UUID, SessionMetaData> sessions = new ConcurrentHashMap<>();
59 60
60 //TODO: Implement cleanup of this maps. 61 //TODO: Implement cleanup of this maps.
61 - private ConcurrentMap<TenantId, TbTransportRateLimits> perTenantLimits = new ConcurrentHashMap<>();  
62 - private ConcurrentMap<DeviceId, TbTransportRateLimits> perDeviceLimits = new ConcurrentHashMap<>(); 62 + private ConcurrentMap<TenantId, TbRateLimits> perTenantLimits = new ConcurrentHashMap<>();
  63 + private ConcurrentMap<DeviceId, TbRateLimits> perDeviceLimits = new ConcurrentHashMap<>();
63 64
64 @Override 65 @Override
65 public void registerAsyncSession(TransportProtos.SessionInfoProto sessionInfo, SessionMsgListener listener) { 66 public void registerAsyncSession(TransportProtos.SessionInfoProto sessionInfo, SessionMsgListener listener) {
@@ -204,7 +205,7 @@ public abstract class AbstractTransportService implements TransportService { @@ -204,7 +205,7 @@ public abstract class AbstractTransportService implements TransportService {
204 return true; 205 return true;
205 } 206 }
206 TenantId tenantId = new TenantId(new UUID(sessionInfo.getTenantIdMSB(), sessionInfo.getTenantIdLSB())); 207 TenantId tenantId = new TenantId(new UUID(sessionInfo.getTenantIdMSB(), sessionInfo.getTenantIdLSB()));
207 - TbTransportRateLimits rateLimits = perTenantLimits.computeIfAbsent(tenantId, id -> new TbTransportRateLimits(perTenantLimitsConf)); 208 + TbRateLimits rateLimits = perTenantLimits.computeIfAbsent(tenantId, id -> new TbRateLimits(perTenantLimitsConf));
208 if (!rateLimits.tryConsume()) { 209 if (!rateLimits.tryConsume()) {
209 if (callback != null) { 210 if (callback != null) {
210 callback.onError(new TbRateLimitsException(EntityType.TENANT)); 211 callback.onError(new TbRateLimitsException(EntityType.TENANT));
@@ -215,7 +216,7 @@ public abstract class AbstractTransportService implements TransportService { @@ -215,7 +216,7 @@ public abstract class AbstractTransportService implements TransportService {
215 return false; 216 return false;
216 } 217 }
217 DeviceId deviceId = new DeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB())); 218 DeviceId deviceId = new DeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
218 - rateLimits = perDeviceLimits.computeIfAbsent(deviceId, id -> new TbTransportRateLimits(perDevicesLimitsConf)); 219 + rateLimits = perDeviceLimits.computeIfAbsent(deviceId, id -> new TbRateLimits(perDevicesLimitsConf));
219 if (!rateLimits.tryConsume()) { 220 if (!rateLimits.tryConsume()) {
220 if (callback != null) { 221 if (callback != null) {
221 callback.onError(new TbRateLimitsException(EntityType.DEVICE)); 222 callback.onError(new TbRateLimitsException(EntityType.DEVICE));
@@ -271,8 +272,8 @@ public abstract class AbstractTransportService implements TransportService { @@ -271,8 +272,8 @@ public abstract class AbstractTransportService implements TransportService {
271 public void init() { 272 public void init() {
272 if (rateLimitEnabled) { 273 if (rateLimitEnabled) {
273 //Just checking the configuration parameters 274 //Just checking the configuration parameters
274 - new TbTransportRateLimits(perTenantLimitsConf);  
275 - new TbTransportRateLimits(perDevicesLimitsConf); 275 + new TbRateLimits(perTenantLimitsConf);
  276 + new TbRateLimits(perDevicesLimitsConf);
276 } 277 }
277 this.schedulerExecutor = Executors.newSingleThreadScheduledExecutor(); 278 this.schedulerExecutor = Executors.newSingleThreadScheduledExecutor();
278 this.transportCallbackExecutor = new ThreadPoolExecutor(0, 20, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); 279 this.transportCallbackExecutor = new ThreadPoolExecutor(0, 20, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
@@ -16,20 +16,21 @@ @@ -16,20 +16,21 @@
16 package org.thingsboard.server.dao; 16 package org.thingsboard.server.dao;
17 17
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
  19 +import org.thingsboard.server.common.data.id.TenantId;
19 20
20 import java.util.List; 21 import java.util.List;
21 import java.util.UUID; 22 import java.util.UUID;
22 23
23 public interface Dao<T> { 24 public interface Dao<T> {
24 25
25 - List<T> find(); 26 + List<T> find(TenantId tenantId);
26 27
27 - T findById(UUID id); 28 + T findById(TenantId tenantId, UUID id);
28 29
29 - ListenableFuture<T> findByIdAsync(UUID id); 30 + ListenableFuture<T> findByIdAsync(TenantId tenantId, UUID id);
30 31
31 - T save(T t); 32 + T save(TenantId tenantId, T t);
32 33
33 - boolean removeById(UUID id); 34 + boolean removeById(TenantId tenantId, UUID id);
34 35
35 } 36 }
@@ -33,9 +33,9 @@ public interface AlarmDao extends Dao<Alarm> { @@ -33,9 +33,9 @@ public interface AlarmDao extends Dao<Alarm> {
33 33
34 ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type); 34 ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
35 35
36 - ListenableFuture<Alarm> findAlarmByIdAsync(UUID key); 36 + ListenableFuture<Alarm> findAlarmByIdAsync(TenantId tenantId, UUID key);
37 37
38 - Alarm save(Alarm alarm); 38 + Alarm save(TenantId tenantId, Alarm alarm);
39 39
40 - ListenableFuture<List<AlarmInfo>> findAlarms(AlarmQuery query); 40 + ListenableFuture<List<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query);
41 } 41 }
@@ -35,17 +35,17 @@ public interface AlarmService { @@ -35,17 +35,17 @@ public interface AlarmService {
35 35
36 Alarm createOrUpdateAlarm(Alarm alarm); 36 Alarm createOrUpdateAlarm(Alarm alarm);
37 37
38 - ListenableFuture<Boolean> ackAlarm(AlarmId alarmId, long ackTs); 38 + ListenableFuture<Boolean> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTs);
39 39
40 - ListenableFuture<Boolean> clearAlarm(AlarmId alarmId, JsonNode details, long ackTs); 40 + ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long ackTs);
41 41
42 - ListenableFuture<Alarm> findAlarmByIdAsync(AlarmId alarmId); 42 + ListenableFuture<Alarm> findAlarmByIdAsync(TenantId tenantId, AlarmId alarmId);
43 43
44 - ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(AlarmId alarmId); 44 + ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(TenantId tenantId, AlarmId alarmId);
45 45
46 - ListenableFuture<TimePageData<AlarmInfo>> findAlarms(AlarmQuery query); 46 + ListenableFuture<TimePageData<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query);
47 47
48 - AlarmSeverity findHighestAlarmSeverity(EntityId entityId, AlarmSearchStatus alarmSearchStatus, 48 + AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus,
49 AlarmStatus alarmStatus); 49 AlarmStatus alarmStatus);
50 50
51 ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type); 51 ListenableFuture<Alarm> findLatestByOriginatorAndType(TenantId tenantId, EntityId originator, String type);
@@ -91,7 +91,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -91,7 +91,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
91 91
92 @Override 92 @Override
93 public Alarm createOrUpdateAlarm(Alarm alarm) { 93 public Alarm createOrUpdateAlarm(Alarm alarm) {
94 - alarmDataValidator.validate(alarm); 94 + alarmDataValidator.validate(alarm, Alarm::getTenantId);
95 try { 95 try {
96 if (alarm.getStartTs() == 0L) { 96 if (alarm.getStartTs() == 0L) {
97 alarm.setStartTs(System.currentTimeMillis()); 97 alarm.setStartTs(System.currentTimeMillis());
@@ -120,7 +120,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -120,7 +120,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
120 120
121 private Alarm createAlarm(Alarm alarm) throws InterruptedException, ExecutionException { 121 private Alarm createAlarm(Alarm alarm) throws InterruptedException, ExecutionException {
122 log.debug("New Alarm : {}", alarm); 122 log.debug("New Alarm : {}", alarm);
123 - Alarm saved = alarmDao.save(alarm); 123 + Alarm saved = alarmDao.save(alarm.getTenantId(), alarm);
124 createAlarmRelations(saved); 124 createAlarmRelations(saved);
125 return saved; 125 return saved;
126 } 126 }
@@ -129,17 +129,17 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -129,17 +129,17 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
129 if (alarm.isPropagate()) { 129 if (alarm.isPropagate()) {
130 EntityRelationsQuery query = new EntityRelationsQuery(); 130 EntityRelationsQuery query = new EntityRelationsQuery();
131 query.setParameters(new RelationsSearchParameters(alarm.getOriginator(), EntitySearchDirection.TO, Integer.MAX_VALUE)); 131 query.setParameters(new RelationsSearchParameters(alarm.getOriginator(), EntitySearchDirection.TO, Integer.MAX_VALUE));
132 - List<EntityId> parentEntities = relationService.findByQuery(query).get().stream().map(r -> r.getFrom()).collect(Collectors.toList()); 132 + List<EntityId> parentEntities = relationService.findByQuery(alarm.getTenantId(), query).get().stream().map(EntityRelation::getFrom).collect(Collectors.toList());
133 for (EntityId parentId : parentEntities) { 133 for (EntityId parentId : parentEntities) {
134 - createAlarmRelation(parentId, alarm.getId(), alarm.getStatus(), true); 134 + createAlarmRelation(alarm.getTenantId(), parentId, alarm.getId(), alarm.getStatus(), true);
135 } 135 }
136 } 136 }
137 - createAlarmRelation(alarm.getOriginator(), alarm.getId(), alarm.getStatus(), true); 137 + createAlarmRelation(alarm.getTenantId(), alarm.getOriginator(), alarm.getId(), alarm.getStatus(), true);
138 } 138 }
139 139
140 private ListenableFuture<Alarm> updateAlarm(Alarm update) { 140 private ListenableFuture<Alarm> updateAlarm(Alarm update) {
141 - alarmDataValidator.validate(update);  
142 - return getAndUpdate(update.getId(), new Function<Alarm, Alarm>() { 141 + alarmDataValidator.validate(update, Alarm::getTenantId);
  142 + return getAndUpdate(update.getTenantId(), update.getId(), new Function<Alarm, Alarm>() {
143 @Nullable 143 @Nullable
144 @Override 144 @Override
145 public Alarm apply(@Nullable Alarm alarm) { 145 public Alarm apply(@Nullable Alarm alarm) {
@@ -157,7 +157,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -157,7 +157,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
157 AlarmStatus newStatus = newAlarm.getStatus(); 157 AlarmStatus newStatus = newAlarm.getStatus();
158 boolean oldPropagate = oldAlarm.isPropagate(); 158 boolean oldPropagate = oldAlarm.isPropagate();
159 boolean newPropagate = newAlarm.isPropagate(); 159 boolean newPropagate = newAlarm.isPropagate();
160 - Alarm result = alarmDao.save(merge(oldAlarm, newAlarm)); 160 + Alarm result = alarmDao.save(newAlarm.getTenantId(), merge(oldAlarm, newAlarm));
161 if (!oldPropagate && newPropagate) { 161 if (!oldPropagate && newPropagate) {
162 try { 162 try {
163 createAlarmRelations(result); 163 createAlarmRelations(result);
@@ -172,8 +172,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -172,8 +172,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
172 } 172 }
173 173
174 @Override 174 @Override
175 - public ListenableFuture<Boolean> ackAlarm(AlarmId alarmId, long ackTime) {  
176 - return getAndUpdate(alarmId, new Function<Alarm, Boolean>() { 175 + public ListenableFuture<Boolean> ackAlarm(TenantId tenantId, AlarmId alarmId, long ackTime) {
  176 + return getAndUpdate(tenantId, alarmId, new Function<Alarm, Boolean>() {
177 @Nullable 177 @Nullable
178 @Override 178 @Override
179 public Boolean apply(@Nullable Alarm alarm) { 179 public Boolean apply(@Nullable Alarm alarm) {
@@ -184,7 +184,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -184,7 +184,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
184 AlarmStatus newStatus = oldStatus.isCleared() ? AlarmStatus.CLEARED_ACK : AlarmStatus.ACTIVE_ACK; 184 AlarmStatus newStatus = oldStatus.isCleared() ? AlarmStatus.CLEARED_ACK : AlarmStatus.ACTIVE_ACK;
185 alarm.setStatus(newStatus); 185 alarm.setStatus(newStatus);
186 alarm.setAckTs(ackTime); 186 alarm.setAckTs(ackTime);
187 - alarmDao.save(alarm); 187 + alarmDao.save(alarm.getTenantId(), alarm);
188 updateRelations(alarm, oldStatus, newStatus); 188 updateRelations(alarm, oldStatus, newStatus);
189 return true; 189 return true;
190 } 190 }
@@ -193,8 +193,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -193,8 +193,8 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
193 } 193 }
194 194
195 @Override 195 @Override
196 - public ListenableFuture<Boolean> clearAlarm(AlarmId alarmId, JsonNode details, long clearTime) {  
197 - return getAndUpdate(alarmId, new Function<Alarm, Boolean>() { 196 + public ListenableFuture<Boolean> clearAlarm(TenantId tenantId, AlarmId alarmId, JsonNode details, long clearTime) {
  197 + return getAndUpdate(tenantId, alarmId, new Function<Alarm, Boolean>() {
198 @Nullable 198 @Nullable
199 @Override 199 @Override
200 public Boolean apply(@Nullable Alarm alarm) { 200 public Boolean apply(@Nullable Alarm alarm) {
@@ -208,7 +208,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -208,7 +208,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
208 if (details != null) { 208 if (details != null) {
209 alarm.setDetails(details); 209 alarm.setDetails(details);
210 } 210 }
211 - alarmDao.save(alarm); 211 + alarmDao.save(alarm.getTenantId(), alarm);
212 updateRelations(alarm, oldStatus, newStatus); 212 updateRelations(alarm, oldStatus, newStatus);
213 return true; 213 return true;
214 } 214 }
@@ -217,21 +217,21 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -217,21 +217,21 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
217 } 217 }
218 218
219 @Override 219 @Override
220 - public ListenableFuture<Alarm> findAlarmByIdAsync(AlarmId alarmId) { 220 + public ListenableFuture<Alarm> findAlarmByIdAsync(TenantId tenantId, AlarmId alarmId) {
221 log.trace("Executing findAlarmById [{}]", alarmId); 221 log.trace("Executing findAlarmById [{}]", alarmId);
222 validateId(alarmId, "Incorrect alarmId " + alarmId); 222 validateId(alarmId, "Incorrect alarmId " + alarmId);
223 - return alarmDao.findAlarmByIdAsync(alarmId.getId()); 223 + return alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId());
224 } 224 }
225 225
226 @Override 226 @Override
227 - public ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(AlarmId alarmId) { 227 + public ListenableFuture<AlarmInfo> findAlarmInfoByIdAsync(TenantId tenantId, AlarmId alarmId) {
228 log.trace("Executing findAlarmInfoByIdAsync [{}]", alarmId); 228 log.trace("Executing findAlarmInfoByIdAsync [{}]", alarmId);
229 validateId(alarmId, "Incorrect alarmId " + alarmId); 229 validateId(alarmId, "Incorrect alarmId " + alarmId);
230 - return Futures.transformAsync(alarmDao.findAlarmByIdAsync(alarmId.getId()), 230 + return Futures.transformAsync(alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId()),
231 a -> { 231 a -> {
232 AlarmInfo alarmInfo = new AlarmInfo(a); 232 AlarmInfo alarmInfo = new AlarmInfo(a);
233 return Futures.transform( 233 return Futures.transform(
234 - entityService.fetchEntityNameAsync(alarmInfo.getOriginator()), originatorName -> { 234 + entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> {
235 alarmInfo.setOriginatorName(originatorName); 235 alarmInfo.setOriginatorName(originatorName);
236 return alarmInfo; 236 return alarmInfo;
237 } 237 }
@@ -240,14 +240,14 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -240,14 +240,14 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
240 } 240 }
241 241
242 @Override 242 @Override
243 - public ListenableFuture<TimePageData<AlarmInfo>> findAlarms(AlarmQuery query) {  
244 - ListenableFuture<List<AlarmInfo>> alarms = alarmDao.findAlarms(query); 243 + public ListenableFuture<TimePageData<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query) {
  244 + ListenableFuture<List<AlarmInfo>> alarms = alarmDao.findAlarms(tenantId, query);
245 if (query.getFetchOriginator() != null && query.getFetchOriginator().booleanValue()) { 245 if (query.getFetchOriginator() != null && query.getFetchOriginator().booleanValue()) {
246 alarms = Futures.transformAsync(alarms, input -> { 246 alarms = Futures.transformAsync(alarms, input -> {
247 List<ListenableFuture<AlarmInfo>> alarmFutures = new ArrayList<>(input.size()); 247 List<ListenableFuture<AlarmInfo>> alarmFutures = new ArrayList<>(input.size());
248 for (AlarmInfo alarmInfo : input) { 248 for (AlarmInfo alarmInfo : input) {
249 alarmFutures.add(Futures.transform( 249 alarmFutures.add(Futures.transform(
250 - entityService.fetchEntityNameAsync(alarmInfo.getOriginator()), originatorName -> { 250 + entityService.fetchEntityNameAsync(tenantId, alarmInfo.getOriginator()), originatorName -> {
251 if (originatorName == null) { 251 if (originatorName == null) {
252 originatorName = "Deleted"; 252 originatorName = "Deleted";
253 } 253 }
@@ -269,7 +269,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -269,7 +269,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
269 } 269 }
270 270
271 @Override 271 @Override
272 - public AlarmSeverity findHighestAlarmSeverity(EntityId entityId, AlarmSearchStatus alarmSearchStatus, 272 + public AlarmSeverity findHighestAlarmSeverity(TenantId tenantId, EntityId entityId, AlarmSearchStatus alarmSearchStatus,
273 AlarmStatus alarmStatus) { 273 AlarmStatus alarmStatus) {
274 TimePageLink nextPageLink = new TimePageLink(100); 274 TimePageLink nextPageLink = new TimePageLink(100);
275 boolean hasNext = true; 275 boolean hasNext = true;
@@ -279,7 +279,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -279,7 +279,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
279 query = new AlarmQuery(entityId, nextPageLink, alarmSearchStatus, alarmStatus, false); 279 query = new AlarmQuery(entityId, nextPageLink, alarmSearchStatus, alarmStatus, false);
280 List<AlarmInfo> alarms; 280 List<AlarmInfo> alarms;
281 try { 281 try {
282 - alarms = alarmDao.findAlarms(query).get(); 282 + alarms = alarmDao.findAlarms(tenantId, query).get();
283 } catch (ExecutionException | InterruptedException e) { 283 } catch (ExecutionException | InterruptedException e) {
284 log.warn("Failed to find highest alarm severity. EntityId: [{}], AlarmSearchStatus: [{}], AlarmStatus: [{}]", 284 log.warn("Failed to find highest alarm severity. EntityId: [{}], AlarmSearchStatus: [{}], AlarmStatus: [{}]",
285 entityId, alarmSearchStatus, alarmStatus); 285 entityId, alarmSearchStatus, alarmStatus);
@@ -312,14 +312,14 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -312,14 +312,14 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
312 } 312 }
313 } 313 }
314 314
315 - private void deleteRelation(EntityRelation alarmRelation) throws ExecutionException, InterruptedException { 315 + private void deleteRelation(TenantId tenantId, EntityRelation alarmRelation) throws ExecutionException, InterruptedException {
316 log.debug("Deleting Alarm relation: {}", alarmRelation); 316 log.debug("Deleting Alarm relation: {}", alarmRelation);
317 - relationService.deleteRelationAsync(alarmRelation).get(); 317 + relationService.deleteRelationAsync(tenantId, alarmRelation).get();
318 } 318 }
319 319
320 - private void createRelation(EntityRelation alarmRelation) throws ExecutionException, InterruptedException { 320 + private void createRelation(TenantId tenantId, EntityRelation alarmRelation) throws ExecutionException, InterruptedException {
321 log.debug("Creating Alarm relation: {}", alarmRelation); 321 log.debug("Creating Alarm relation: {}", alarmRelation);
322 - relationService.saveRelationAsync(alarmRelation).get(); 322 + relationService.saveRelationAsync(tenantId, alarmRelation).get();
323 } 323 }
324 324
325 private Alarm merge(Alarm existing, Alarm alarm) { 325 private Alarm merge(Alarm existing, Alarm alarm) {
@@ -344,10 +344,10 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -344,10 +344,10 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
344 344
345 private void updateRelations(Alarm alarm, AlarmStatus oldStatus, AlarmStatus newStatus) { 345 private void updateRelations(Alarm alarm, AlarmStatus oldStatus, AlarmStatus newStatus) {
346 try { 346 try {
347 - List<EntityRelation> relations = relationService.findByToAsync(alarm.getId(), RelationTypeGroup.ALARM).get(); 347 + List<EntityRelation> relations = relationService.findByToAsync(alarm.getTenantId(), alarm.getId(), RelationTypeGroup.ALARM).get();
348 Set<EntityId> parents = relations.stream().map(EntityRelation::getFrom).collect(Collectors.toSet()); 348 Set<EntityId> parents = relations.stream().map(EntityRelation::getFrom).collect(Collectors.toSet());
349 for (EntityId parentId : parents) { 349 for (EntityId parentId : parents) {
350 - updateAlarmRelation(parentId, alarm.getId(), oldStatus, newStatus); 350 + updateAlarmRelation(alarm.getTenantId(), parentId, alarm.getId(), oldStatus, newStatus);
351 } 351 }
352 } catch (ExecutionException | InterruptedException e) { 352 } catch (ExecutionException | InterruptedException e) {
353 log.warn("[{}] Failed to update relations. Old status: [{}], New status: [{}]", alarm.getId(), oldStatus, newStatus); 353 log.warn("[{}] Failed to update relations. Old status: [{}], New status: [{}]", alarm.getId(), oldStatus, newStatus);
@@ -355,39 +355,39 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -355,39 +355,39 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
355 } 355 }
356 } 356 }
357 357
358 - private void createAlarmRelation(EntityId entityId, EntityId alarmId, AlarmStatus status, boolean createAnyRelation) { 358 + private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status, boolean createAnyRelation) {
359 try { 359 try {
360 if (createAnyRelation) { 360 if (createAnyRelation) {
361 - createRelation(new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + AlarmSearchStatus.ANY.name(), RelationTypeGroup.ALARM)); 361 + createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + AlarmSearchStatus.ANY.name(), RelationTypeGroup.ALARM));
362 } 362 }
363 - createRelation(new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.name(), RelationTypeGroup.ALARM));  
364 - createRelation(new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getClearSearchStatus().name(), RelationTypeGroup.ALARM));  
365 - createRelation(new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM)); 363 + createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.name(), RelationTypeGroup.ALARM));
  364 + createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getClearSearchStatus().name(), RelationTypeGroup.ALARM));
  365 + createRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM));
366 } catch (ExecutionException | InterruptedException e) { 366 } catch (ExecutionException | InterruptedException e) {
367 log.warn("[{}] Failed to create relation. Status: [{}]", alarmId, status); 367 log.warn("[{}] Failed to create relation. Status: [{}]", alarmId, status);
368 throw new RuntimeException(e); 368 throw new RuntimeException(e);
369 } 369 }
370 } 370 }
371 371
372 - private void deleteAlarmRelation(EntityId entityId, EntityId alarmId, AlarmStatus status) { 372 + private void deleteAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus status) {
373 try { 373 try {
374 - deleteRelation(new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.name(), RelationTypeGroup.ALARM));  
375 - deleteRelation(new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getClearSearchStatus().name(), RelationTypeGroup.ALARM));  
376 - deleteRelation(new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM)); 374 + deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.name(), RelationTypeGroup.ALARM));
  375 + deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getClearSearchStatus().name(), RelationTypeGroup.ALARM));
  376 + deleteRelation(tenantId, new EntityRelation(entityId, alarmId, ALARM_RELATION_PREFIX + status.getAckSearchStatus().name(), RelationTypeGroup.ALARM));
377 } catch (ExecutionException | InterruptedException e) { 377 } catch (ExecutionException | InterruptedException e) {
378 log.warn("[{}] Failed to delete relation. Status: [{}]", alarmId, status); 378 log.warn("[{}] Failed to delete relation. Status: [{}]", alarmId, status);
379 throw new RuntimeException(e); 379 throw new RuntimeException(e);
380 } 380 }
381 } 381 }
382 382
383 - private void updateAlarmRelation(EntityId entityId, EntityId alarmId, AlarmStatus oldStatus, AlarmStatus newStatus) {  
384 - deleteAlarmRelation(entityId, alarmId, oldStatus);  
385 - createAlarmRelation(entityId, alarmId, newStatus, false); 383 + private void updateAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId, AlarmStatus oldStatus, AlarmStatus newStatus) {
  384 + deleteAlarmRelation(tenantId, entityId, alarmId, oldStatus);
  385 + createAlarmRelation(tenantId, entityId, alarmId, newStatus, false);
386 } 386 }
387 387
388 - private <T> ListenableFuture<T> getAndUpdate(AlarmId alarmId, Function<Alarm, T> function) { 388 + private <T> ListenableFuture<T> getAndUpdate(TenantId tenantId, AlarmId alarmId, Function<Alarm, T> function) {
389 validateId(alarmId, "Alarm id should be specified!"); 389 validateId(alarmId, "Alarm id should be specified!");
390 - ListenableFuture<Alarm> entity = alarmDao.findAlarmByIdAsync(alarmId.getId()); 390 + ListenableFuture<Alarm> entity = alarmDao.findAlarmByIdAsync(tenantId, alarmId.getId());
391 return Futures.transform(entity, function, readResultsProcessingExecutor); 391 return Futures.transform(entity, function, readResultsProcessingExecutor);
392 } 392 }
393 393
@@ -395,7 +395,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -395,7 +395,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
395 new DataValidator<Alarm>() { 395 new DataValidator<Alarm>() {
396 396
397 @Override 397 @Override
398 - protected void validateDataImpl(Alarm alarm) { 398 + protected void validateDataImpl(TenantId tenantId, Alarm alarm) {
399 if (StringUtils.isEmpty(alarm.getType())) { 399 if (StringUtils.isEmpty(alarm.getType())) {
400 throw new DataValidationException("Alarm type should be specified!"); 400 throw new DataValidationException("Alarm type should be specified!");
401 } 401 }
@@ -411,7 +411,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @@ -411,7 +411,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
411 if (alarm.getTenantId() == null) { 411 if (alarm.getTenantId() == null) {
412 throw new DataValidationException("Alarm should be assigned to tenant!"); 412 throw new DataValidationException("Alarm should be assigned to tenant!");
413 } else { 413 } else {
414 - Tenant tenant = tenantDao.findById(alarm.getTenantId().getId()); 414 + Tenant tenant = tenantDao.findById(alarm.getTenantId(), alarm.getTenantId().getId());
415 if (tenant == null) { 415 if (tenant == null) {
416 throw new DataValidationException("Alarm is referencing to non-existent tenant!"); 416 throw new DataValidationException("Alarm is referencing to non-existent tenant!");
417 } 417 }
@@ -73,9 +73,9 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al @@ -73,9 +73,9 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al
73 } 73 }
74 74
75 @Override 75 @Override
76 - public Alarm save(Alarm alarm) { 76 + public Alarm save(TenantId tenantId, Alarm alarm) {
77 log.debug("Save asset [{}] ", alarm); 77 log.debug("Save asset [{}] ", alarm);
78 - return super.save(alarm); 78 + return super.save(tenantId, alarm);
79 } 79 }
80 80
81 @Override 81 @Override
@@ -88,11 +88,11 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al @@ -88,11 +88,11 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al
88 query.and(eq(ALARM_TYPE_PROPERTY, type)); 88 query.and(eq(ALARM_TYPE_PROPERTY, type));
89 query.limit(1); 89 query.limit(1);
90 query.orderBy(QueryBuilder.asc(ModelConstants.ALARM_TYPE_PROPERTY), QueryBuilder.desc(ModelConstants.ID_PROPERTY)); 90 query.orderBy(QueryBuilder.asc(ModelConstants.ALARM_TYPE_PROPERTY), QueryBuilder.desc(ModelConstants.ID_PROPERTY));
91 - return findOneByStatementAsync(query); 91 + return findOneByStatementAsync(tenantId, query);
92 } 92 }
93 93
94 @Override 94 @Override
95 - public ListenableFuture<List<AlarmInfo>> findAlarms(AlarmQuery query) { 95 + public ListenableFuture<List<AlarmInfo>> findAlarms(TenantId tenantId, AlarmQuery query) {
96 log.trace("Try to find alarms by entity [{}], searchStatus [{}], status [{}] and pageLink [{}]", query.getAffectedEntityId(), query.getSearchStatus(), query.getStatus(), query.getPageLink()); 96 log.trace("Try to find alarms by entity [{}], searchStatus [{}], status [{}] and pageLink [{}]", query.getAffectedEntityId(), query.getSearchStatus(), query.getStatus(), query.getPageLink());
97 EntityId affectedEntity = query.getAffectedEntityId(); 97 EntityId affectedEntity = query.getAffectedEntityId();
98 String searchStatusName; 98 String searchStatusName;
@@ -104,12 +104,12 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al @@ -104,12 +104,12 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al
104 searchStatusName = query.getStatus().name(); 104 searchStatusName = query.getStatus().name();
105 } 105 }
106 String relationType = BaseAlarmService.ALARM_RELATION_PREFIX + searchStatusName; 106 String relationType = BaseAlarmService.ALARM_RELATION_PREFIX + searchStatusName;
107 - ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(affectedEntity, relationType, RelationTypeGroup.ALARM, EntityType.ALARM, query.getPageLink()); 107 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(tenantId, affectedEntity, relationType, RelationTypeGroup.ALARM, EntityType.ALARM, query.getPageLink());
108 return Futures.transformAsync(relations, input -> { 108 return Futures.transformAsync(relations, input -> {
109 List<ListenableFuture<AlarmInfo>> alarmFutures = new ArrayList<>(input.size()); 109 List<ListenableFuture<AlarmInfo>> alarmFutures = new ArrayList<>(input.size());
110 for (EntityRelation relation : input) { 110 for (EntityRelation relation : input) {
111 alarmFutures.add(Futures.transform( 111 alarmFutures.add(Futures.transform(
112 - findAlarmByIdAsync(relation.getTo().getId()), 112 + findAlarmByIdAsync(tenantId, relation.getTo().getId()),
113 AlarmInfo::new)); 113 AlarmInfo::new));
114 } 114 }
115 return Futures.successfulAsList(alarmFutures); 115 return Futures.successfulAsList(alarmFutures);
@@ -117,11 +117,11 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al @@ -117,11 +117,11 @@ public class CassandraAlarmDao extends CassandraAbstractModelDao<AlarmEntity, Al
117 } 117 }
118 118
119 @Override 119 @Override
120 - public ListenableFuture<Alarm> findAlarmByIdAsync(UUID key) { 120 + public ListenableFuture<Alarm> findAlarmByIdAsync(TenantId tenantId, UUID key) {
121 log.debug("Get alarm by id {}", key); 121 log.debug("Get alarm by id {}", key);
122 Select.Where query = select().from(ALARM_BY_ID_VIEW_NAME).where(eq(ModelConstants.ID_PROPERTY, key)); 122 Select.Where query = select().from(ALARM_BY_ID_VIEW_NAME).where(eq(ModelConstants.ID_PROPERTY, key));
123 query.limit(1); 123 query.limit(1);
124 log.trace("Execute query {}", query); 124 log.trace("Execute query {}", query);
125 - return findOneByStatementAsync(query); 125 + return findOneByStatementAsync(tenantId, query);
126 } 126 }
127 } 127 }
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.asset; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.asset;
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.EntitySubtype; 19 import org.thingsboard.server.common.data.EntitySubtype;
20 import org.thingsboard.server.common.data.asset.Asset; 20 import org.thingsboard.server.common.data.asset.Asset;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.page.TextPageLink; 22 import org.thingsboard.server.common.data.page.TextPageLink;
22 import org.thingsboard.server.dao.Dao; 23 import org.thingsboard.server.dao.Dao;
23 24
@@ -37,7 +38,7 @@ public interface AssetDao extends Dao<Asset> { @@ -37,7 +38,7 @@ public interface AssetDao extends Dao<Asset> {
37 * @param asset the asset object 38 * @param asset the asset object
38 * @return saved asset object 39 * @return saved asset object
39 */ 40 */
40 - Asset save(Asset asset); 41 + Asset save(TenantId tenantId, Asset asset);
41 42
42 /** 43 /**
43 * Find assets by tenantId and page link. 44 * Find assets by tenantId and page link.
@@ -30,19 +30,19 @@ import java.util.Optional; @@ -30,19 +30,19 @@ import java.util.Optional;
30 30
31 public interface AssetService { 31 public interface AssetService {
32 32
33 - Asset findAssetById(AssetId assetId); 33 + Asset findAssetById(TenantId tenantId, AssetId assetId);
34 34
35 - ListenableFuture<Asset> findAssetByIdAsync(AssetId assetId); 35 + ListenableFuture<Asset> findAssetByIdAsync(TenantId tenantId, AssetId assetId);
36 36
37 Asset findAssetByTenantIdAndName(TenantId tenantId, String name); 37 Asset findAssetByTenantIdAndName(TenantId tenantId, String name);
38 38
39 Asset saveAsset(Asset asset); 39 Asset saveAsset(Asset asset);
40 40
41 - Asset assignAssetToCustomer(AssetId assetId, CustomerId customerId); 41 + Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, CustomerId customerId);
42 42
43 - Asset unassignAssetFromCustomer(AssetId assetId); 43 + Asset unassignAssetFromCustomer(TenantId tenantId, AssetId assetId);
44 44
45 - void deleteAsset(AssetId assetId); 45 + void deleteAsset(TenantId tenantId, AssetId assetId);
46 46
47 TextPageData<Asset> findAssetsByTenantId(TenantId tenantId, TextPageLink pageLink); 47 TextPageData<Asset> findAssetsByTenantId(TenantId tenantId, TextPageLink pageLink);
48 48
@@ -60,7 +60,7 @@ public interface AssetService { @@ -60,7 +60,7 @@ public interface AssetService {
60 60
61 void unassignCustomerAssets(TenantId tenantId, CustomerId customerId); 61 void unassignCustomerAssets(TenantId tenantId, CustomerId customerId);
62 62
63 - ListenableFuture<List<Asset>> findAssetsByQuery(AssetSearchQuery query); 63 + ListenableFuture<List<Asset>> findAssetsByQuery(TenantId tenantId, AssetSearchQuery query);
64 64
65 ListenableFuture<List<EntitySubtype>> findAssetTypesByTenantId(TenantId tenantId); 65 ListenableFuture<List<EntitySubtype>> findAssetTypesByTenantId(TenantId tenantId);
66 } 66 }
@@ -86,17 +86,17 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -86,17 +86,17 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
86 private CacheManager cacheManager; 86 private CacheManager cacheManager;
87 87
88 @Override 88 @Override
89 - public Asset findAssetById(AssetId assetId) { 89 + public Asset findAssetById(TenantId tenantId, AssetId assetId) {
90 log.trace("Executing findAssetById [{}]", assetId); 90 log.trace("Executing findAssetById [{}]", assetId);
91 validateId(assetId, INCORRECT_ASSET_ID + assetId); 91 validateId(assetId, INCORRECT_ASSET_ID + assetId);
92 - return assetDao.findById(assetId.getId()); 92 + return assetDao.findById(tenantId, assetId.getId());
93 } 93 }
94 94
95 @Override 95 @Override
96 - public ListenableFuture<Asset> findAssetByIdAsync(AssetId assetId) { 96 + public ListenableFuture<Asset> findAssetByIdAsync(TenantId tenantId, AssetId assetId) {
97 log.trace("Executing findAssetById [{}]", assetId); 97 log.trace("Executing findAssetById [{}]", assetId);
98 validateId(assetId, INCORRECT_ASSET_ID + assetId); 98 validateId(assetId, INCORRECT_ASSET_ID + assetId);
99 - return assetDao.findByIdAsync(assetId.getId()); 99 + return assetDao.findByIdAsync(tenantId, assetId.getId());
100 } 100 }
101 101
102 @Cacheable(cacheNames = ASSET_CACHE, key = "{#tenantId, #name}") 102 @Cacheable(cacheNames = ASSET_CACHE, key = "{#tenantId, #name}")
@@ -112,31 +112,31 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -112,31 +112,31 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
112 @Override 112 @Override
113 public Asset saveAsset(Asset asset) { 113 public Asset saveAsset(Asset asset) {
114 log.trace("Executing saveAsset [{}]", asset); 114 log.trace("Executing saveAsset [{}]", asset);
115 - assetValidator.validate(asset);  
116 - return assetDao.save(asset); 115 + assetValidator.validate(asset, Asset::getTenantId);
  116 + return assetDao.save(asset.getTenantId(), asset);
117 } 117 }
118 118
119 @Override 119 @Override
120 - public Asset assignAssetToCustomer(AssetId assetId, CustomerId customerId) {  
121 - Asset asset = findAssetById(assetId); 120 + public Asset assignAssetToCustomer(TenantId tenantId, AssetId assetId, CustomerId customerId) {
  121 + Asset asset = findAssetById(tenantId, assetId);
122 asset.setCustomerId(customerId); 122 asset.setCustomerId(customerId);
123 return saveAsset(asset); 123 return saveAsset(asset);
124 } 124 }
125 125
126 @Override 126 @Override
127 - public Asset unassignAssetFromCustomer(AssetId assetId) {  
128 - Asset asset = findAssetById(assetId); 127 + public Asset unassignAssetFromCustomer(TenantId tenantId, AssetId assetId) {
  128 + Asset asset = findAssetById(tenantId, assetId);
129 asset.setCustomerId(null); 129 asset.setCustomerId(null);
130 return saveAsset(asset); 130 return saveAsset(asset);
131 } 131 }
132 132
133 @Override 133 @Override
134 - public void deleteAsset(AssetId assetId) { 134 + public void deleteAsset(TenantId tenantId, AssetId assetId) {
135 log.trace("Executing deleteAsset [{}]", assetId); 135 log.trace("Executing deleteAsset [{}]", assetId);
136 validateId(assetId, INCORRECT_ASSET_ID + assetId); 136 validateId(assetId, INCORRECT_ASSET_ID + assetId);
137 - deleteEntityRelations(assetId); 137 + deleteEntityRelations(tenantId, assetId);
138 138
139 - Asset asset = assetDao.findById(assetId.getId()); 139 + Asset asset = assetDao.findById(tenantId, assetId.getId());
140 try { 140 try {
141 List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(asset.getTenantId(), assetId).get(); 141 List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(asset.getTenantId(), assetId).get();
142 if (entityViews != null && !entityViews.isEmpty()) { 142 if (entityViews != null && !entityViews.isEmpty()) {
@@ -153,7 +153,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -153,7 +153,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
153 Cache cache = cacheManager.getCache(ASSET_CACHE); 153 Cache cache = cacheManager.getCache(ASSET_CACHE);
154 cache.evict(list); 154 cache.evict(list);
155 155
156 - assetDao.removeById(assetId.getId()); 156 + assetDao.removeById(tenantId, assetId.getId());
157 } 157 }
158 158
159 @Override 159 @Override
@@ -187,7 +187,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -187,7 +187,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
187 public void deleteAssetsByTenantId(TenantId tenantId) { 187 public void deleteAssetsByTenantId(TenantId tenantId) {
188 log.trace("Executing deleteAssetsByTenantId, tenantId [{}]", tenantId); 188 log.trace("Executing deleteAssetsByTenantId, tenantId [{}]", tenantId);
189 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 189 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
190 - tenantAssetsRemover.removeEntities(tenantId); 190 + tenantAssetsRemover.removeEntities(tenantId, tenantId);
191 } 191 }
192 192
193 @Override 193 @Override
@@ -225,24 +225,24 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -225,24 +225,24 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
225 log.trace("Executing unassignCustomerAssets, tenantId [{}], customerId [{}]", tenantId, customerId); 225 log.trace("Executing unassignCustomerAssets, tenantId [{}], customerId [{}]", tenantId, customerId);
226 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 226 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
227 validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); 227 validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
228 - new CustomerAssetsUnassigner(tenantId).removeEntities(customerId); 228 + customerAssetsUnasigner.removeEntities(tenantId, customerId);
229 } 229 }
230 230
231 @Override 231 @Override
232 - public ListenableFuture<List<Asset>> findAssetsByQuery(AssetSearchQuery query) {  
233 - ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(query.toEntitySearchQuery()); 232 + public ListenableFuture<List<Asset>> findAssetsByQuery(TenantId tenantId, AssetSearchQuery query) {
  233 + ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(tenantId, query.toEntitySearchQuery());
234 ListenableFuture<List<Asset>> assets = Futures.transformAsync(relations, r -> { 234 ListenableFuture<List<Asset>> assets = Futures.transformAsync(relations, r -> {
235 EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection(); 235 EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection();
236 List<ListenableFuture<Asset>> futures = new ArrayList<>(); 236 List<ListenableFuture<Asset>> futures = new ArrayList<>();
237 for (EntityRelation relation : r) { 237 for (EntityRelation relation : r) {
238 EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom(); 238 EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom();
239 if (entityId.getEntityType() == EntityType.ASSET) { 239 if (entityId.getEntityType() == EntityType.ASSET) {
240 - futures.add(findAssetByIdAsync(new AssetId(entityId.getId()))); 240 + futures.add(findAssetByIdAsync(tenantId, new AssetId(entityId.getId())));
241 } 241 }
242 } 242 }
243 return Futures.successfulAsList(futures); 243 return Futures.successfulAsList(futures);
244 }); 244 });
245 - assets = Futures.transform(assets, (Function<List<Asset>, List<Asset>>)assetList -> 245 + assets = Futures.transform(assets, assetList ->
246 assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()) 246 assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList())
247 ); 247 );
248 return assets; 248 return assets;
@@ -254,7 +254,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -254,7 +254,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
254 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 254 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
255 ListenableFuture<List<EntitySubtype>> tenantAssetTypes = assetDao.findTenantAssetTypesAsync(tenantId.getId()); 255 ListenableFuture<List<EntitySubtype>> tenantAssetTypes = assetDao.findTenantAssetTypesAsync(tenantId.getId());
256 return Futures.transform(tenantAssetTypes, 256 return Futures.transform(tenantAssetTypes,
257 - (Function<List<EntitySubtype>, List<EntitySubtype>>) assetTypes -> { 257 + assetTypes -> {
258 assetTypes.sort(Comparator.comparing(EntitySubtype::getType)); 258 assetTypes.sort(Comparator.comparing(EntitySubtype::getType));
259 return assetTypes; 259 return assetTypes;
260 }); 260 });
@@ -264,7 +264,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -264,7 +264,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
264 new DataValidator<Asset>() { 264 new DataValidator<Asset>() {
265 265
266 @Override 266 @Override
267 - protected void validateCreate(Asset asset) { 267 + protected void validateCreate(TenantId tenantId, Asset asset) {
268 assetDao.findAssetsByTenantIdAndName(asset.getTenantId().getId(), asset.getName()).ifPresent( 268 assetDao.findAssetsByTenantIdAndName(asset.getTenantId().getId(), asset.getName()).ifPresent(
269 d -> { 269 d -> {
270 throw new DataValidationException("Asset with such name already exists!"); 270 throw new DataValidationException("Asset with such name already exists!");
@@ -273,7 +273,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -273,7 +273,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
273 } 273 }
274 274
275 @Override 275 @Override
276 - protected void validateUpdate(Asset asset) { 276 + protected void validateUpdate(TenantId tenantId, Asset asset) {
277 assetDao.findAssetsByTenantIdAndName(asset.getTenantId().getId(), asset.getName()).ifPresent( 277 assetDao.findAssetsByTenantIdAndName(asset.getTenantId().getId(), asset.getName()).ifPresent(
278 d -> { 278 d -> {
279 if (!d.getId().equals(asset.getId())) { 279 if (!d.getId().equals(asset.getId())) {
@@ -284,7 +284,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -284,7 +284,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
284 } 284 }
285 285
286 @Override 286 @Override
287 - protected void validateDataImpl(Asset asset) { 287 + protected void validateDataImpl(TenantId tenantId, Asset asset) {
288 if (StringUtils.isEmpty(asset.getType())) { 288 if (StringUtils.isEmpty(asset.getType())) {
289 throw new DataValidationException("Asset type should be specified!"); 289 throw new DataValidationException("Asset type should be specified!");
290 } 290 }
@@ -294,7 +294,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -294,7 +294,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
294 if (asset.getTenantId() == null) { 294 if (asset.getTenantId() == null) {
295 throw new DataValidationException("Asset should be assigned to tenant!"); 295 throw new DataValidationException("Asset should be assigned to tenant!");
296 } else { 296 } else {
297 - Tenant tenant = tenantDao.findById(asset.getTenantId().getId()); 297 + Tenant tenant = tenantDao.findById(tenantId, asset.getTenantId().getId());
298 if (tenant == null) { 298 if (tenant == null) {
299 throw new DataValidationException("Asset is referencing to non-existent tenant!"); 299 throw new DataValidationException("Asset is referencing to non-existent tenant!");
300 } 300 }
@@ -302,7 +302,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -302,7 +302,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
302 if (asset.getCustomerId() == null) { 302 if (asset.getCustomerId() == null) {
303 asset.setCustomerId(new CustomerId(NULL_UUID)); 303 asset.setCustomerId(new CustomerId(NULL_UUID));
304 } else if (!asset.getCustomerId().getId().equals(NULL_UUID)) { 304 } else if (!asset.getCustomerId().getId().equals(NULL_UUID)) {
305 - Customer customer = customerDao.findById(asset.getCustomerId().getId()); 305 + Customer customer = customerDao.findById(tenantId, asset.getCustomerId().getId());
306 if (customer == null) { 306 if (customer == null) {
307 throw new DataValidationException("Can't assign asset to non-existent customer!"); 307 throw new DataValidationException("Can't assign asset to non-existent customer!");
308 } 308 }
@@ -314,35 +314,29 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -314,35 +314,29 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
314 }; 314 };
315 315
316 private PaginatedRemover<TenantId, Asset> tenantAssetsRemover = 316 private PaginatedRemover<TenantId, Asset> tenantAssetsRemover =
317 - new PaginatedRemover<TenantId, Asset>() { 317 + new PaginatedRemover<TenantId, Asset>() {
318 318
319 - @Override  
320 - protected List<Asset> findEntities(TenantId id, TextPageLink pageLink) {  
321 - return assetDao.findAssetsByTenantId(id.getId(), pageLink);  
322 - }  
323 -  
324 - @Override  
325 - protected void removeEntity(Asset entity) {  
326 - deleteAsset(new AssetId(entity.getId().getId()));  
327 - }  
328 - }; 319 + @Override
  320 + protected List<Asset> findEntities(TenantId tenantId, TenantId id, TextPageLink pageLink) {
  321 + return assetDao.findAssetsByTenantId(id.getId(), pageLink);
  322 + }
329 323
330 - class CustomerAssetsUnassigner extends PaginatedRemover<CustomerId, Asset> { 324 + @Override
  325 + protected void removeEntity(TenantId tenantId, Asset entity) {
  326 + deleteAsset(tenantId, new AssetId(entity.getId().getId()));
  327 + }
  328 + };
331 329
332 - private TenantId tenantId;  
333 -  
334 - CustomerAssetsUnassigner(TenantId tenantId) {  
335 - this.tenantId = tenantId;  
336 - } 330 + private PaginatedRemover<CustomerId, Asset> customerAssetsUnasigner = new PaginatedRemover<CustomerId, Asset>() {
337 331
338 @Override 332 @Override
339 - protected List<Asset> findEntities(CustomerId id, TextPageLink pageLink) { 333 + protected List<Asset> findEntities(TenantId tenantId, CustomerId id, TextPageLink pageLink) {
340 return assetDao.findAssetsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink); 334 return assetDao.findAssetsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink);
341 } 335 }
342 336
343 @Override 337 @Override
344 - protected void removeEntity(Asset entity) {  
345 - unassignAssetFromCustomer(new AssetId(entity.getId().getId())); 338 + protected void removeEntity(TenantId tenantId, Asset entity) {
  339 + unassignAssetFromCustomer(tenantId, new AssetId(entity.getId().getId()));
346 } 340 }
347 - } 341 + };
348 } 342 }
@@ -28,6 +28,7 @@ import org.springframework.stereotype.Component; @@ -28,6 +28,7 @@ import org.springframework.stereotype.Component;
28 import org.thingsboard.server.common.data.EntitySubtype; 28 import org.thingsboard.server.common.data.EntitySubtype;
29 import org.thingsboard.server.common.data.EntityType; 29 import org.thingsboard.server.common.data.EntityType;
30 import org.thingsboard.server.common.data.asset.Asset; 30 import org.thingsboard.server.common.data.asset.Asset;
  31 +import org.thingsboard.server.common.data.id.TenantId;
31 import org.thingsboard.server.common.data.page.TextPageLink; 32 import org.thingsboard.server.common.data.page.TextPageLink;
32 import org.thingsboard.server.dao.DaoUtil; 33 import org.thingsboard.server.dao.DaoUtil;
33 import org.thingsboard.server.dao.model.EntitySubtypeEntity; 34 import org.thingsboard.server.dao.model.EntitySubtypeEntity;
@@ -77,19 +78,19 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit @@ -77,19 +78,19 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
77 } 78 }
78 79
79 @Override 80 @Override
80 - public Asset save(Asset domain) {  
81 - Asset savedAsset = super.save(domain); 81 + public Asset save(TenantId tenantId, Asset domain) {
  82 + Asset savedAsset = super.save(tenantId, domain);
82 EntitySubtype entitySubtype = new EntitySubtype(savedAsset.getTenantId(), EntityType.ASSET, savedAsset.getType()); 83 EntitySubtype entitySubtype = new EntitySubtype(savedAsset.getTenantId(), EntityType.ASSET, savedAsset.getType());
83 EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype); 84 EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype);
84 Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity); 85 Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity);
85 - executeWrite(saveStatement); 86 + executeWrite(tenantId, saveStatement);
86 return savedAsset; 87 return savedAsset;
87 } 88 }
88 89
89 @Override 90 @Override
90 public List<Asset> findAssetsByTenantId(UUID tenantId, TextPageLink pageLink) { 91 public List<Asset> findAssetsByTenantId(UUID tenantId, TextPageLink pageLink) {
91 log.debug("Try to find assets by tenantId [{}] and pageLink [{}]", tenantId, pageLink); 92 log.debug("Try to find assets by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
92 - List<AssetEntity> assetEntities = findPageWithTextSearch(ASSET_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 93 + List<AssetEntity> assetEntities = findPageWithTextSearch(new TenantId(tenantId), ASSET_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
93 Collections.singletonList(eq(ASSET_TENANT_ID_PROPERTY, tenantId)), pageLink); 94 Collections.singletonList(eq(ASSET_TENANT_ID_PROPERTY, tenantId)), pageLink);
94 95
95 log.trace("Found assets [{}] by tenantId [{}] and pageLink [{}]", assetEntities, tenantId, pageLink); 96 log.trace("Found assets [{}] by tenantId [{}] and pageLink [{}]", assetEntities, tenantId, pageLink);
@@ -99,7 +100,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit @@ -99,7 +100,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
99 @Override 100 @Override
100 public List<Asset> findAssetsByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) { 101 public List<Asset> findAssetsByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) {
101 log.debug("Try to find assets by tenantId [{}], type [{}] and pageLink [{}]", tenantId, type, pageLink); 102 log.debug("Try to find assets by tenantId [{}], type [{}] and pageLink [{}]", tenantId, type, pageLink);
102 - List<AssetEntity> assetEntities = findPageWithTextSearch(ASSET_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 103 + List<AssetEntity> assetEntities = findPageWithTextSearch(new TenantId(tenantId), ASSET_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
103 Arrays.asList(eq(ASSET_TYPE_PROPERTY, type), 104 Arrays.asList(eq(ASSET_TYPE_PROPERTY, type),
104 eq(ASSET_TENANT_ID_PROPERTY, tenantId)), pageLink); 105 eq(ASSET_TENANT_ID_PROPERTY, tenantId)), pageLink);
105 log.trace("Found assets [{}] by tenantId [{}], type [{}] and pageLink [{}]", assetEntities, tenantId, type, pageLink); 106 log.trace("Found assets [{}] by tenantId [{}], type [{}] and pageLink [{}]", assetEntities, tenantId, type, pageLink);
@@ -112,13 +113,13 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit @@ -112,13 +113,13 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
112 Select.Where query = select.where(); 113 Select.Where query = select.where();
113 query.and(eq(ASSET_TENANT_ID_PROPERTY, tenantId)); 114 query.and(eq(ASSET_TENANT_ID_PROPERTY, tenantId));
114 query.and(in(ID_PROPERTY, assetIds)); 115 query.and(in(ID_PROPERTY, assetIds));
115 - return findListByStatementAsync(query); 116 + return findListByStatementAsync(new TenantId(tenantId), query);
116 } 117 }
117 118
118 @Override 119 @Override
119 public List<Asset> findAssetsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) { 120 public List<Asset> findAssetsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) {
120 log.debug("Try to find assets by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink); 121 log.debug("Try to find assets by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink);
121 - List<AssetEntity> assetEntities = findPageWithTextSearch(ASSET_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 122 + List<AssetEntity> assetEntities = findPageWithTextSearch(new TenantId(tenantId), ASSET_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
122 Arrays.asList(eq(ASSET_CUSTOMER_ID_PROPERTY, customerId), 123 Arrays.asList(eq(ASSET_CUSTOMER_ID_PROPERTY, customerId),
123 eq(ASSET_TENANT_ID_PROPERTY, tenantId)), 124 eq(ASSET_TENANT_ID_PROPERTY, tenantId)),
124 pageLink); 125 pageLink);
@@ -130,7 +131,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit @@ -130,7 +131,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
130 @Override 131 @Override
131 public List<Asset> findAssetsByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) { 132 public List<Asset> findAssetsByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) {
132 log.debug("Try to find assets by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink); 133 log.debug("Try to find assets by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink);
133 - List<AssetEntity> assetEntities = findPageWithTextSearch(ASSET_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 134 + List<AssetEntity> assetEntities = findPageWithTextSearch(new TenantId(tenantId), ASSET_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
134 Arrays.asList(eq(ASSET_TYPE_PROPERTY, type), 135 Arrays.asList(eq(ASSET_TYPE_PROPERTY, type),
135 eq(ASSET_CUSTOMER_ID_PROPERTY, customerId), 136 eq(ASSET_CUSTOMER_ID_PROPERTY, customerId),
136 eq(ASSET_TENANT_ID_PROPERTY, tenantId)), 137 eq(ASSET_TENANT_ID_PROPERTY, tenantId)),
@@ -148,7 +149,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit @@ -148,7 +149,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
148 query.and(eq(ASSET_TENANT_ID_PROPERTY, tenantId)); 149 query.and(eq(ASSET_TENANT_ID_PROPERTY, tenantId));
149 query.and(eq(ASSET_CUSTOMER_ID_PROPERTY, customerId)); 150 query.and(eq(ASSET_CUSTOMER_ID_PROPERTY, customerId));
150 query.and(in(ID_PROPERTY, assetIds)); 151 query.and(in(ID_PROPERTY, assetIds));
151 - return findListByStatementAsync(query); 152 + return findListByStatementAsync(new TenantId(tenantId), query);
152 } 153 }
153 154
154 @Override 155 @Override
@@ -157,7 +158,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit @@ -157,7 +158,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
157 Select.Where query = select.where(); 158 Select.Where query = select.where();
158 query.and(eq(ASSET_TENANT_ID_PROPERTY, tenantId)); 159 query.and(eq(ASSET_TENANT_ID_PROPERTY, tenantId));
159 query.and(eq(ASSET_NAME_PROPERTY, assetName)); 160 query.and(eq(ASSET_NAME_PROPERTY, assetName));
160 - AssetEntity assetEntity = (AssetEntity) findOneByStatement(query); 161 + AssetEntity assetEntity = (AssetEntity) findOneByStatement(new TenantId(tenantId), query);
161 return Optional.ofNullable(DaoUtil.getData(assetEntity)); 162 return Optional.ofNullable(DaoUtil.getData(assetEntity));
162 } 163 }
163 164
@@ -168,7 +169,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit @@ -168,7 +169,7 @@ public class CassandraAssetDao extends CassandraAbstractSearchTextDao<AssetEntit
168 query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId)); 169 query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId));
169 query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.ASSET)); 170 query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.ASSET));
170 query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); 171 query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
171 - ResultSetFuture resultSetFuture = executeAsyncRead(query); 172 + ResultSetFuture resultSetFuture = executeAsyncRead(new TenantId(tenantId), query);
172 return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() { 173 return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() {
173 @Nullable 174 @Nullable
174 @Override 175 @Override
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.attributes; @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.attributes;
17 17
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.id.EntityId; 19 import org.thingsboard.server.common.data.id.EntityId;
  20 +import org.thingsboard.server.common.data.id.TenantId;
20 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 21 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
21 22
22 import java.util.Collection; 23 import java.util.Collection;
@@ -28,13 +29,13 @@ import java.util.Optional; @@ -28,13 +29,13 @@ import java.util.Optional;
28 */ 29 */
29 public interface AttributesDao { 30 public interface AttributesDao {
30 31
31 - ListenableFuture<Optional<AttributeKvEntry>> find(EntityId entityId, String attributeType, String attributeKey); 32 + ListenableFuture<Optional<AttributeKvEntry>> find(TenantId tenantId, EntityId entityId, String attributeType, String attributeKey);
32 33
33 - ListenableFuture<List<AttributeKvEntry>> find(EntityId entityId, String attributeType, Collection<String> attributeKey); 34 + ListenableFuture<List<AttributeKvEntry>> find(TenantId tenantId, EntityId entityId, String attributeType, Collection<String> attributeKey);
34 35
35 - ListenableFuture<List<AttributeKvEntry>> findAll(EntityId entityId, String attributeType); 36 + ListenableFuture<List<AttributeKvEntry>> findAll(TenantId tenantId, EntityId entityId, String attributeType);
36 37
37 - ListenableFuture<Void> save(EntityId entityId, String attributeType, AttributeKvEntry attribute); 38 + ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, String attributeType, AttributeKvEntry attribute);
38 39
39 - ListenableFuture<List<Void>> removeAll(EntityId entityId, String attributeType, List<String> keys); 40 + ListenableFuture<List<Void>> removeAll(TenantId tenantId, EntityId entityId, String attributeType, List<String> keys);
40 } 41 }
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.attributes; @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.attributes;
17 17
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.id.EntityId; 19 import org.thingsboard.server.common.data.id.EntityId;
  20 +import org.thingsboard.server.common.data.id.TenantId;
20 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 21 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
21 22
22 import java.util.Collection; 23 import java.util.Collection;
@@ -28,13 +29,13 @@ import java.util.Optional; @@ -28,13 +29,13 @@ import java.util.Optional;
28 */ 29 */
29 public interface AttributesService { 30 public interface AttributesService {
30 31
31 - ListenableFuture<Optional<AttributeKvEntry>> find(EntityId entityId, String scope, String attributeKey); 32 + ListenableFuture<Optional<AttributeKvEntry>> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey);
32 33
33 - ListenableFuture<List<AttributeKvEntry>> find(EntityId entityId, String scope, Collection<String> attributeKeys); 34 + ListenableFuture<List<AttributeKvEntry>> find(TenantId tenantId, EntityId entityId, String scope, Collection<String> attributeKeys);
34 35
35 - ListenableFuture<List<AttributeKvEntry>> findAll(EntityId entityId, String scope); 36 + ListenableFuture<List<AttributeKvEntry>> findAll(TenantId tenantId, EntityId entityId, String scope);
36 37
37 - ListenableFuture<List<Void>> save(EntityId entityId, String scope, List<AttributeKvEntry> attributes); 38 + ListenableFuture<List<Void>> save(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes);
38 39
39 - ListenableFuture<List<Void>> removeAll(EntityId entityId, String scope, List<String> attributeKeys); 40 + ListenableFuture<List<Void>> removeAll(TenantId tenantId, EntityId entityId, String scope, List<String> attributeKeys);
40 } 41 }
@@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture; @@ -21,6 +21,7 @@ import com.google.common.util.concurrent.ListenableFuture;
21 import org.springframework.beans.factory.annotation.Autowired; 21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Service; 22 import org.springframework.stereotype.Service;
23 import org.thingsboard.server.common.data.id.EntityId; 23 import org.thingsboard.server.common.data.id.EntityId;
  24 +import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 25 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
25 import org.thingsboard.server.dao.exception.IncorrectParameterException; 26 import org.thingsboard.server.dao.exception.IncorrectParameterException;
26 import org.thingsboard.server.dao.service.Validator; 27 import org.thingsboard.server.dao.service.Validator;
@@ -39,40 +40,40 @@ public class BaseAttributesService implements AttributesService { @@ -39,40 +40,40 @@ public class BaseAttributesService implements AttributesService {
39 private AttributesDao attributesDao; 40 private AttributesDao attributesDao;
40 41
41 @Override 42 @Override
42 - public ListenableFuture<Optional<AttributeKvEntry>> find(EntityId entityId, String scope, String attributeKey) { 43 + public ListenableFuture<Optional<AttributeKvEntry>> find(TenantId tenantId, EntityId entityId, String scope, String attributeKey) {
43 validate(entityId, scope); 44 validate(entityId, scope);
44 Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey); 45 Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey);
45 - return attributesDao.find(entityId, scope, attributeKey); 46 + return attributesDao.find(tenantId, entityId, scope, attributeKey);
46 } 47 }
47 48
48 @Override 49 @Override
49 - public ListenableFuture<List<AttributeKvEntry>> find(EntityId entityId, String scope, Collection<String> attributeKeys) { 50 + public ListenableFuture<List<AttributeKvEntry>> find(TenantId tenantId, EntityId entityId, String scope, Collection<String> attributeKeys) {
50 validate(entityId, scope); 51 validate(entityId, scope);
51 attributeKeys.forEach(attributeKey -> Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey)); 52 attributeKeys.forEach(attributeKey -> Validator.validateString(attributeKey, "Incorrect attribute key " + attributeKey));
52 - return attributesDao.find(entityId, scope, attributeKeys); 53 + return attributesDao.find(tenantId, entityId, scope, attributeKeys);
53 } 54 }
54 55
55 @Override 56 @Override
56 - public ListenableFuture<List<AttributeKvEntry>> findAll(EntityId entityId, String scope) { 57 + public ListenableFuture<List<AttributeKvEntry>> findAll(TenantId tenantId, EntityId entityId, String scope) {
57 validate(entityId, scope); 58 validate(entityId, scope);
58 - return attributesDao.findAll(entityId, scope); 59 + return attributesDao.findAll(tenantId, entityId, scope);
59 } 60 }
60 61
61 @Override 62 @Override
62 - public ListenableFuture<List<Void>> save(EntityId entityId, String scope, List<AttributeKvEntry> attributes) { 63 + public ListenableFuture<List<Void>> save(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes) {
63 validate(entityId, scope); 64 validate(entityId, scope);
64 attributes.forEach(attribute -> validate(attribute)); 65 attributes.forEach(attribute -> validate(attribute));
65 List<ListenableFuture<Void>> futures = Lists.newArrayListWithExpectedSize(attributes.size()); 66 List<ListenableFuture<Void>> futures = Lists.newArrayListWithExpectedSize(attributes.size());
66 for (AttributeKvEntry attribute : attributes) { 67 for (AttributeKvEntry attribute : attributes) {
67 - futures.add(attributesDao.save(entityId, scope, attribute)); 68 + futures.add(attributesDao.save(tenantId, entityId, scope, attribute));
68 } 69 }
69 return Futures.allAsList(futures); 70 return Futures.allAsList(futures);
70 } 71 }
71 72
72 @Override 73 @Override
73 - public ListenableFuture<List<Void>> removeAll(EntityId entityId, String scope, List<String> keys) { 74 + public ListenableFuture<List<Void>> removeAll(TenantId tenantId, EntityId entityId, String scope, List<String> keys) {
74 validate(entityId, scope); 75 validate(entityId, scope);
75 - return attributesDao.removeAll(entityId, scope, keys); 76 + return attributesDao.removeAll(tenantId, entityId, scope, keys);
76 } 77 }
77 78
78 private static void validate(EntityId id, String scope) { 79 private static void validate(EntityId id, String scope) {
@@ -28,6 +28,7 @@ import com.google.common.util.concurrent.ListenableFuture; @@ -28,6 +28,7 @@ import com.google.common.util.concurrent.ListenableFuture;
28 import lombok.extern.slf4j.Slf4j; 28 import lombok.extern.slf4j.Slf4j;
29 import org.springframework.stereotype.Component; 29 import org.springframework.stereotype.Component;
30 import org.thingsboard.server.common.data.id.EntityId; 30 import org.thingsboard.server.common.data.id.EntityId;
  31 +import org.thingsboard.server.common.data.id.TenantId;
31 import org.thingsboard.server.common.data.kv.AttributeKvEntry; 32 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
32 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry; 33 import org.thingsboard.server.common.data.kv.BaseAttributeKvEntry;
33 import org.thingsboard.server.dao.model.ModelConstants; 34 import org.thingsboard.server.dao.model.ModelConstants;
@@ -73,22 +74,22 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem @@ -73,22 +74,22 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem
73 } 74 }
74 75
75 @Override 76 @Override
76 - public ListenableFuture<Optional<AttributeKvEntry>> find(EntityId entityId, String attributeType, String attributeKey) { 77 + public ListenableFuture<Optional<AttributeKvEntry>> find(TenantId tenantId, EntityId entityId, String attributeType, String attributeKey) {
77 Select.Where select = select().from(ATTRIBUTES_KV_CF) 78 Select.Where select = select().from(ATTRIBUTES_KV_CF)
78 .where(eq(ENTITY_TYPE_COLUMN, entityId.getEntityType())) 79 .where(eq(ENTITY_TYPE_COLUMN, entityId.getEntityType()))
79 .and(eq(ENTITY_ID_COLUMN, entityId.getId())) 80 .and(eq(ENTITY_ID_COLUMN, entityId.getId()))
80 .and(eq(ATTRIBUTE_TYPE_COLUMN, attributeType)) 81 .and(eq(ATTRIBUTE_TYPE_COLUMN, attributeType))
81 .and(eq(ATTRIBUTE_KEY_COLUMN, attributeKey)); 82 .and(eq(ATTRIBUTE_KEY_COLUMN, attributeKey));
82 log.trace("Generated query [{}] for entityId {} and key {}", select, entityId, attributeKey); 83 log.trace("Generated query [{}] for entityId {} and key {}", select, entityId, attributeKey);
83 - return Futures.transform(executeAsyncRead(select), (Function<? super ResultSet, ? extends Optional<AttributeKvEntry>>) input -> 84 + return Futures.transform(executeAsyncRead(tenantId, select), (Function<? super ResultSet, ? extends Optional<AttributeKvEntry>>) input ->
84 Optional.ofNullable(convertResultToAttributesKvEntry(attributeKey, input.one())) 85 Optional.ofNullable(convertResultToAttributesKvEntry(attributeKey, input.one()))
85 , readResultsProcessingExecutor); 86 , readResultsProcessingExecutor);
86 } 87 }
87 88
88 @Override 89 @Override
89 - public ListenableFuture<List<AttributeKvEntry>> find(EntityId entityId, String attributeType, Collection<String> attributeKeys) { 90 + public ListenableFuture<List<AttributeKvEntry>> find(TenantId tenantId, EntityId entityId, String attributeType, Collection<String> attributeKeys) {
90 List<ListenableFuture<Optional<AttributeKvEntry>>> entries = new ArrayList<>(); 91 List<ListenableFuture<Optional<AttributeKvEntry>>> entries = new ArrayList<>();
91 - attributeKeys.forEach(attributeKey -> entries.add(find(entityId, attributeType, attributeKey))); 92 + attributeKeys.forEach(attributeKey -> entries.add(find(tenantId, entityId, attributeType, attributeKey)));
92 return Futures.transform(Futures.allAsList(entries), (Function<List<Optional<AttributeKvEntry>>, ? extends List<AttributeKvEntry>>) input -> { 93 return Futures.transform(Futures.allAsList(entries), (Function<List<Optional<AttributeKvEntry>>, ? extends List<AttributeKvEntry>>) input -> {
93 List<AttributeKvEntry> result = new ArrayList<>(); 94 List<AttributeKvEntry> result = new ArrayList<>();
94 input.stream().filter(opt -> opt.isPresent()).forEach(opt -> result.add(opt.get())); 95 input.stream().filter(opt -> opt.isPresent()).forEach(opt -> result.add(opt.get()));
@@ -98,19 +99,19 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem @@ -98,19 +99,19 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem
98 99
99 100
100 @Override 101 @Override
101 - public ListenableFuture<List<AttributeKvEntry>> findAll(EntityId entityId, String attributeType) { 102 + public ListenableFuture<List<AttributeKvEntry>> findAll(TenantId tenantId, EntityId entityId, String attributeType) {
102 Select.Where select = select().from(ATTRIBUTES_KV_CF) 103 Select.Where select = select().from(ATTRIBUTES_KV_CF)
103 .where(eq(ENTITY_TYPE_COLUMN, entityId.getEntityType())) 104 .where(eq(ENTITY_TYPE_COLUMN, entityId.getEntityType()))
104 .and(eq(ENTITY_ID_COLUMN, entityId.getId())) 105 .and(eq(ENTITY_ID_COLUMN, entityId.getId()))
105 .and(eq(ATTRIBUTE_TYPE_COLUMN, attributeType)); 106 .and(eq(ATTRIBUTE_TYPE_COLUMN, attributeType));
106 log.trace("Generated query [{}] for entityId {} and attributeType {}", select, entityId, attributeType); 107 log.trace("Generated query [{}] for entityId {} and attributeType {}", select, entityId, attributeType);
107 - return Futures.transform(executeAsyncRead(select), (Function<? super ResultSet, ? extends List<AttributeKvEntry>>) input -> 108 + return Futures.transform(executeAsyncRead(tenantId, select), (Function<? super ResultSet, ? extends List<AttributeKvEntry>>) input ->
108 convertResultToAttributesKvEntryList(input) 109 convertResultToAttributesKvEntryList(input)
109 , readResultsProcessingExecutor); 110 , readResultsProcessingExecutor);
110 } 111 }
111 112
112 @Override 113 @Override
113 - public ListenableFuture<Void> save(EntityId entityId, String attributeType, AttributeKvEntry attribute) { 114 + public ListenableFuture<Void> save(TenantId tenantId, EntityId entityId, String attributeType, AttributeKvEntry attribute) {
114 BoundStatement stmt = getSaveStmt().bind(); 115 BoundStatement stmt = getSaveStmt().bind();
115 stmt.setString(0, entityId.getEntityType().name()); 116 stmt.setString(0, entityId.getEntityType().name());
116 stmt.setUUID(1, entityId.getId()); 117 stmt.setUUID(1, entityId.getId());
@@ -137,26 +138,26 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem @@ -137,26 +138,26 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem
137 stmt.setToNull(8); 138 stmt.setToNull(8);
138 } 139 }
139 log.trace("Generated save stmt [{}] for entityId {} and attributeType {} and attribute", stmt, entityId, attributeType, attribute); 140 log.trace("Generated save stmt [{}] for entityId {} and attributeType {} and attribute", stmt, entityId, attributeType, attribute);
140 - return getFuture(executeAsyncWrite(stmt), rs -> null); 141 + return getFuture(executeAsyncWrite(tenantId, stmt), rs -> null);
141 } 142 }
142 143
143 @Override 144 @Override
144 - public ListenableFuture<List<Void>> removeAll(EntityId entityId, String attributeType, List<String> keys) { 145 + public ListenableFuture<List<Void>> removeAll(TenantId tenantId, EntityId entityId, String attributeType, List<String> keys) {
145 List<ListenableFuture<Void>> futures = keys 146 List<ListenableFuture<Void>> futures = keys
146 .stream() 147 .stream()
147 - .map(key -> delete(entityId, attributeType, key)) 148 + .map(key -> delete(tenantId, entityId, attributeType, key))
148 .collect(Collectors.toList()); 149 .collect(Collectors.toList());
149 return Futures.allAsList(futures); 150 return Futures.allAsList(futures);
150 } 151 }
151 152
152 - private ListenableFuture<Void> delete(EntityId entityId, String attributeType, String key) { 153 + private ListenableFuture<Void> delete(TenantId tenantId, EntityId entityId, String attributeType, String key) {
153 Statement delete = QueryBuilder.delete().all().from(ModelConstants.ATTRIBUTES_KV_CF) 154 Statement delete = QueryBuilder.delete().all().from(ModelConstants.ATTRIBUTES_KV_CF)
154 .where(eq(ENTITY_TYPE_COLUMN, entityId.getEntityType())) 155 .where(eq(ENTITY_TYPE_COLUMN, entityId.getEntityType()))
155 .and(eq(ENTITY_ID_COLUMN, entityId.getId())) 156 .and(eq(ENTITY_ID_COLUMN, entityId.getId()))
156 .and(eq(ATTRIBUTE_TYPE_COLUMN, attributeType)) 157 .and(eq(ATTRIBUTE_TYPE_COLUMN, attributeType))
157 .and(eq(ATTRIBUTE_KEY_COLUMN, key)); 158 .and(eq(ATTRIBUTE_KEY_COLUMN, key));
158 log.debug("Remove request: {}", delete.toString()); 159 log.debug("Remove request: {}", delete.toString());
159 - return getFuture(executeAsyncWrite(delete), rs -> null); 160 + return getFuture(executeAsyncWrite(tenantId, delete), rs -> null);
160 } 161 }
161 162
162 private PreparedStatement getSaveStmt() { 163 private PreparedStatement getSaveStmt() {
@@ -128,7 +128,7 @@ public class AuditLogServiceImpl implements AuditLogService { @@ -128,7 +128,7 @@ public class AuditLogServiceImpl implements AuditLogService {
128 entityName = entity.getName(); 128 entityName = entity.getName();
129 } else { 129 } else {
130 try { 130 try {
131 - entityName = entityService.fetchEntityNameAsync(entityId).get(); 131 + entityName = entityService.fetchEntityNameAsync(tenantId, entityId).get();
132 } catch (Exception ex) {} 132 } catch (Exception ex) {}
133 } 133 }
134 if (e != null) { 134 if (e != null) {
@@ -315,7 +315,7 @@ public class AuditLogServiceImpl implements AuditLogService { @@ -315,7 +315,7 @@ public class AuditLogServiceImpl implements AuditLogService {
315 AuditLog auditLogEntry = createAuditLogEntry(tenantId, entityId, entityName, customerId, userId, userName, 315 AuditLog auditLogEntry = createAuditLogEntry(tenantId, entityId, entityName, customerId, userId, userName,
316 actionType, actionData, actionStatus, actionFailureDetails); 316 actionType, actionData, actionStatus, actionFailureDetails);
317 log.trace("Executing logAction [{}]", auditLogEntry); 317 log.trace("Executing logAction [{}]", auditLogEntry);
318 - auditLogValidator.validate(auditLogEntry); 318 + auditLogValidator.validate(auditLogEntry, AuditLog::getTenantId);
319 List<ListenableFuture<Void>> futures = Lists.newArrayListWithExpectedSize(INSERTS_PER_ENTRY); 319 List<ListenableFuture<Void>> futures = Lists.newArrayListWithExpectedSize(INSERTS_PER_ENTRY);
320 futures.add(auditLogDao.savePartitionsByTenantId(auditLogEntry)); 320 futures.add(auditLogDao.savePartitionsByTenantId(auditLogEntry));
321 futures.add(auditLogDao.saveByTenantId(auditLogEntry)); 321 futures.add(auditLogDao.saveByTenantId(auditLogEntry));
@@ -331,7 +331,7 @@ public class AuditLogServiceImpl implements AuditLogService { @@ -331,7 +331,7 @@ public class AuditLogServiceImpl implements AuditLogService {
331 private DataValidator<AuditLog> auditLogValidator = 331 private DataValidator<AuditLog> auditLogValidator =
332 new DataValidator<AuditLog>() { 332 new DataValidator<AuditLog>() {
333 @Override 333 @Override
334 - protected void validateDataImpl(AuditLog auditLog) { 334 + protected void validateDataImpl(TenantId tenantId, AuditLog auditLog) {
335 if (auditLog.getEntityId() == null) { 335 if (auditLog.getEntityId() == null) {
336 throw new DataValidationException("Entity Id should be specified!"); 336 throw new DataValidationException("Entity Id should be specified!");
337 } 337 }
@@ -32,6 +32,7 @@ import org.springframework.stereotype.Component; @@ -32,6 +32,7 @@ import org.springframework.stereotype.Component;
32 import org.thingsboard.server.common.data.audit.AuditLog; 32 import org.thingsboard.server.common.data.audit.AuditLog;
33 import org.thingsboard.server.common.data.id.CustomerId; 33 import org.thingsboard.server.common.data.id.CustomerId;
34 import org.thingsboard.server.common.data.id.EntityId; 34 import org.thingsboard.server.common.data.id.EntityId;
  35 +import org.thingsboard.server.common.data.id.TenantId;
35 import org.thingsboard.server.common.data.id.UserId; 36 import org.thingsboard.server.common.data.id.UserId;
36 import org.thingsboard.server.common.data.page.TimePageLink; 37 import org.thingsboard.server.common.data.page.TimePageLink;
37 import org.thingsboard.server.dao.DaoUtil; 38 import org.thingsboard.server.dao.DaoUtil;
@@ -142,7 +143,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -142,7 +143,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
142 long partition = toPartitionTs(LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli()); 143 long partition = toPartitionTs(LocalDate.now().atStartOfDay().toInstant(ZoneOffset.UTC).toEpochMilli());
143 BoundStatement stmt = getSaveByTenantStmt().bind(); 144 BoundStatement stmt = getSaveByTenantStmt().bind();
144 stmt = setSaveStmtVariables(stmt, auditLog, partition); 145 stmt = setSaveStmtVariables(stmt, auditLog, partition);
145 - return getFuture(executeAsyncWrite(stmt), rs -> null); 146 + return getFuture(executeAsyncWrite(auditLog.getTenantId(), stmt), rs -> null);
146 } 147 }
147 148
148 @Override 149 @Override
@@ -151,7 +152,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -151,7 +152,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
151 152
152 BoundStatement stmt = getSaveByTenantIdAndEntityIdStmt().bind(); 153 BoundStatement stmt = getSaveByTenantIdAndEntityIdStmt().bind();
153 stmt = setSaveStmtVariables(stmt, auditLog, -1); 154 stmt = setSaveStmtVariables(stmt, auditLog, -1);
154 - return getFuture(executeAsyncWrite(stmt), rs -> null); 155 + return getFuture(executeAsyncWrite(auditLog.getTenantId(), stmt), rs -> null);
155 } 156 }
156 157
157 @Override 158 @Override
@@ -160,7 +161,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -160,7 +161,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
160 161
161 BoundStatement stmt = getSaveByTenantIdAndCustomerIdStmt().bind(); 162 BoundStatement stmt = getSaveByTenantIdAndCustomerIdStmt().bind();
162 stmt = setSaveStmtVariables(stmt, auditLog, -1); 163 stmt = setSaveStmtVariables(stmt, auditLog, -1);
163 - return getFuture(executeAsyncWrite(stmt), rs -> null); 164 + return getFuture(executeAsyncWrite(auditLog.getTenantId(), stmt), rs -> null);
164 } 165 }
165 166
166 @Override 167 @Override
@@ -169,11 +170,11 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -169,11 +170,11 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
169 170
170 BoundStatement stmt = getSaveByTenantIdAndUserIdStmt().bind(); 171 BoundStatement stmt = getSaveByTenantIdAndUserIdStmt().bind();
171 stmt = setSaveStmtVariables(stmt, auditLog, -1); 172 stmt = setSaveStmtVariables(stmt, auditLog, -1);
172 - return getFuture(executeAsyncWrite(stmt), rs -> null); 173 + return getFuture(executeAsyncWrite(auditLog.getTenantId(), stmt), rs -> null);
173 } 174 }
174 175
175 private BoundStatement setSaveStmtVariables(BoundStatement stmt, AuditLog auditLog, long partition) { 176 private BoundStatement setSaveStmtVariables(BoundStatement stmt, AuditLog auditLog, long partition) {
176 - stmt.setUUID(0, auditLog.getId().getId()) 177 + stmt.setUUID(0, auditLog.getId().getId())
177 .setUUID(1, auditLog.getTenantId().getId()) 178 .setUUID(1, auditLog.getTenantId().getId())
178 .setUUID(2, auditLog.getCustomerId().getId()) 179 .setUUID(2, auditLog.getCustomerId().getId())
179 .setUUID(3, auditLog.getEntityId().getId()) 180 .setUUID(3, auditLog.getEntityId().getId())
@@ -200,7 +201,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -200,7 +201,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
200 BoundStatement stmt = getPartitionInsertStmt().bind(); 201 BoundStatement stmt = getPartitionInsertStmt().bind();
201 stmt = stmt.setUUID(0, auditLog.getTenantId().getId()) 202 stmt = stmt.setUUID(0, auditLog.getTenantId().getId())
202 .setLong(1, partition); 203 .setLong(1, partition);
203 - return getFuture(executeAsyncWrite(stmt), rs -> null); 204 + return getFuture(executeAsyncWrite(auditLog.getTenantId(), stmt), rs -> null);
204 } 205 }
205 206
206 private PreparedStatement getSaveByTenantStmt() { 207 private PreparedStatement getSaveByTenantStmt() {
@@ -249,7 +250,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -249,7 +250,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
249 columnsList.add(ModelConstants.AUDIT_LOG_PARTITION_PROPERTY); 250 columnsList.add(ModelConstants.AUDIT_LOG_PARTITION_PROPERTY);
250 } 251 }
251 StringJoiner values = new StringJoiner(","); 252 StringJoiner values = new StringJoiner(",");
252 - for (int i=0;i<columnsList.size();i++) { 253 + for (int i = 0; i < columnsList.size(); i++) {
253 values.add("?"); 254 values.add("?");
254 } 255 }
255 String statementString = INSERT_INTO + cfName + " (" + String.join(",", columnsList) + ") VALUES (" + values.toString() + ")"; 256 String statementString = INSERT_INTO + cfName + " (" + String.join(",", columnsList) + ") VALUES (" + values.toString() + ")";
@@ -274,7 +275,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -274,7 +275,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
274 @Override 275 @Override
275 public List<AuditLog> findAuditLogsByTenantIdAndEntityId(UUID tenantId, EntityId entityId, TimePageLink pageLink) { 276 public List<AuditLog> findAuditLogsByTenantIdAndEntityId(UUID tenantId, EntityId entityId, TimePageLink pageLink) {
276 log.trace("Try to find audit logs by tenant [{}], entity [{}] and pageLink [{}]", tenantId, entityId, pageLink); 277 log.trace("Try to find audit logs by tenant [{}], entity [{}] and pageLink [{}]", tenantId, entityId, pageLink);
277 - List<AuditLogEntity> entities = findPageWithTimeSearch(AUDIT_LOG_BY_ENTITY_ID_CF, 278 + List<AuditLogEntity> entities = findPageWithTimeSearch(new TenantId(tenantId), AUDIT_LOG_BY_ENTITY_ID_CF,
278 Arrays.asList(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, tenantId), 279 Arrays.asList(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, tenantId),
279 eq(ModelConstants.AUDIT_LOG_ENTITY_TYPE_PROPERTY, entityId.getEntityType()), 280 eq(ModelConstants.AUDIT_LOG_ENTITY_TYPE_PROPERTY, entityId.getEntityType()),
280 eq(ModelConstants.AUDIT_LOG_ENTITY_ID_PROPERTY, entityId.getId())), 281 eq(ModelConstants.AUDIT_LOG_ENTITY_ID_PROPERTY, entityId.getId())),
@@ -286,7 +287,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -286,7 +287,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
286 @Override 287 @Override
287 public List<AuditLog> findAuditLogsByTenantIdAndCustomerId(UUID tenantId, CustomerId customerId, TimePageLink pageLink) { 288 public List<AuditLog> findAuditLogsByTenantIdAndCustomerId(UUID tenantId, CustomerId customerId, TimePageLink pageLink) {
288 log.trace("Try to find audit logs by tenant [{}], customer [{}] and pageLink [{}]", tenantId, customerId, pageLink); 289 log.trace("Try to find audit logs by tenant [{}], customer [{}] and pageLink [{}]", tenantId, customerId, pageLink);
289 - List<AuditLogEntity> entities = findPageWithTimeSearch(AUDIT_LOG_BY_CUSTOMER_ID_CF, 290 + List<AuditLogEntity> entities = findPageWithTimeSearch(new TenantId(tenantId), AUDIT_LOG_BY_CUSTOMER_ID_CF,
290 Arrays.asList(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, tenantId), 291 Arrays.asList(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, tenantId),
291 eq(ModelConstants.AUDIT_LOG_CUSTOMER_ID_PROPERTY, customerId.getId())), 292 eq(ModelConstants.AUDIT_LOG_CUSTOMER_ID_PROPERTY, customerId.getId())),
292 pageLink); 293 pageLink);
@@ -297,7 +298,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -297,7 +298,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
297 @Override 298 @Override
298 public List<AuditLog> findAuditLogsByTenantIdAndUserId(UUID tenantId, UserId userId, TimePageLink pageLink) { 299 public List<AuditLog> findAuditLogsByTenantIdAndUserId(UUID tenantId, UserId userId, TimePageLink pageLink) {
299 log.trace("Try to find audit logs by tenant [{}], user [{}] and pageLink [{}]", tenantId, userId, pageLink); 300 log.trace("Try to find audit logs by tenant [{}], user [{}] and pageLink [{}]", tenantId, userId, pageLink);
300 - List<AuditLogEntity> entities = findPageWithTimeSearch(AUDIT_LOG_BY_USER_ID_CF, 301 + List<AuditLogEntity> entities = findPageWithTimeSearch(new TenantId(tenantId), AUDIT_LOG_BY_USER_ID_CF,
301 Arrays.asList(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, tenantId), 302 Arrays.asList(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, tenantId),
302 eq(ModelConstants.AUDIT_LOG_USER_ID_PROPERTY, userId.getId())), 303 eq(ModelConstants.AUDIT_LOG_USER_ID_PROPERTY, userId.getId())),
303 pageLink); 304 pageLink);
@@ -339,7 +340,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -339,7 +340,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
339 if (cursor.isFull() || !cursor.hasNextPartition()) { 340 if (cursor.isFull() || !cursor.hasNextPartition()) {
340 return cursor.getData(); 341 return cursor.getData();
341 } else { 342 } else {
342 - cursor.addData(findPageWithTimeSearch(AUDIT_LOG_BY_TENANT_ID_CF, 343 + cursor.addData(findPageWithTimeSearch(new TenantId(cursor.getTenantId()), AUDIT_LOG_BY_TENANT_ID_CF,
343 Arrays.asList(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, cursor.getTenantId()), 344 Arrays.asList(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, cursor.getTenantId()),
344 eq(ModelConstants.AUDIT_LOG_PARTITION_PROPERTY, cursor.getNextPartition())), 345 eq(ModelConstants.AUDIT_LOG_PARTITION_PROPERTY, cursor.getNextPartition())),
345 cursor.getPageLink())); 346 cursor.getPageLink()));
@@ -352,7 +353,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo @@ -352,7 +353,7 @@ public class CassandraAuditLogDao extends CassandraAbstractSearchTimeDao<AuditLo
352 .where(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, tenantId)); 353 .where(eq(ModelConstants.AUDIT_LOG_TENANT_ID_PROPERTY, tenantId));
353 select.and(QueryBuilder.gte(ModelConstants.PARTITION_COLUMN, minPartition)); 354 select.and(QueryBuilder.gte(ModelConstants.PARTITION_COLUMN, minPartition));
354 select.and(QueryBuilder.lte(ModelConstants.PARTITION_COLUMN, maxPartition)); 355 select.and(QueryBuilder.lte(ModelConstants.PARTITION_COLUMN, maxPartition));
355 - return executeRead(select); 356 + return executeRead(new TenantId(tenantId), select);
356 } 357 }
357 358
358 } 359 }
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.cache; 16 package org.thingsboard.server.dao.cache;
17 17
18 import org.springframework.cache.interceptor.KeyGenerator; 18 import org.springframework.cache.interceptor.KeyGenerator;
  19 +import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.security.DeviceCredentials; 20 import org.thingsboard.server.common.data.security.DeviceCredentials;
20 import org.thingsboard.server.dao.device.DeviceCredentialsService; 21 import org.thingsboard.server.dao.device.DeviceCredentialsService;
21 22
@@ -28,9 +29,10 @@ public class PreviousDeviceCredentialsIdKeyGenerator implements KeyGenerator { @@ -28,9 +29,10 @@ public class PreviousDeviceCredentialsIdKeyGenerator implements KeyGenerator {
28 @Override 29 @Override
29 public Object generate(Object o, Method method, Object... objects) { 30 public Object generate(Object o, Method method, Object... objects) {
30 DeviceCredentialsService deviceCredentialsService = (DeviceCredentialsService) o; 31 DeviceCredentialsService deviceCredentialsService = (DeviceCredentialsService) o;
31 - DeviceCredentials deviceCredentials = (DeviceCredentials) objects[0]; 32 + TenantId tenantId = (TenantId) objects[0];
  33 + DeviceCredentials deviceCredentials = (DeviceCredentials) objects[1];
32 if (deviceCredentials.getDeviceId() != null) { 34 if (deviceCredentials.getDeviceId() != null) {
33 - DeviceCredentials oldDeviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(deviceCredentials.getDeviceId()); 35 + DeviceCredentials oldDeviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceCredentials.getDeviceId());
34 if (oldDeviceCredentials != null) { 36 if (oldDeviceCredentials != null) {
35 return oldDeviceCredentials.getCredentialsId(); 37 return oldDeviceCredentials.getCredentialsId();
36 } 38 }
@@ -25,6 +25,8 @@ import org.apache.commons.lang3.StringUtils; @@ -25,6 +25,8 @@ import org.apache.commons.lang3.StringUtils;
25 import org.springframework.beans.factory.annotation.Autowired; 25 import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.stereotype.Service; 26 import org.springframework.stereotype.Service;
27 import org.thingsboard.server.common.data.id.ComponentDescriptorId; 27 import org.thingsboard.server.common.data.id.ComponentDescriptorId;
  28 +import org.thingsboard.server.common.data.id.EntityId;
  29 +import org.thingsboard.server.common.data.id.TenantId;
28 import org.thingsboard.server.common.data.page.TextPageData; 30 import org.thingsboard.server.common.data.page.TextPageData;
29 import org.thingsboard.server.common.data.page.TextPageLink; 31 import org.thingsboard.server.common.data.page.TextPageLink;
30 import org.thingsboard.server.common.data.plugin.ComponentDescriptor; 32 import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
@@ -49,50 +51,50 @@ public class BaseComponentDescriptorService implements ComponentDescriptorServic @@ -49,50 +51,50 @@ public class BaseComponentDescriptorService implements ComponentDescriptorServic
49 private ComponentDescriptorDao componentDescriptorDao; 51 private ComponentDescriptorDao componentDescriptorDao;
50 52
51 @Override 53 @Override
52 - public ComponentDescriptor saveComponent(ComponentDescriptor component) {  
53 - componentValidator.validate(component);  
54 - Optional<ComponentDescriptor> result = componentDescriptorDao.saveIfNotExist(component); 54 + public ComponentDescriptor saveComponent(TenantId tenantId, ComponentDescriptor component) {
  55 + componentValidator.validate(component, data -> new TenantId(EntityId.NULL_UUID));
  56 + Optional<ComponentDescriptor> result = componentDescriptorDao.saveIfNotExist(tenantId, component);
55 if (result.isPresent()) { 57 if (result.isPresent()) {
56 return result.get(); 58 return result.get();
57 } else { 59 } else {
58 - return componentDescriptorDao.findByClazz(component.getClazz()); 60 + return componentDescriptorDao.findByClazz(tenantId, component.getClazz());
59 } 61 }
60 } 62 }
61 63
62 @Override 64 @Override
63 - public ComponentDescriptor findById(ComponentDescriptorId componentId) { 65 + public ComponentDescriptor findById(TenantId tenantId, ComponentDescriptorId componentId) {
64 Validator.validateId(componentId, "Incorrect component id for search request."); 66 Validator.validateId(componentId, "Incorrect component id for search request.");
65 - return componentDescriptorDao.findById(componentId); 67 + return componentDescriptorDao.findById(tenantId, componentId);
66 } 68 }
67 69
68 @Override 70 @Override
69 - public ComponentDescriptor findByClazz(String clazz) { 71 + public ComponentDescriptor findByClazz(TenantId tenantId, String clazz) {
70 Validator.validateString(clazz, "Incorrect clazz for search request."); 72 Validator.validateString(clazz, "Incorrect clazz for search request.");
71 - return componentDescriptorDao.findByClazz(clazz); 73 + return componentDescriptorDao.findByClazz(tenantId, clazz);
72 } 74 }
73 75
74 @Override 76 @Override
75 - public TextPageData<ComponentDescriptor> findByTypeAndPageLink(ComponentType type, TextPageLink pageLink) { 77 + public TextPageData<ComponentDescriptor> findByTypeAndPageLink(TenantId tenantId, ComponentType type, TextPageLink pageLink) {
76 Validator.validatePageLink(pageLink, "Incorrect PageLink object for search plugin components request."); 78 Validator.validatePageLink(pageLink, "Incorrect PageLink object for search plugin components request.");
77 - List<ComponentDescriptor> components = componentDescriptorDao.findByTypeAndPageLink(type, pageLink); 79 + List<ComponentDescriptor> components = componentDescriptorDao.findByTypeAndPageLink(tenantId, type, pageLink);
78 return new TextPageData<>(components, pageLink); 80 return new TextPageData<>(components, pageLink);
79 } 81 }
80 82
81 @Override 83 @Override
82 - public TextPageData<ComponentDescriptor> findByScopeAndTypeAndPageLink(ComponentScope scope, ComponentType type, TextPageLink pageLink) { 84 + public TextPageData<ComponentDescriptor> findByScopeAndTypeAndPageLink(TenantId tenantId, ComponentScope scope, ComponentType type, TextPageLink pageLink) {
83 Validator.validatePageLink(pageLink, "Incorrect PageLink object for search plugin components request."); 85 Validator.validatePageLink(pageLink, "Incorrect PageLink object for search plugin components request.");
84 - List<ComponentDescriptor> components = componentDescriptorDao.findByScopeAndTypeAndPageLink(scope, type, pageLink); 86 + List<ComponentDescriptor> components = componentDescriptorDao.findByScopeAndTypeAndPageLink(tenantId, scope, type, pageLink);
85 return new TextPageData<>(components, pageLink); 87 return new TextPageData<>(components, pageLink);
86 } 88 }
87 89
88 @Override 90 @Override
89 - public void deleteByClazz(String clazz) { 91 + public void deleteByClazz(TenantId tenantId, String clazz) {
90 Validator.validateString(clazz, "Incorrect clazz for delete request."); 92 Validator.validateString(clazz, "Incorrect clazz for delete request.");
91 - componentDescriptorDao.deleteByClazz(clazz); 93 + componentDescriptorDao.deleteByClazz(tenantId, clazz);
92 } 94 }
93 95
94 @Override 96 @Override
95 - public boolean validate(ComponentDescriptor component, JsonNode configuration) { 97 + public boolean validate(TenantId tenantId, ComponentDescriptor component, JsonNode configuration) {
96 JsonValidator validator = JsonSchemaFactory.byDefault().getValidator(); 98 JsonValidator validator = JsonSchemaFactory.byDefault().getValidator();
97 try { 99 try {
98 if (!component.getConfigurationDescriptor().has("schema")) { 100 if (!component.getConfigurationDescriptor().has("schema")) {
@@ -109,7 +111,7 @@ public class BaseComponentDescriptorService implements ComponentDescriptorServic @@ -109,7 +111,7 @@ public class BaseComponentDescriptorService implements ComponentDescriptorServic
109 private DataValidator<ComponentDescriptor> componentValidator = 111 private DataValidator<ComponentDescriptor> componentValidator =
110 new DataValidator<ComponentDescriptor>() { 112 new DataValidator<ComponentDescriptor>() {
111 @Override 113 @Override
112 - protected void validateDataImpl(ComponentDescriptor plugin) { 114 + protected void validateDataImpl(TenantId tenantId, ComponentDescriptor plugin) {
113 if (plugin.getType() == null) { 115 if (plugin.getType() == null) {
114 throw new DataValidationException("Component type should be specified!."); 116 throw new DataValidationException("Component type should be specified!.");
115 } 117 }
@@ -23,6 +23,7 @@ import com.datastax.driver.core.utils.UUIDs; @@ -23,6 +23,7 @@ import com.datastax.driver.core.utils.UUIDs;
23 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
24 import org.springframework.stereotype.Component; 24 import org.springframework.stereotype.Component;
25 import org.thingsboard.server.common.data.id.ComponentDescriptorId; 25 import org.thingsboard.server.common.data.id.ComponentDescriptorId;
  26 +import org.thingsboard.server.common.data.id.TenantId;
26 import org.thingsboard.server.common.data.page.TextPageLink; 27 import org.thingsboard.server.common.data.page.TextPageLink;
27 import org.thingsboard.server.common.data.plugin.ComponentDescriptor; 28 import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
28 import org.thingsboard.server.common.data.plugin.ComponentScope; 29 import org.thingsboard.server.common.data.plugin.ComponentScope;
@@ -62,10 +63,10 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch @@ -62,10 +63,10 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch
62 } 63 }
63 64
64 @Override 65 @Override
65 - public Optional<ComponentDescriptor> saveIfNotExist(ComponentDescriptor component) { 66 + public Optional<ComponentDescriptor> saveIfNotExist(TenantId tenantId, ComponentDescriptor component) {
66 ComponentDescriptorEntity entity = new ComponentDescriptorEntity(component); 67 ComponentDescriptorEntity entity = new ComponentDescriptorEntity(component);
67 log.debug("Save component entity [{}]", entity); 68 log.debug("Save component entity [{}]", entity);
68 - Optional<ComponentDescriptor> result = saveIfNotExist(entity); 69 + Optional<ComponentDescriptor> result = saveIfNotExist(tenantId, entity);
69 if (log.isTraceEnabled()) { 70 if (log.isTraceEnabled()) {
70 log.trace("Saved result: [{}] for component entity [{}]", result.isPresent(), result.orElse(null)); 71 log.trace("Saved result: [{}] for component entity [{}]", result.isPresent(), result.orElse(null));
71 } else { 72 } else {
@@ -75,9 +76,9 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch @@ -75,9 +76,9 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch
75 } 76 }
76 77
77 @Override 78 @Override
78 - public ComponentDescriptor findById(ComponentDescriptorId componentId) { 79 + public ComponentDescriptor findById(TenantId tenantId, ComponentDescriptorId componentId) {
79 log.debug("Search component entity by id [{}]", componentId); 80 log.debug("Search component entity by id [{}]", componentId);
80 - ComponentDescriptor componentDescriptor = super.findById(componentId.getId()); 81 + ComponentDescriptor componentDescriptor = super.findById(tenantId, componentId.getId());
81 if (log.isTraceEnabled()) { 82 if (log.isTraceEnabled()) {
82 log.trace("Search result: [{}] for component entity [{}]", componentDescriptor != null, componentDescriptor); 83 log.trace("Search result: [{}] for component entity [{}]", componentDescriptor != null, componentDescriptor);
83 } else { 84 } else {
@@ -87,11 +88,11 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch @@ -87,11 +88,11 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch
87 } 88 }
88 89
89 @Override 90 @Override
90 - public ComponentDescriptor findByClazz(String clazz) { 91 + public ComponentDescriptor findByClazz(TenantId tenantId, String clazz) {
91 log.debug("Search component entity by clazz [{}]", clazz); 92 log.debug("Search component entity by clazz [{}]", clazz);
92 Select.Where query = select().from(getColumnFamilyName()).where(eq(ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY, clazz)); 93 Select.Where query = select().from(getColumnFamilyName()).where(eq(ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY, clazz));
93 log.trace("Execute query [{}]", query); 94 log.trace("Execute query [{}]", query);
94 - ComponentDescriptorEntity entity = findOneByStatement(query); 95 + ComponentDescriptorEntity entity = findOneByStatement(tenantId, query);
95 if (log.isTraceEnabled()) { 96 if (log.isTraceEnabled()) {
96 log.trace("Search result: [{}] for component entity [{}]", entity != null, entity); 97 log.trace("Search result: [{}] for component entity [{}]", entity != null, entity);
97 } else { 98 } else {
@@ -101,9 +102,9 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch @@ -101,9 +102,9 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch
101 } 102 }
102 103
103 @Override 104 @Override
104 - public List<ComponentDescriptor> findByTypeAndPageLink(ComponentType type, TextPageLink pageLink) { 105 + public List<ComponentDescriptor> findByTypeAndPageLink(TenantId tenantId, ComponentType type, TextPageLink pageLink) {
105 log.debug("Try to find component by type [{}] and pageLink [{}]", type, pageLink); 106 log.debug("Try to find component by type [{}] and pageLink [{}]", type, pageLink);
106 - List<ComponentDescriptorEntity> entities = findPageWithTextSearch(ModelConstants.COMPONENT_DESCRIPTOR_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 107 + List<ComponentDescriptorEntity> entities = findPageWithTextSearch(tenantId, ModelConstants.COMPONENT_DESCRIPTOR_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
107 Arrays.asList(eq(ModelConstants.COMPONENT_DESCRIPTOR_TYPE_PROPERTY, type)), pageLink); 108 Arrays.asList(eq(ModelConstants.COMPONENT_DESCRIPTOR_TYPE_PROPERTY, type)), pageLink);
108 if (log.isTraceEnabled()) { 109 if (log.isTraceEnabled()) {
109 log.trace(SEARCH_RESULT, Arrays.toString(entities.toArray())); 110 log.trace(SEARCH_RESULT, Arrays.toString(entities.toArray()));
@@ -114,9 +115,9 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch @@ -114,9 +115,9 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch
114 } 115 }
115 116
116 @Override 117 @Override
117 - public List<ComponentDescriptor> findByScopeAndTypeAndPageLink(ComponentScope scope, ComponentType type, TextPageLink pageLink) { 118 + public List<ComponentDescriptor> findByScopeAndTypeAndPageLink(TenantId tenantId, ComponentScope scope, ComponentType type, TextPageLink pageLink) {
118 log.debug("Try to find component by scope [{}] and type [{}] and pageLink [{}]", scope, type, pageLink); 119 log.debug("Try to find component by scope [{}] and type [{}] and pageLink [{}]", scope, type, pageLink);
119 - List<ComponentDescriptorEntity> entities = findPageWithTextSearch(ModelConstants.COMPONENT_DESCRIPTOR_BY_SCOPE_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 120 + List<ComponentDescriptorEntity> entities = findPageWithTextSearch(tenantId, ModelConstants.COMPONENT_DESCRIPTOR_BY_SCOPE_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
120 Arrays.asList(eq(ModelConstants.COMPONENT_DESCRIPTOR_TYPE_PROPERTY, type), 121 Arrays.asList(eq(ModelConstants.COMPONENT_DESCRIPTOR_TYPE_PROPERTY, type),
121 eq(ModelConstants.COMPONENT_DESCRIPTOR_SCOPE_PROPERTY, scope.name())), pageLink); 122 eq(ModelConstants.COMPONENT_DESCRIPTOR_SCOPE_PROPERTY, scope.name())), pageLink);
122 if (log.isTraceEnabled()) { 123 if (log.isTraceEnabled()) {
@@ -127,34 +128,34 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch @@ -127,34 +128,34 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch
127 return DaoUtil.convertDataList(entities); 128 return DaoUtil.convertDataList(entities);
128 } 129 }
129 130
130 - public boolean removeById(UUID key) { 131 + public boolean removeById(TenantId tenantId, UUID key) {
131 Statement delete = QueryBuilder.delete().all().from(ModelConstants.COMPONENT_DESCRIPTOR_BY_ID).where(eq(ModelConstants.ID_PROPERTY, key)); 132 Statement delete = QueryBuilder.delete().all().from(ModelConstants.COMPONENT_DESCRIPTOR_BY_ID).where(eq(ModelConstants.ID_PROPERTY, key));
132 log.debug("Remove request: {}", delete.toString()); 133 log.debug("Remove request: {}", delete.toString());
133 - return executeWrite(delete).wasApplied(); 134 + return executeWrite(tenantId, delete).wasApplied();
134 } 135 }
135 136
136 @Override 137 @Override
137 - public void deleteById(ComponentDescriptorId id) { 138 + public void deleteById(TenantId tenantId, ComponentDescriptorId id) {
138 log.debug("Delete plugin meta-data entity by id [{}]", id); 139 log.debug("Delete plugin meta-data entity by id [{}]", id);
139 - boolean result = removeById(id.getId()); 140 + boolean result = removeById(tenantId, id.getId());
140 log.debug("Delete result: [{}]", result); 141 log.debug("Delete result: [{}]", result);
141 } 142 }
142 143
143 @Override 144 @Override
144 - public void deleteByClazz(String clazz) { 145 + public void deleteByClazz(TenantId tenantId, String clazz) {
145 log.debug("Delete plugin meta-data entity by id [{}]", clazz); 146 log.debug("Delete plugin meta-data entity by id [{}]", clazz);
146 Statement delete = QueryBuilder.delete().all().from(getColumnFamilyName()).where(eq(ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY, clazz)); 147 Statement delete = QueryBuilder.delete().all().from(getColumnFamilyName()).where(eq(ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY, clazz));
147 log.debug("Remove request: {}", delete.toString()); 148 log.debug("Remove request: {}", delete.toString());
148 - ResultSet resultSet = executeWrite(delete); 149 + ResultSet resultSet = executeWrite(tenantId, delete);
149 log.debug("Delete result: [{}]", resultSet.wasApplied()); 150 log.debug("Delete result: [{}]", resultSet.wasApplied());
150 } 151 }
151 152
152 - private Optional<ComponentDescriptor> saveIfNotExist(ComponentDescriptorEntity entity) { 153 + private Optional<ComponentDescriptor> saveIfNotExist(TenantId tenantId, ComponentDescriptorEntity entity) {
153 if (entity.getId() == null) { 154 if (entity.getId() == null) {
154 entity.setId(UUIDs.timeBased()); 155 entity.setId(UUIDs.timeBased());
155 } 156 }
156 157
157 - ResultSet rs = executeRead(QueryBuilder.insertInto(getColumnFamilyName()) 158 + ResultSet rs = executeRead(tenantId, QueryBuilder.insertInto(getColumnFamilyName())
158 .value(ModelConstants.ID_PROPERTY, entity.getId()) 159 .value(ModelConstants.ID_PROPERTY, entity.getId())
159 .value(ModelConstants.COMPONENT_DESCRIPTOR_NAME_PROPERTY, entity.getName()) 160 .value(ModelConstants.COMPONENT_DESCRIPTOR_NAME_PROPERTY, entity.getName())
160 .value(ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY, entity.getClazz()) 161 .value(ModelConstants.COMPONENT_DESCRIPTOR_CLASS_PROPERTY, entity.getClazz())
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.component; 16 package org.thingsboard.server.dao.component;
17 17
18 import org.thingsboard.server.common.data.id.ComponentDescriptorId; 18 import org.thingsboard.server.common.data.id.ComponentDescriptorId;
  19 +import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.page.TextPageLink; 20 import org.thingsboard.server.common.data.page.TextPageLink;
20 import org.thingsboard.server.common.data.plugin.ComponentDescriptor; 21 import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
21 import org.thingsboard.server.common.data.plugin.ComponentScope; 22 import org.thingsboard.server.common.data.plugin.ComponentScope;
@@ -30,18 +31,18 @@ import java.util.Optional; @@ -30,18 +31,18 @@ import java.util.Optional;
30 */ 31 */
31 public interface ComponentDescriptorDao extends Dao<ComponentDescriptor> { 32 public interface ComponentDescriptorDao extends Dao<ComponentDescriptor> {
32 33
33 - Optional<ComponentDescriptor> saveIfNotExist(ComponentDescriptor component); 34 + Optional<ComponentDescriptor> saveIfNotExist(TenantId tenantId, ComponentDescriptor component);
34 35
35 - ComponentDescriptor findById(ComponentDescriptorId componentId); 36 + ComponentDescriptor findById(TenantId tenantId, ComponentDescriptorId componentId);
36 37
37 - ComponentDescriptor findByClazz(String clazz); 38 + ComponentDescriptor findByClazz(TenantId tenantId, String clazz);
38 39
39 - List<ComponentDescriptor> findByTypeAndPageLink(ComponentType type, TextPageLink pageLink); 40 + List<ComponentDescriptor> findByTypeAndPageLink(TenantId tenantId, ComponentType type, TextPageLink pageLink);
40 41
41 - List<ComponentDescriptor> findByScopeAndTypeAndPageLink(ComponentScope scope, ComponentType type, TextPageLink pageLink); 42 + List<ComponentDescriptor> findByScopeAndTypeAndPageLink(TenantId tenantId, ComponentScope scope, ComponentType type, TextPageLink pageLink);
42 43
43 - void deleteById(ComponentDescriptorId componentId); 44 + void deleteById(TenantId tenantId, ComponentDescriptorId componentId);
44 45
45 - void deleteByClazz(String clazz); 46 + void deleteByClazz(TenantId tenantId, String clazz);
46 47
47 } 48 }
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.component; @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.component;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import org.thingsboard.server.common.data.id.ComponentDescriptorId; 19 import org.thingsboard.server.common.data.id.ComponentDescriptorId;
  20 +import org.thingsboard.server.common.data.id.TenantId;
20 import org.thingsboard.server.common.data.page.TextPageData; 21 import org.thingsboard.server.common.data.page.TextPageData;
21 import org.thingsboard.server.common.data.page.TextPageLink; 22 import org.thingsboard.server.common.data.page.TextPageLink;
22 import org.thingsboard.server.common.data.plugin.ComponentDescriptor; 23 import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
@@ -28,18 +29,18 @@ import org.thingsboard.server.common.data.plugin.ComponentType; @@ -28,18 +29,18 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
28 */ 29 */
29 public interface ComponentDescriptorService { 30 public interface ComponentDescriptorService {
30 31
31 - ComponentDescriptor saveComponent(ComponentDescriptor component); 32 + ComponentDescriptor saveComponent(TenantId tenantId, ComponentDescriptor component);
32 33
33 - ComponentDescriptor findById(ComponentDescriptorId componentId); 34 + ComponentDescriptor findById(TenantId tenantId, ComponentDescriptorId componentId);
34 35
35 - ComponentDescriptor findByClazz(String clazz); 36 + ComponentDescriptor findByClazz(TenantId tenantId, String clazz);
36 37
37 - TextPageData<ComponentDescriptor> findByTypeAndPageLink(ComponentType type, TextPageLink pageLink); 38 + TextPageData<ComponentDescriptor> findByTypeAndPageLink(TenantId tenantId, ComponentType type, TextPageLink pageLink);
38 39
39 - TextPageData<ComponentDescriptor> findByScopeAndTypeAndPageLink(ComponentScope scope, ComponentType type, TextPageLink pageLink); 40 + TextPageData<ComponentDescriptor> findByScopeAndTypeAndPageLink(TenantId tenantId, ComponentScope scope, ComponentType type, TextPageLink pageLink);
40 41
41 - boolean validate(ComponentDescriptor component, JsonNode configuration); 42 + boolean validate(TenantId tenantId, ComponentDescriptor component, JsonNode configuration);
42 43
43 - void deleteByClazz(String clazz); 44 + void deleteByClazz(TenantId tenantId, String clazz);
44 45
45 } 46 }
@@ -19,6 +19,7 @@ import com.datastax.driver.core.querybuilder.Select; @@ -19,6 +19,7 @@ import com.datastax.driver.core.querybuilder.Select;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.stereotype.Component; 20 import org.springframework.stereotype.Component;
21 import org.thingsboard.server.common.data.Customer; 21 import org.thingsboard.server.common.data.Customer;
  22 +import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.common.data.page.TextPageLink; 23 import org.thingsboard.server.common.data.page.TextPageLink;
23 import org.thingsboard.server.dao.DaoUtil; 24 import org.thingsboard.server.dao.DaoUtil;
24 import org.thingsboard.server.dao.model.ModelConstants; 25 import org.thingsboard.server.dao.model.ModelConstants;
@@ -36,6 +37,7 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select; @@ -36,6 +37,7 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
36 import static org.thingsboard.server.dao.model.ModelConstants.CUSTOMER_BY_TENANT_AND_TITLE_VIEW_NAME; 37 import static org.thingsboard.server.dao.model.ModelConstants.CUSTOMER_BY_TENANT_AND_TITLE_VIEW_NAME;
37 import static org.thingsboard.server.dao.model.ModelConstants.CUSTOMER_TENANT_ID_PROPERTY; 38 import static org.thingsboard.server.dao.model.ModelConstants.CUSTOMER_TENANT_ID_PROPERTY;
38 import static org.thingsboard.server.dao.model.ModelConstants.CUSTOMER_TITLE_PROPERTY; 39 import static org.thingsboard.server.dao.model.ModelConstants.CUSTOMER_TITLE_PROPERTY;
  40 +
39 @Component 41 @Component
40 @Slf4j 42 @Slf4j
41 @NoSqlDao 43 @NoSqlDao
@@ -54,9 +56,9 @@ public class CassandraCustomerDao extends CassandraAbstractSearchTextDao<Custome @@ -54,9 +56,9 @@ public class CassandraCustomerDao extends CassandraAbstractSearchTextDao<Custome
54 @Override 56 @Override
55 public List<Customer> findCustomersByTenantId(UUID tenantId, TextPageLink pageLink) { 57 public List<Customer> findCustomersByTenantId(UUID tenantId, TextPageLink pageLink) {
56 log.debug("Try to find customers by tenantId [{}] and pageLink [{}]", tenantId, pageLink); 58 log.debug("Try to find customers by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
57 - List<CustomerEntity> customerEntities = findPageWithTextSearch(ModelConstants.CUSTOMER_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 59 + List<CustomerEntity> customerEntities = findPageWithTextSearch(new TenantId(tenantId), ModelConstants.CUSTOMER_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
58 Arrays.asList(eq(ModelConstants.CUSTOMER_TENANT_ID_PROPERTY, tenantId)), 60 Arrays.asList(eq(ModelConstants.CUSTOMER_TENANT_ID_PROPERTY, tenantId)),
59 - pageLink); 61 + pageLink);
60 log.trace("Found customers [{}] by tenantId [{}] and pageLink [{}]", customerEntities, tenantId, pageLink); 62 log.trace("Found customers [{}] by tenantId [{}] and pageLink [{}]", customerEntities, tenantId, pageLink);
61 return DaoUtil.convertDataList(customerEntities); 63 return DaoUtil.convertDataList(customerEntities);
62 } 64 }
@@ -67,7 +69,7 @@ public class CassandraCustomerDao extends CassandraAbstractSearchTextDao<Custome @@ -67,7 +69,7 @@ public class CassandraCustomerDao extends CassandraAbstractSearchTextDao<Custome
67 Select.Where query = select.where(); 69 Select.Where query = select.where();
68 query.and(eq(CUSTOMER_TENANT_ID_PROPERTY, tenantId)); 70 query.and(eq(CUSTOMER_TENANT_ID_PROPERTY, tenantId));
69 query.and(eq(CUSTOMER_TITLE_PROPERTY, title)); 71 query.and(eq(CUSTOMER_TITLE_PROPERTY, title));
70 - CustomerEntity customerEntity = findOneByStatement(query); 72 + CustomerEntity customerEntity = findOneByStatement(new TenantId(tenantId), query);
71 Customer customer = DaoUtil.getData(customerEntity); 73 Customer customer = DaoUtil.getData(customerEntity);
72 return Optional.ofNullable(customer); 74 return Optional.ofNullable(customer);
73 } 75 }
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.customer; 16 package org.thingsboard.server.dao.customer;
17 17
18 import org.thingsboard.server.common.data.Customer; 18 import org.thingsboard.server.common.data.Customer;
  19 +import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.page.TextPageLink; 20 import org.thingsboard.server.common.data.page.TextPageLink;
20 import org.thingsboard.server.dao.Dao; 21 import org.thingsboard.server.dao.Dao;
21 22
@@ -34,7 +35,7 @@ public interface CustomerDao extends Dao<Customer> { @@ -34,7 +35,7 @@ public interface CustomerDao extends Dao<Customer> {
34 * @param customer the customer object 35 * @param customer the customer object
35 * @return saved customer object 36 * @return saved customer object
36 */ 37 */
37 - Customer save(Customer customer); 38 + Customer save(TenantId tenantId, Customer customer);
38 39
39 /** 40 /**
40 * Find customers by tenant id and page link. 41 * Find customers by tenant id and page link.
@@ -26,15 +26,15 @@ import java.util.Optional; @@ -26,15 +26,15 @@ import java.util.Optional;
26 26
27 public interface CustomerService { 27 public interface CustomerService {
28 28
29 - Customer findCustomerById(CustomerId customerId); 29 + Customer findCustomerById(TenantId tenantId, CustomerId customerId);
30 30
31 Optional<Customer> findCustomerByTenantIdAndTitle(TenantId tenantId, String title); 31 Optional<Customer> findCustomerByTenantIdAndTitle(TenantId tenantId, String title);
32 32
33 - ListenableFuture<Customer> findCustomerByIdAsync(CustomerId customerId); 33 + ListenableFuture<Customer> findCustomerByIdAsync(TenantId tenantId, CustomerId customerId);
34 34
35 Customer saveCustomer(Customer customer); 35 Customer saveCustomer(Customer customer);
36 36
37 - void deleteCustomer(CustomerId customerId); 37 + void deleteCustomer(TenantId tenantId, CustomerId customerId);
38 38
39 Customer findOrCreatePublicCustomer(TenantId tenantId); 39 Customer findOrCreatePublicCustomer(TenantId tenantId);
40 40
@@ -77,10 +77,10 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @@ -77,10 +77,10 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
77 private DashboardService dashboardService; 77 private DashboardService dashboardService;
78 78
79 @Override 79 @Override
80 - public Customer findCustomerById(CustomerId customerId) { 80 + public Customer findCustomerById(TenantId tenantId, CustomerId customerId) {
81 log.trace("Executing findCustomerById [{}]", customerId); 81 log.trace("Executing findCustomerById [{}]", customerId);
82 Validator.validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); 82 Validator.validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
83 - return customerDao.findById(customerId.getId()); 83 + return customerDao.findById(tenantId, customerId.getId());
84 } 84 }
85 85
86 @Override 86 @Override
@@ -91,36 +91,36 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @@ -91,36 +91,36 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
91 } 91 }
92 92
93 @Override 93 @Override
94 - public ListenableFuture<Customer> findCustomerByIdAsync(CustomerId customerId) { 94 + public ListenableFuture<Customer> findCustomerByIdAsync(TenantId tenantId, CustomerId customerId) {
95 log.trace("Executing findCustomerByIdAsync [{}]", customerId); 95 log.trace("Executing findCustomerByIdAsync [{}]", customerId);
96 validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); 96 validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
97 - return customerDao.findByIdAsync(customerId.getId()); 97 + return customerDao.findByIdAsync(tenantId, customerId.getId());
98 } 98 }
99 99
100 @Override 100 @Override
101 public Customer saveCustomer(Customer customer) { 101 public Customer saveCustomer(Customer customer) {
102 log.trace("Executing saveCustomer [{}]", customer); 102 log.trace("Executing saveCustomer [{}]", customer);
103 - customerValidator.validate(customer);  
104 - Customer savedCustomer = customerDao.save(customer);  
105 - dashboardService.updateCustomerDashboards(savedCustomer.getId()); 103 + customerValidator.validate(customer, Customer::getTenantId);
  104 + Customer savedCustomer = customerDao.save(customer.getTenantId(), customer);
  105 + dashboardService.updateCustomerDashboards(savedCustomer.getTenantId(), savedCustomer.getId());
106 return savedCustomer; 106 return savedCustomer;
107 } 107 }
108 108
109 @Override 109 @Override
110 - public void deleteCustomer(CustomerId customerId) { 110 + public void deleteCustomer(TenantId tenantId, CustomerId customerId) {
111 log.trace("Executing deleteCustomer [{}]", customerId); 111 log.trace("Executing deleteCustomer [{}]", customerId);
112 Validator.validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); 112 Validator.validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
113 - Customer customer = findCustomerById(customerId); 113 + Customer customer = findCustomerById(tenantId, customerId);
114 if (customer == null) { 114 if (customer == null) {
115 throw new IncorrectParameterException("Unable to delete non-existent customer."); 115 throw new IncorrectParameterException("Unable to delete non-existent customer.");
116 } 116 }
117 - dashboardService.unassignCustomerDashboards(customerId); 117 + dashboardService.unassignCustomerDashboards(tenantId, customerId);
118 entityViewService.unassignCustomerEntityViews(customer.getTenantId(), customerId); 118 entityViewService.unassignCustomerEntityViews(customer.getTenantId(), customerId);
119 assetService.unassignCustomerAssets(customer.getTenantId(), customerId); 119 assetService.unassignCustomerAssets(customer.getTenantId(), customerId);
120 deviceService.unassignCustomerDevices(customer.getTenantId(), customerId); 120 deviceService.unassignCustomerDevices(customer.getTenantId(), customerId);
121 userService.deleteCustomerUsers(customer.getTenantId(), customerId); 121 userService.deleteCustomerUsers(customer.getTenantId(), customerId);
122 - deleteEntityRelations(customerId);  
123 - customerDao.removeById(customerId.getId()); 122 + deleteEntityRelations(tenantId, customerId);
  123 + customerDao.removeById(tenantId, customerId.getId());
124 } 124 }
125 125
126 @Override 126 @Override
@@ -139,7 +139,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @@ -139,7 +139,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
139 } catch (IOException e) { 139 } catch (IOException e) {
140 throw new IncorrectParameterException("Unable to create public customer.", e); 140 throw new IncorrectParameterException("Unable to create public customer.", e);
141 } 141 }
142 - return customerDao.save(publicCustomer); 142 + return customerDao.save(tenantId, publicCustomer);
143 } 143 }
144 } 144 }
145 145
@@ -156,14 +156,14 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @@ -156,14 +156,14 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
156 public void deleteCustomersByTenantId(TenantId tenantId) { 156 public void deleteCustomersByTenantId(TenantId tenantId) {
157 log.trace("Executing deleteCustomersByTenantId, tenantId [{}]", tenantId); 157 log.trace("Executing deleteCustomersByTenantId, tenantId [{}]", tenantId);
158 Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); 158 Validator.validateId(tenantId, "Incorrect tenantId " + tenantId);
159 - customersByTenantRemover.removeEntities(tenantId); 159 + customersByTenantRemover.removeEntities(tenantId, tenantId);
160 } 160 }
161 161
162 private DataValidator<Customer> customerValidator = 162 private DataValidator<Customer> customerValidator =
163 new DataValidator<Customer>() { 163 new DataValidator<Customer>() {
164 164
165 @Override 165 @Override
166 - protected void validateCreate(Customer customer) { 166 + protected void validateCreate(TenantId tenantId, Customer customer) {
167 customerDao.findCustomersByTenantIdAndTitle(customer.getTenantId().getId(), customer.getTitle()).ifPresent( 167 customerDao.findCustomersByTenantIdAndTitle(customer.getTenantId().getId(), customer.getTitle()).ifPresent(
168 c -> { 168 c -> {
169 throw new DataValidationException("Customer with such title already exists!"); 169 throw new DataValidationException("Customer with such title already exists!");
@@ -172,7 +172,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @@ -172,7 +172,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
172 } 172 }
173 173
174 @Override 174 @Override
175 - protected void validateUpdate(Customer customer) { 175 + protected void validateUpdate(TenantId tenantId, Customer customer) {
176 customerDao.findCustomersByTenantIdAndTitle(customer.getTenantId().getId(), customer.getTitle()).ifPresent( 176 customerDao.findCustomersByTenantIdAndTitle(customer.getTenantId().getId(), customer.getTitle()).ifPresent(
177 c -> { 177 c -> {
178 if (!c.getId().equals(customer.getId())) { 178 if (!c.getId().equals(customer.getId())) {
@@ -183,7 +183,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @@ -183,7 +183,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
183 } 183 }
184 184
185 @Override 185 @Override
186 - protected void validateDataImpl(Customer customer) { 186 + protected void validateDataImpl(TenantId tenantId, Customer customer) {
187 if (StringUtils.isEmpty(customer.getTitle())) { 187 if (StringUtils.isEmpty(customer.getTitle())) {
188 throw new DataValidationException("Customer title should be specified!"); 188 throw new DataValidationException("Customer title should be specified!");
189 } 189 }
@@ -196,7 +196,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @@ -196,7 +196,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
196 if (customer.getTenantId() == null) { 196 if (customer.getTenantId() == null) {
197 throw new DataValidationException("Customer should be assigned to tenant!"); 197 throw new DataValidationException("Customer should be assigned to tenant!");
198 } else { 198 } else {
199 - Tenant tenant = tenantDao.findById(customer.getTenantId().getId()); 199 + Tenant tenant = tenantDao.findById(tenantId, customer.getTenantId().getId());
200 if (tenant == null) { 200 if (tenant == null) {
201 throw new DataValidationException("Customer is referencing to non-existent tenant!"); 201 throw new DataValidationException("Customer is referencing to non-existent tenant!");
202 } 202 }
@@ -208,13 +208,13 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @@ -208,13 +208,13 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom
208 new PaginatedRemover<TenantId, Customer>() { 208 new PaginatedRemover<TenantId, Customer>() {
209 209
210 @Override 210 @Override
211 - protected List<Customer> findEntities(TenantId id, TextPageLink pageLink) { 211 + protected List<Customer> findEntities(TenantId tenantId, TenantId id, TextPageLink pageLink) {
212 return customerDao.findCustomersByTenantId(id.getId(), pageLink); 212 return customerDao.findCustomersByTenantId(id.getId(), pageLink);
213 } 213 }
214 214
215 @Override 215 @Override
216 - protected void removeEntity(Customer entity) {  
217 - deleteCustomer(new CustomerId(entity.getUuidId())); 216 + protected void removeEntity(TenantId tenantId, Customer entity) {
  217 + deleteCustomer(tenantId, new CustomerId(entity.getUuidId()));
218 } 218 }
219 }; 219 };
220 } 220 }
@@ -23,6 +23,7 @@ import org.springframework.stereotype.Component; @@ -23,6 +23,7 @@ import org.springframework.stereotype.Component;
23 import org.thingsboard.server.common.data.DashboardInfo; 23 import org.thingsboard.server.common.data.DashboardInfo;
24 import org.thingsboard.server.common.data.EntityType; 24 import org.thingsboard.server.common.data.EntityType;
25 import org.thingsboard.server.common.data.id.CustomerId; 25 import org.thingsboard.server.common.data.id.CustomerId;
  26 +import org.thingsboard.server.common.data.id.TenantId;
26 import org.thingsboard.server.common.data.page.TextPageLink; 27 import org.thingsboard.server.common.data.page.TextPageLink;
27 import org.thingsboard.server.common.data.page.TimePageLink; 28 import org.thingsboard.server.common.data.page.TimePageLink;
28 import org.thingsboard.server.common.data.relation.EntityRelation; 29 import org.thingsboard.server.common.data.relation.EntityRelation;
@@ -64,7 +65,7 @@ public class CassandraDashboardInfoDao extends CassandraAbstractSearchTextDao<Da @@ -64,7 +65,7 @@ public class CassandraDashboardInfoDao extends CassandraAbstractSearchTextDao<Da
64 @Override 65 @Override
65 public List<DashboardInfo> findDashboardsByTenantId(UUID tenantId, TextPageLink pageLink) { 66 public List<DashboardInfo> findDashboardsByTenantId(UUID tenantId, TextPageLink pageLink) {
66 log.debug("Try to find dashboards by tenantId [{}] and pageLink [{}]", tenantId, pageLink); 67 log.debug("Try to find dashboards by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
67 - List<DashboardInfoEntity> dashboardEntities = findPageWithTextSearch(DASHBOARD_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 68 + List<DashboardInfoEntity> dashboardEntities = findPageWithTextSearch(new TenantId(tenantId), DASHBOARD_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
68 Collections.singletonList(eq(DASHBOARD_TENANT_ID_PROPERTY, tenantId)), 69 Collections.singletonList(eq(DASHBOARD_TENANT_ID_PROPERTY, tenantId)),
69 pageLink); 70 pageLink);
70 71
@@ -76,12 +77,12 @@ public class CassandraDashboardInfoDao extends CassandraAbstractSearchTextDao<Da @@ -76,12 +77,12 @@ public class CassandraDashboardInfoDao extends CassandraAbstractSearchTextDao<Da
76 public ListenableFuture<List<DashboardInfo>> findDashboardsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TimePageLink pageLink) { 77 public ListenableFuture<List<DashboardInfo>> findDashboardsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TimePageLink pageLink) {
77 log.debug("Try to find dashboards by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink); 78 log.debug("Try to find dashboards by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink);
78 79
79 - ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new CustomerId(customerId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD, EntityType.DASHBOARD, pageLink); 80 + ListenableFuture<List<EntityRelation>> relations = relationDao.findRelations(new TenantId(tenantId), new CustomerId(customerId), EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD, EntityType.DASHBOARD, pageLink);
80 81
81 return Futures.transformAsync(relations, input -> { 82 return Futures.transformAsync(relations, input -> {
82 List<ListenableFuture<DashboardInfo>> dashboardFutures = new ArrayList<>(input.size()); 83 List<ListenableFuture<DashboardInfo>> dashboardFutures = new ArrayList<>(input.size());
83 for (EntityRelation relation : input) { 84 for (EntityRelation relation : input) {
84 - dashboardFutures.add(findByIdAsync(relation.getTo().getId())); 85 + dashboardFutures.add(findByIdAsync(new TenantId(tenantId), relation.getTo().getId()));
85 } 86 }
86 return Futures.successfulAsList(dashboardFutures); 87 return Futures.successfulAsList(dashboardFutures);
87 }); 88 });
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.dashboard; 16 package org.thingsboard.server.dao.dashboard;
17 17
18 import org.thingsboard.server.common.data.Dashboard; 18 import org.thingsboard.server.common.data.Dashboard;
  19 +import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.dao.Dao; 20 import org.thingsboard.server.dao.Dao;
20 21
21 /** 22 /**
@@ -29,6 +30,6 @@ public interface DashboardDao extends Dao<Dashboard> { @@ -29,6 +30,6 @@ public interface DashboardDao extends Dao<Dashboard> {
29 * @param dashboard the dashboard object 30 * @param dashboard the dashboard object
30 * @return saved dashboard object 31 * @return saved dashboard object
31 */ 32 */
32 - Dashboard save(Dashboard dashboard); 33 + Dashboard save(TenantId tenantId, Dashboard dashboard);
33 34
34 } 35 }
@@ -28,21 +28,21 @@ import org.thingsboard.server.common.data.page.TimePageLink; @@ -28,21 +28,21 @@ import org.thingsboard.server.common.data.page.TimePageLink;
28 28
29 public interface DashboardService { 29 public interface DashboardService {
30 30
31 - Dashboard findDashboardById(DashboardId dashboardId); 31 + Dashboard findDashboardById(TenantId tenantId, DashboardId dashboardId);
32 32
33 - ListenableFuture<Dashboard> findDashboardByIdAsync(DashboardId dashboardId); 33 + ListenableFuture<Dashboard> findDashboardByIdAsync(TenantId tenantId, DashboardId dashboardId);
34 34
35 - DashboardInfo findDashboardInfoById(DashboardId dashboardId); 35 + DashboardInfo findDashboardInfoById(TenantId tenantId, DashboardId dashboardId);
36 36
37 - ListenableFuture<DashboardInfo> findDashboardInfoByIdAsync(DashboardId dashboardId); 37 + ListenableFuture<DashboardInfo> findDashboardInfoByIdAsync(TenantId tenantId, DashboardId dashboardId);
38 38
39 Dashboard saveDashboard(Dashboard dashboard); 39 Dashboard saveDashboard(Dashboard dashboard);
40 40
41 - Dashboard assignDashboardToCustomer(DashboardId dashboardId, CustomerId customerId); 41 + Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId);
42 42
43 - Dashboard unassignDashboardFromCustomer(DashboardId dashboardId, CustomerId customerId); 43 + Dashboard unassignDashboardFromCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId);
44 44
45 - void deleteDashboard(DashboardId dashboardId); 45 + void deleteDashboard(TenantId tenantId, DashboardId dashboardId);
46 46
47 TextPageData<DashboardInfo> findDashboardsByTenantId(TenantId tenantId, TextPageLink pageLink); 47 TextPageData<DashboardInfo> findDashboardsByTenantId(TenantId tenantId, TextPageLink pageLink);
48 48
@@ -50,8 +50,8 @@ public interface DashboardService { @@ -50,8 +50,8 @@ public interface DashboardService {
50 50
51 ListenableFuture<TimePageData<DashboardInfo>> findDashboardsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TimePageLink pageLink); 51 ListenableFuture<TimePageData<DashboardInfo>> findDashboardsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TimePageLink pageLink);
52 52
53 - void unassignCustomerDashboards(CustomerId customerId); 53 + void unassignCustomerDashboards(TenantId tenantId, CustomerId customerId);
54 54
55 - void updateCustomerDashboards(CustomerId customerId); 55 + void updateCustomerDashboards(TenantId tenantId, CustomerId customerId);
56 56
57 } 57 }
@@ -69,44 +69,44 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -69,44 +69,44 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
69 private CustomerDao customerDao; 69 private CustomerDao customerDao;
70 70
71 @Override 71 @Override
72 - public Dashboard findDashboardById(DashboardId dashboardId) { 72 + public Dashboard findDashboardById(TenantId tenantId, DashboardId dashboardId) {
73 log.trace("Executing findDashboardById [{}]", dashboardId); 73 log.trace("Executing findDashboardById [{}]", dashboardId);
74 Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); 74 Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId);
75 - return dashboardDao.findById(dashboardId.getId()); 75 + return dashboardDao.findById(tenantId, dashboardId.getId());
76 } 76 }
77 77
78 @Override 78 @Override
79 - public ListenableFuture<Dashboard> findDashboardByIdAsync(DashboardId dashboardId) { 79 + public ListenableFuture<Dashboard> findDashboardByIdAsync(TenantId tenantId, DashboardId dashboardId) {
80 log.trace("Executing findDashboardByIdAsync [{}]", dashboardId); 80 log.trace("Executing findDashboardByIdAsync [{}]", dashboardId);
81 validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); 81 validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId);
82 - return dashboardDao.findByIdAsync(dashboardId.getId()); 82 + return dashboardDao.findByIdAsync(tenantId, dashboardId.getId());
83 } 83 }
84 84
85 @Override 85 @Override
86 - public DashboardInfo findDashboardInfoById(DashboardId dashboardId) { 86 + public DashboardInfo findDashboardInfoById(TenantId tenantId, DashboardId dashboardId) {
87 log.trace("Executing findDashboardInfoById [{}]", dashboardId); 87 log.trace("Executing findDashboardInfoById [{}]", dashboardId);
88 Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); 88 Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId);
89 - return dashboardInfoDao.findById(dashboardId.getId()); 89 + return dashboardInfoDao.findById(tenantId, dashboardId.getId());
90 } 90 }
91 91
92 @Override 92 @Override
93 - public ListenableFuture<DashboardInfo> findDashboardInfoByIdAsync(DashboardId dashboardId) { 93 + public ListenableFuture<DashboardInfo> findDashboardInfoByIdAsync(TenantId tenantId, DashboardId dashboardId) {
94 log.trace("Executing findDashboardInfoByIdAsync [{}]", dashboardId); 94 log.trace("Executing findDashboardInfoByIdAsync [{}]", dashboardId);
95 validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); 95 validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId);
96 - return dashboardInfoDao.findByIdAsync(dashboardId.getId()); 96 + return dashboardInfoDao.findByIdAsync(tenantId, dashboardId.getId());
97 } 97 }
98 98
99 @Override 99 @Override
100 public Dashboard saveDashboard(Dashboard dashboard) { 100 public Dashboard saveDashboard(Dashboard dashboard) {
101 log.trace("Executing saveDashboard [{}]", dashboard); 101 log.trace("Executing saveDashboard [{}]", dashboard);
102 - dashboardValidator.validate(dashboard);  
103 - return dashboardDao.save(dashboard); 102 + dashboardValidator.validate(dashboard, DashboardInfo::getTenantId);
  103 + return dashboardDao.save(dashboard.getTenantId(), dashboard);
104 } 104 }
105 105
106 @Override 106 @Override
107 - public Dashboard assignDashboardToCustomer(DashboardId dashboardId, CustomerId customerId) {  
108 - Dashboard dashboard = findDashboardById(dashboardId);  
109 - Customer customer = customerDao.findById(customerId.getId()); 107 + public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId) {
  108 + Dashboard dashboard = findDashboardById(tenantId, dashboardId);
  109 + Customer customer = customerDao.findById(tenantId, customerId.getId());
110 if (customer == null) { 110 if (customer == null) {
111 throw new DataValidationException("Can't assign dashboard to non-existent customer!"); 111 throw new DataValidationException("Can't assign dashboard to non-existent customer!");
112 } 112 }
@@ -115,7 +115,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -115,7 +115,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
115 } 115 }
116 if (dashboard.addAssignedCustomer(customer)) { 116 if (dashboard.addAssignedCustomer(customer)) {
117 try { 117 try {
118 - createRelation(new EntityRelation(customerId, dashboardId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD)); 118 + createRelation(tenantId, new EntityRelation(customerId, dashboardId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD));
119 } catch (ExecutionException | InterruptedException e) { 119 } catch (ExecutionException | InterruptedException e) {
120 log.warn("[{}] Failed to create dashboard relation. Customer Id: [{}]", dashboardId, customerId); 120 log.warn("[{}] Failed to create dashboard relation. Customer Id: [{}]", dashboardId, customerId);
121 throw new RuntimeException(e); 121 throw new RuntimeException(e);
@@ -127,15 +127,15 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -127,15 +127,15 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
127 } 127 }
128 128
129 @Override 129 @Override
130 - public Dashboard unassignDashboardFromCustomer(DashboardId dashboardId, CustomerId customerId) {  
131 - Dashboard dashboard = findDashboardById(dashboardId);  
132 - Customer customer = customerDao.findById(customerId.getId()); 130 + public Dashboard unassignDashboardFromCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId) {
  131 + Dashboard dashboard = findDashboardById(tenantId, dashboardId);
  132 + Customer customer = customerDao.findById(tenantId, customerId.getId());
133 if (customer == null) { 133 if (customer == null) {
134 throw new DataValidationException("Can't unassign dashboard from non-existent customer!"); 134 throw new DataValidationException("Can't unassign dashboard from non-existent customer!");
135 } 135 }
136 if (dashboard.removeAssignedCustomer(customer)) { 136 if (dashboard.removeAssignedCustomer(customer)) {
137 try { 137 try {
138 - deleteRelation(new EntityRelation(customerId, dashboardId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD)); 138 + deleteRelation(tenantId, new EntityRelation(customerId, dashboardId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD));
139 } catch (ExecutionException | InterruptedException e) { 139 } catch (ExecutionException | InterruptedException e) {
140 log.warn("[{}] Failed to delete dashboard relation. Customer Id: [{}]", dashboardId, customerId); 140 log.warn("[{}] Failed to delete dashboard relation. Customer Id: [{}]", dashboardId, customerId);
141 throw new RuntimeException(e); 141 throw new RuntimeException(e);
@@ -146,8 +146,8 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -146,8 +146,8 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
146 } 146 }
147 } 147 }
148 148
149 - private Dashboard updateAssignedCustomer(DashboardId dashboardId, Customer customer) {  
150 - Dashboard dashboard = findDashboardById(dashboardId); 149 + private Dashboard updateAssignedCustomer(TenantId tenantId, DashboardId dashboardId, Customer customer) {
  150 + Dashboard dashboard = findDashboardById(tenantId, dashboardId);
151 if (dashboard.updateAssignedCustomer(customer)) { 151 if (dashboard.updateAssignedCustomer(customer)) {
152 return saveDashboard(dashboard); 152 return saveDashboard(dashboard);
153 } else { 153 } else {
@@ -155,22 +155,22 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -155,22 +155,22 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
155 } 155 }
156 } 156 }
157 157
158 - private void deleteRelation(EntityRelation dashboardRelation) throws ExecutionException, InterruptedException { 158 + private void deleteRelation(TenantId tenantId, EntityRelation dashboardRelation) throws ExecutionException, InterruptedException {
159 log.debug("Deleting Dashboard relation: {}", dashboardRelation); 159 log.debug("Deleting Dashboard relation: {}", dashboardRelation);
160 - relationService.deleteRelationAsync(dashboardRelation).get(); 160 + relationService.deleteRelationAsync(tenantId, dashboardRelation).get();
161 } 161 }
162 162
163 - private void createRelation(EntityRelation dashboardRelation) throws ExecutionException, InterruptedException { 163 + private void createRelation(TenantId tenantId, EntityRelation dashboardRelation) throws ExecutionException, InterruptedException {
164 log.debug("Creating Dashboard relation: {}", dashboardRelation); 164 log.debug("Creating Dashboard relation: {}", dashboardRelation);
165 - relationService.saveRelationAsync(dashboardRelation).get(); 165 + relationService.saveRelationAsync(tenantId, dashboardRelation).get();
166 } 166 }
167 167
168 @Override 168 @Override
169 - public void deleteDashboard(DashboardId dashboardId) { 169 + public void deleteDashboard(TenantId tenantId, DashboardId dashboardId) {
170 log.trace("Executing deleteDashboard [{}]", dashboardId); 170 log.trace("Executing deleteDashboard [{}]", dashboardId);
171 Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); 171 Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId);
172 - deleteEntityRelations(dashboardId);  
173 - dashboardDao.removeById(dashboardId.getId()); 172 + deleteEntityRelations(tenantId, dashboardId);
  173 + dashboardDao.removeById(tenantId, dashboardId.getId());
174 } 174 }
175 175
176 @Override 176 @Override
@@ -186,7 +186,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -186,7 +186,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
186 public void deleteDashboardsByTenantId(TenantId tenantId) { 186 public void deleteDashboardsByTenantId(TenantId tenantId) {
187 log.trace("Executing deleteDashboardsByTenantId, tenantId [{}]", tenantId); 187 log.trace("Executing deleteDashboardsByTenantId, tenantId [{}]", tenantId);
188 Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 188 Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
189 - tenantDashboardsRemover.removeEntities(tenantId); 189 + tenantDashboardsRemover.removeEntities(tenantId, tenantId);
190 } 190 }
191 191
192 @Override 192 @Override
@@ -207,10 +207,10 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -207,10 +207,10 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
207 } 207 }
208 208
209 @Override 209 @Override
210 - public void unassignCustomerDashboards(CustomerId customerId) { 210 + public void unassignCustomerDashboards(TenantId tenantId, CustomerId customerId) {
211 log.trace("Executing unassignCustomerDashboards, customerId [{}]", customerId); 211 log.trace("Executing unassignCustomerDashboards, customerId [{}]", customerId);
212 Validator.validateId(customerId, "Incorrect customerId " + customerId); 212 Validator.validateId(customerId, "Incorrect customerId " + customerId);
213 - Customer customer = customerDao.findById(customerId.getId()); 213 + Customer customer = customerDao.findById(tenantId, customerId.getId());
214 if (customer == null) { 214 if (customer == null) {
215 throw new DataValidationException("Can't unassign dashboards from non-existent customer!"); 215 throw new DataValidationException("Can't unassign dashboards from non-existent customer!");
216 } 216 }
@@ -218,10 +218,10 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -218,10 +218,10 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
218 } 218 }
219 219
220 @Override 220 @Override
221 - public void updateCustomerDashboards(CustomerId customerId) { 221 + public void updateCustomerDashboards(TenantId tenantId, CustomerId customerId) {
222 log.trace("Executing updateCustomerDashboards, customerId [{}]", customerId); 222 log.trace("Executing updateCustomerDashboards, customerId [{}]", customerId);
223 Validator.validateId(customerId, "Incorrect customerId " + customerId); 223 Validator.validateId(customerId, "Incorrect customerId " + customerId);
224 - Customer customer = customerDao.findById(customerId.getId()); 224 + Customer customer = customerDao.findById(tenantId, customerId.getId());
225 if (customer == null) { 225 if (customer == null) {
226 throw new DataValidationException("Can't update dashboards for non-existent customer!"); 226 throw new DataValidationException("Can't update dashboards for non-existent customer!");
227 } 227 }
@@ -231,14 +231,14 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -231,14 +231,14 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
231 private DataValidator<Dashboard> dashboardValidator = 231 private DataValidator<Dashboard> dashboardValidator =
232 new DataValidator<Dashboard>() { 232 new DataValidator<Dashboard>() {
233 @Override 233 @Override
234 - protected void validateDataImpl(Dashboard dashboard) { 234 + protected void validateDataImpl(TenantId tenantId, Dashboard dashboard) {
235 if (StringUtils.isEmpty(dashboard.getTitle())) { 235 if (StringUtils.isEmpty(dashboard.getTitle())) {
236 throw new DataValidationException("Dashboard title should be specified!"); 236 throw new DataValidationException("Dashboard title should be specified!");
237 } 237 }
238 if (dashboard.getTenantId() == null) { 238 if (dashboard.getTenantId() == null) {
239 throw new DataValidationException("Dashboard should be assigned to tenant!"); 239 throw new DataValidationException("Dashboard should be assigned to tenant!");
240 } else { 240 } else {
241 - Tenant tenant = tenantDao.findById(dashboard.getTenantId().getId()); 241 + Tenant tenant = tenantDao.findById(tenantId, dashboard.getTenantId().getId());
242 if (tenant == null) { 242 if (tenant == null) {
243 throw new DataValidationException("Dashboard is referencing to non-existent tenant!"); 243 throw new DataValidationException("Dashboard is referencing to non-existent tenant!");
244 } 244 }
@@ -250,13 +250,13 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -250,13 +250,13 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
250 new PaginatedRemover<TenantId, DashboardInfo>() { 250 new PaginatedRemover<TenantId, DashboardInfo>() {
251 251
252 @Override 252 @Override
253 - protected List<DashboardInfo> findEntities(TenantId id, TextPageLink pageLink) { 253 + protected List<DashboardInfo> findEntities(TenantId tenantId, TenantId id, TextPageLink pageLink) {
254 return dashboardInfoDao.findDashboardsByTenantId(id.getId(), pageLink); 254 return dashboardInfoDao.findDashboardsByTenantId(id.getId(), pageLink);
255 } 255 }
256 256
257 @Override 257 @Override
258 - protected void removeEntity(DashboardInfo entity) {  
259 - deleteDashboard(new DashboardId(entity.getUuidId())); 258 + protected void removeEntity(TenantId tenantId, DashboardInfo entity) {
  259 + deleteDashboard(tenantId, new DashboardId(entity.getUuidId()));
260 } 260 }
261 }; 261 };
262 262
@@ -280,7 +280,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -280,7 +280,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
280 280
281 @Override 281 @Override
282 protected void removeEntity(DashboardInfo entity) { 282 protected void removeEntity(DashboardInfo entity) {
283 - unassignDashboardFromCustomer(new DashboardId(entity.getUuidId()), this.customer.getId()); 283 + unassignDashboardFromCustomer(customer.getTenantId(), new DashboardId(entity.getUuidId()), this.customer.getId());
284 } 284 }
285 285
286 } 286 }
@@ -305,7 +305,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @@ -305,7 +305,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
305 305
306 @Override 306 @Override
307 protected void removeEntity(DashboardInfo entity) { 307 protected void removeEntity(DashboardInfo entity) {
308 - updateAssignedCustomer(new DashboardId(entity.getUuidId()), this.customer); 308 + updateAssignedCustomer(customer.getTenantId(), new DashboardId(entity.getUuidId()), this.customer);
309 } 309 }
310 310
311 } 311 }
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device;
18 import com.datastax.driver.core.querybuilder.Select.Where; 18 import com.datastax.driver.core.querybuilder.Select.Where;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.stereotype.Component; 20 import org.springframework.stereotype.Component;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.security.DeviceCredentials; 22 import org.thingsboard.server.common.data.security.DeviceCredentials;
22 import org.thingsboard.server.dao.DaoUtil; 23 import org.thingsboard.server.dao.DaoUtil;
23 import org.thingsboard.server.dao.model.ModelConstants; 24 import org.thingsboard.server.dao.model.ModelConstants;
@@ -46,23 +47,23 @@ public class CassandraDeviceCredentialsDao extends CassandraAbstractModelDao<Dev @@ -46,23 +47,23 @@ public class CassandraDeviceCredentialsDao extends CassandraAbstractModelDao<Dev
46 } 47 }
47 48
48 @Override 49 @Override
49 - public DeviceCredentials findByDeviceId(UUID deviceId) { 50 + public DeviceCredentials findByDeviceId(TenantId tenantId, UUID deviceId) {
50 log.debug("Try to find device credentials by deviceId [{}] ", deviceId); 51 log.debug("Try to find device credentials by deviceId [{}] ", deviceId);
51 Where query = select().from(ModelConstants.DEVICE_CREDENTIALS_BY_DEVICE_COLUMN_FAMILY_NAME) 52 Where query = select().from(ModelConstants.DEVICE_CREDENTIALS_BY_DEVICE_COLUMN_FAMILY_NAME)
52 .where(eq(ModelConstants.DEVICE_CREDENTIALS_DEVICE_ID_PROPERTY, deviceId)); 53 .where(eq(ModelConstants.DEVICE_CREDENTIALS_DEVICE_ID_PROPERTY, deviceId));
53 log.trace("Execute query {}", query); 54 log.trace("Execute query {}", query);
54 - DeviceCredentialsEntity deviceCredentialsEntity = findOneByStatement(query); 55 + DeviceCredentialsEntity deviceCredentialsEntity = findOneByStatement(tenantId, query);
55 log.trace("Found device credentials [{}] by deviceId [{}]", deviceCredentialsEntity, deviceId); 56 log.trace("Found device credentials [{}] by deviceId [{}]", deviceCredentialsEntity, deviceId);
56 return DaoUtil.getData(deviceCredentialsEntity); 57 return DaoUtil.getData(deviceCredentialsEntity);
57 } 58 }
58 59
59 @Override 60 @Override
60 - public DeviceCredentials findByCredentialsId(String credentialsId) { 61 + public DeviceCredentials findByCredentialsId(TenantId tenantId, String credentialsId) {
61 log.debug("Try to find device credentials by credentialsId [{}] ", credentialsId); 62 log.debug("Try to find device credentials by credentialsId [{}] ", credentialsId);
62 Where query = select().from(ModelConstants.DEVICE_CREDENTIALS_BY_CREDENTIALS_ID_COLUMN_FAMILY_NAME) 63 Where query = select().from(ModelConstants.DEVICE_CREDENTIALS_BY_CREDENTIALS_ID_COLUMN_FAMILY_NAME)
63 .where(eq(ModelConstants.DEVICE_CREDENTIALS_CREDENTIALS_ID_PROPERTY, credentialsId)); 64 .where(eq(ModelConstants.DEVICE_CREDENTIALS_CREDENTIALS_ID_PROPERTY, credentialsId));
64 log.trace("Execute query {}", query); 65 log.trace("Execute query {}", query);
65 - DeviceCredentialsEntity deviceCredentialsEntity = findOneByStatement(query); 66 + DeviceCredentialsEntity deviceCredentialsEntity = findOneByStatement(tenantId, query);
66 log.trace("Found device credentials [{}] by credentialsId [{}]", deviceCredentialsEntity, credentialsId); 67 log.trace("Found device credentials [{}] by credentialsId [{}]", deviceCredentialsEntity, credentialsId);
67 return DaoUtil.getData(deviceCredentialsEntity); 68 return DaoUtil.getData(deviceCredentialsEntity);
68 } 69 }
@@ -28,6 +28,7 @@ import org.springframework.stereotype.Component; @@ -28,6 +28,7 @@ import org.springframework.stereotype.Component;
28 import org.thingsboard.server.common.data.Device; 28 import org.thingsboard.server.common.data.Device;
29 import org.thingsboard.server.common.data.EntitySubtype; 29 import org.thingsboard.server.common.data.EntitySubtype;
30 import org.thingsboard.server.common.data.EntityType; 30 import org.thingsboard.server.common.data.EntityType;
  31 +import org.thingsboard.server.common.data.id.TenantId;
31 import org.thingsboard.server.common.data.page.TextPageLink; 32 import org.thingsboard.server.common.data.page.TextPageLink;
32 import org.thingsboard.server.dao.DaoUtil; 33 import org.thingsboard.server.dao.DaoUtil;
33 import org.thingsboard.server.dao.model.EntitySubtypeEntity; 34 import org.thingsboard.server.dao.model.EntitySubtypeEntity;
@@ -77,19 +78,19 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt @@ -77,19 +78,19 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
77 } 78 }
78 79
79 @Override 80 @Override
80 - public Device save(Device domain) {  
81 - Device savedDevice = super.save(domain); 81 + public Device save(TenantId tenantId, Device domain) {
  82 + Device savedDevice = super.save(tenantId, domain);
82 EntitySubtype entitySubtype = new EntitySubtype(savedDevice.getTenantId(), EntityType.DEVICE, savedDevice.getType()); 83 EntitySubtype entitySubtype = new EntitySubtype(savedDevice.getTenantId(), EntityType.DEVICE, savedDevice.getType());
83 EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype); 84 EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype);
84 Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity); 85 Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity);
85 - executeWrite(saveStatement); 86 + executeWrite(tenantId, saveStatement);
86 return savedDevice; 87 return savedDevice;
87 } 88 }
88 89
89 @Override 90 @Override
90 public List<Device> findDevicesByTenantId(UUID tenantId, TextPageLink pageLink) { 91 public List<Device> findDevicesByTenantId(UUID tenantId, TextPageLink pageLink) {
91 log.debug("Try to find devices by tenantId [{}] and pageLink [{}]", tenantId, pageLink); 92 log.debug("Try to find devices by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
92 - List<DeviceEntity> deviceEntities = findPageWithTextSearch(DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 93 + List<DeviceEntity> deviceEntities = findPageWithTextSearch(new TenantId(tenantId), DEVICE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
93 Collections.singletonList(eq(DEVICE_TENANT_ID_PROPERTY, tenantId)), pageLink); 94 Collections.singletonList(eq(DEVICE_TENANT_ID_PROPERTY, tenantId)), pageLink);
94 95
95 log.trace("Found devices [{}] by tenantId [{}] and pageLink [{}]", deviceEntities, tenantId, pageLink); 96 log.trace("Found devices [{}] by tenantId [{}] and pageLink [{}]", deviceEntities, tenantId, pageLink);
@@ -99,7 +100,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt @@ -99,7 +100,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
99 @Override 100 @Override
100 public List<Device> findDevicesByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) { 101 public List<Device> findDevicesByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) {
101 log.debug("Try to find devices by tenantId [{}], type [{}] and pageLink [{}]", tenantId, type, pageLink); 102 log.debug("Try to find devices by tenantId [{}], type [{}] and pageLink [{}]", tenantId, type, pageLink);
102 - List<DeviceEntity> deviceEntities = findPageWithTextSearch(DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 103 + List<DeviceEntity> deviceEntities = findPageWithTextSearch(new TenantId(tenantId), DEVICE_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
103 Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type), 104 Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type),
104 eq(DEVICE_TENANT_ID_PROPERTY, tenantId)), pageLink); 105 eq(DEVICE_TENANT_ID_PROPERTY, tenantId)), pageLink);
105 log.trace("Found devices [{}] by tenantId [{}], type [{}] and pageLink [{}]", deviceEntities, tenantId, type, pageLink); 106 log.trace("Found devices [{}] by tenantId [{}], type [{}] and pageLink [{}]", deviceEntities, tenantId, type, pageLink);
@@ -113,13 +114,13 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt @@ -113,13 +114,13 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
113 Select.Where query = select.where(); 114 Select.Where query = select.where();
114 query.and(eq(DEVICE_TENANT_ID_PROPERTY, tenantId)); 115 query.and(eq(DEVICE_TENANT_ID_PROPERTY, tenantId));
115 query.and(in(ID_PROPERTY, deviceIds)); 116 query.and(in(ID_PROPERTY, deviceIds));
116 - return findListByStatementAsync(query); 117 + return findListByStatementAsync(new TenantId(tenantId), query);
117 } 118 }
118 119
119 @Override 120 @Override
120 public List<Device> findDevicesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) { 121 public List<Device> findDevicesByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) {
121 log.debug("Try to find devices by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink); 122 log.debug("Try to find devices by tenantId [{}], customerId[{}] and pageLink [{}]", tenantId, customerId, pageLink);
122 - List<DeviceEntity> deviceEntities = findPageWithTextSearch(DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 123 + List<DeviceEntity> deviceEntities = findPageWithTextSearch(new TenantId(tenantId), DEVICE_BY_CUSTOMER_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
123 Arrays.asList(eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId), 124 Arrays.asList(eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId),
124 eq(DEVICE_TENANT_ID_PROPERTY, tenantId)), 125 eq(DEVICE_TENANT_ID_PROPERTY, tenantId)),
125 pageLink); 126 pageLink);
@@ -131,7 +132,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt @@ -131,7 +132,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
131 @Override 132 @Override
132 public List<Device> findDevicesByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) { 133 public List<Device> findDevicesByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) {
133 log.debug("Try to find devices by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink); 134 log.debug("Try to find devices by tenantId [{}], customerId [{}], type [{}] and pageLink [{}]", tenantId, customerId, type, pageLink);
134 - List<DeviceEntity> deviceEntities = findPageWithTextSearch(DEVICE_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 135 + List<DeviceEntity> deviceEntities = findPageWithTextSearch(new TenantId(tenantId), DEVICE_BY_CUSTOMER_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
135 Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type), 136 Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type),
136 eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId), 137 eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId),
137 eq(DEVICE_TENANT_ID_PROPERTY, tenantId)), 138 eq(DEVICE_TENANT_ID_PROPERTY, tenantId)),
@@ -149,7 +150,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt @@ -149,7 +150,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
149 query.and(eq(DEVICE_TENANT_ID_PROPERTY, tenantId)); 150 query.and(eq(DEVICE_TENANT_ID_PROPERTY, tenantId));
150 query.and(eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId)); 151 query.and(eq(DEVICE_CUSTOMER_ID_PROPERTY, customerId));
151 query.and(in(ID_PROPERTY, deviceIds)); 152 query.and(in(ID_PROPERTY, deviceIds));
152 - return findListByStatementAsync(query); 153 + return findListByStatementAsync(new TenantId(tenantId), query);
153 } 154 }
154 155
155 @Override 156 @Override
@@ -158,7 +159,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt @@ -158,7 +159,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
158 Select.Where query = select.where(); 159 Select.Where query = select.where();
159 query.and(eq(DEVICE_TENANT_ID_PROPERTY, tenantId)); 160 query.and(eq(DEVICE_TENANT_ID_PROPERTY, tenantId));
160 query.and(eq(DEVICE_NAME_PROPERTY, deviceName)); 161 query.and(eq(DEVICE_NAME_PROPERTY, deviceName));
161 - return Optional.ofNullable(DaoUtil.getData(findOneByStatement(query))); 162 + return Optional.ofNullable(DaoUtil.getData(findOneByStatement(new TenantId(tenantId), query)));
162 } 163 }
163 164
164 @Override 165 @Override
@@ -168,7 +169,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt @@ -168,7 +169,7 @@ public class CassandraDeviceDao extends CassandraAbstractSearchTextDao<DeviceEnt
168 query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId)); 169 query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId));
169 query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.DEVICE)); 170 query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.DEVICE));
170 query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); 171 query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
171 - ResultSetFuture resultSetFuture = executeAsyncRead(query); 172 + ResultSetFuture resultSetFuture = executeAsyncRead(new TenantId(tenantId), query);
172 return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() { 173 return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() {
173 @Nullable 174 @Nullable
174 @Override 175 @Override
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.dao.device; 16 package org.thingsboard.server.dao.device;
17 17
  18 +import org.thingsboard.server.common.data.id.TenantId;
18 import org.thingsboard.server.common.data.security.DeviceCredentials; 19 import org.thingsboard.server.common.data.security.DeviceCredentials;
19 import org.thingsboard.server.dao.Dao; 20 import org.thingsboard.server.dao.Dao;
20 21
@@ -28,10 +29,11 @@ public interface DeviceCredentialsDao extends Dao<DeviceCredentials> { @@ -28,10 +29,11 @@ public interface DeviceCredentialsDao extends Dao<DeviceCredentials> {
28 /** 29 /**
29 * Save or update device credentials object 30 * Save or update device credentials object
30 * 31 *
  32 + * @param tenantId the device tenant id
31 * @param deviceCredentials the device credentials object 33 * @param deviceCredentials the device credentials object
32 * @return saved device credentials object 34 * @return saved device credentials object
33 */ 35 */
34 - DeviceCredentials save(DeviceCredentials deviceCredentials); 36 + DeviceCredentials save(TenantId tenantId, DeviceCredentials deviceCredentials);
35 37
36 /** 38 /**
37 * Find device credentials by device id. 39 * Find device credentials by device id.
@@ -39,7 +41,7 @@ public interface DeviceCredentialsDao extends Dao<DeviceCredentials> { @@ -39,7 +41,7 @@ public interface DeviceCredentialsDao extends Dao<DeviceCredentials> {
39 * @param deviceId the device id 41 * @param deviceId the device id
40 * @return the device credentials object 42 * @return the device credentials object
41 */ 43 */
42 - DeviceCredentials findByDeviceId(UUID deviceId); 44 + DeviceCredentials findByDeviceId(TenantId tenantId, UUID deviceId);
43 45
44 /** 46 /**
45 * Find device credentials by credentials id. 47 * Find device credentials by credentials id.
@@ -47,6 +49,6 @@ public interface DeviceCredentialsDao extends Dao<DeviceCredentials> { @@ -47,6 +49,6 @@ public interface DeviceCredentialsDao extends Dao<DeviceCredentials> {
47 * @param credentialsId the credentials id 49 * @param credentialsId the credentials id
48 * @return the device credentials object 50 * @return the device credentials object
49 */ 51 */
50 - DeviceCredentials findByCredentialsId(String credentialsId); 52 + DeviceCredentials findByCredentialsId(TenantId tenantId, String credentialsId);
51 53
52 } 54 }
@@ -16,17 +16,18 @@ @@ -16,17 +16,18 @@
16 package org.thingsboard.server.dao.device; 16 package org.thingsboard.server.dao.device;
17 17
18 import org.thingsboard.server.common.data.id.DeviceId; 18 import org.thingsboard.server.common.data.id.DeviceId;
  19 +import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.security.DeviceCredentials; 20 import org.thingsboard.server.common.data.security.DeviceCredentials;
20 21
21 public interface DeviceCredentialsService { 22 public interface DeviceCredentialsService {
22 23
23 - DeviceCredentials findDeviceCredentialsByDeviceId(DeviceId deviceId); 24 + DeviceCredentials findDeviceCredentialsByDeviceId(TenantId tenantId, DeviceId deviceId);
24 25
25 DeviceCredentials findDeviceCredentialsByCredentialsId(String credentialsId); 26 DeviceCredentials findDeviceCredentialsByCredentialsId(String credentialsId);
26 27
27 - DeviceCredentials updateDeviceCredentials(DeviceCredentials deviceCredentials); 28 + DeviceCredentials updateDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials);
28 29
29 - DeviceCredentials createDeviceCredentials(DeviceCredentials deviceCredentials); 30 + DeviceCredentials createDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials);
30 31
31 - void deleteDeviceCredentials(DeviceCredentials deviceCredentials); 32 + void deleteDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials);
32 } 33 }
@@ -24,6 +24,8 @@ import org.springframework.stereotype.Service; @@ -24,6 +24,8 @@ import org.springframework.stereotype.Service;
24 import org.springframework.util.StringUtils; 24 import org.springframework.util.StringUtils;
25 import org.thingsboard.server.common.data.Device; 25 import org.thingsboard.server.common.data.Device;
26 import org.thingsboard.server.common.data.id.DeviceId; 26 import org.thingsboard.server.common.data.id.DeviceId;
  27 +import org.thingsboard.server.common.data.id.EntityId;
  28 +import org.thingsboard.server.common.data.id.TenantId;
27 import org.thingsboard.server.common.data.security.DeviceCredentials; 29 import org.thingsboard.server.common.data.security.DeviceCredentials;
28 import org.thingsboard.server.common.data.security.DeviceCredentialsType; 30 import org.thingsboard.server.common.data.security.DeviceCredentialsType;
29 import org.thingsboard.server.common.msg.EncryptionUtil; 31 import org.thingsboard.server.common.msg.EncryptionUtil;
@@ -45,38 +47,38 @@ public class DeviceCredentialsServiceImpl implements DeviceCredentialsService { @@ -45,38 +47,38 @@ public class DeviceCredentialsServiceImpl implements DeviceCredentialsService {
45 private DeviceService deviceService; 47 private DeviceService deviceService;
46 48
47 @Override 49 @Override
48 - public DeviceCredentials findDeviceCredentialsByDeviceId(DeviceId deviceId) { 50 + public DeviceCredentials findDeviceCredentialsByDeviceId(TenantId tenantId, DeviceId deviceId) {
49 log.trace("Executing findDeviceCredentialsByDeviceId [{}]", deviceId); 51 log.trace("Executing findDeviceCredentialsByDeviceId [{}]", deviceId);
50 validateId(deviceId, "Incorrect deviceId " + deviceId); 52 validateId(deviceId, "Incorrect deviceId " + deviceId);
51 - return deviceCredentialsDao.findByDeviceId(deviceId.getId()); 53 + return deviceCredentialsDao.findByDeviceId(tenantId, deviceId.getId());
52 } 54 }
53 55
54 @Override 56 @Override
55 - @Cacheable(cacheNames = DEVICE_CREDENTIALS_CACHE, unless="#result == null") 57 + @Cacheable(cacheNames = DEVICE_CREDENTIALS_CACHE, unless = "#result == null")
56 public DeviceCredentials findDeviceCredentialsByCredentialsId(String credentialsId) { 58 public DeviceCredentials findDeviceCredentialsByCredentialsId(String credentialsId) {
57 log.trace("Executing findDeviceCredentialsByCredentialsId [{}]", credentialsId); 59 log.trace("Executing findDeviceCredentialsByCredentialsId [{}]", credentialsId);
58 validateString(credentialsId, "Incorrect credentialsId " + credentialsId); 60 validateString(credentialsId, "Incorrect credentialsId " + credentialsId);
59 - return deviceCredentialsDao.findByCredentialsId(credentialsId); 61 + return deviceCredentialsDao.findByCredentialsId(new TenantId(EntityId.NULL_UUID), credentialsId);
60 } 62 }
61 63
62 @Override 64 @Override
63 - @CacheEvict(cacheNames = DEVICE_CREDENTIALS_CACHE, keyGenerator="previousDeviceCredentialsId", beforeInvocation = true)  
64 - public DeviceCredentials updateDeviceCredentials(DeviceCredentials deviceCredentials) {  
65 - return saveOrUpdate(deviceCredentials); 65 + @CacheEvict(cacheNames = DEVICE_CREDENTIALS_CACHE, keyGenerator = "previousDeviceCredentialsId", beforeInvocation = true)
  66 + public DeviceCredentials updateDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials) {
  67 + return saveOrUpdate(tenantId, deviceCredentials);
66 } 68 }
67 69
68 @Override 70 @Override
69 - public DeviceCredentials createDeviceCredentials(DeviceCredentials deviceCredentials) {  
70 - return saveOrUpdate(deviceCredentials); 71 + public DeviceCredentials createDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials) {
  72 + return saveOrUpdate(tenantId, deviceCredentials);
71 } 73 }
72 74
73 - private DeviceCredentials saveOrUpdate(DeviceCredentials deviceCredentials) { 75 + private DeviceCredentials saveOrUpdate(TenantId tenantId, DeviceCredentials deviceCredentials) {
74 if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) { 76 if (deviceCredentials.getCredentialsType() == DeviceCredentialsType.X509_CERTIFICATE) {
75 formatCertData(deviceCredentials); 77 formatCertData(deviceCredentials);
76 } 78 }
77 log.trace("Executing updateDeviceCredentials [{}]", deviceCredentials); 79 log.trace("Executing updateDeviceCredentials [{}]", deviceCredentials);
78 - credentialsValidator.validate(deviceCredentials);  
79 - return deviceCredentialsDao.save(deviceCredentials); 80 + credentialsValidator.validate(deviceCredentials, id -> tenantId);
  81 + return deviceCredentialsDao.save(tenantId, deviceCredentials);
80 } 82 }
81 83
82 private void formatCertData(DeviceCredentials deviceCredentials) { 84 private void formatCertData(DeviceCredentials deviceCredentials) {
@@ -87,37 +89,37 @@ public class DeviceCredentialsServiceImpl implements DeviceCredentialsService { @@ -87,37 +89,37 @@ public class DeviceCredentialsServiceImpl implements DeviceCredentialsService {
87 } 89 }
88 90
89 @Override 91 @Override
90 - @CacheEvict(cacheNames = DEVICE_CREDENTIALS_CACHE, key="#deviceCredentials.credentialsId")  
91 - public void deleteDeviceCredentials(DeviceCredentials deviceCredentials) { 92 + @CacheEvict(cacheNames = DEVICE_CREDENTIALS_CACHE, key = "#deviceCredentials.credentialsId")
  93 + public void deleteDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials) {
92 log.trace("Executing deleteDeviceCredentials [{}]", deviceCredentials); 94 log.trace("Executing deleteDeviceCredentials [{}]", deviceCredentials);
93 - deviceCredentialsDao.removeById(deviceCredentials.getUuidId()); 95 + deviceCredentialsDao.removeById(tenantId, deviceCredentials.getUuidId());
94 } 96 }
95 97
96 private DataValidator<DeviceCredentials> credentialsValidator = 98 private DataValidator<DeviceCredentials> credentialsValidator =
97 new DataValidator<DeviceCredentials>() { 99 new DataValidator<DeviceCredentials>() {
98 100
99 @Override 101 @Override
100 - protected void validateCreate(DeviceCredentials deviceCredentials) {  
101 - DeviceCredentials existingCredentialsEntity = deviceCredentialsDao.findByCredentialsId(deviceCredentials.getCredentialsId()); 102 + protected void validateCreate(TenantId tenantId, DeviceCredentials deviceCredentials) {
  103 + DeviceCredentials existingCredentialsEntity = deviceCredentialsDao.findByCredentialsId(tenantId, deviceCredentials.getCredentialsId());
102 if (existingCredentialsEntity != null) { 104 if (existingCredentialsEntity != null) {
103 throw new DataValidationException("Create of existent device credentials!"); 105 throw new DataValidationException("Create of existent device credentials!");
104 } 106 }
105 } 107 }
106 108
107 @Override 109 @Override
108 - protected void validateUpdate(DeviceCredentials deviceCredentials) {  
109 - DeviceCredentials existingCredentials = deviceCredentialsDao.findById(deviceCredentials.getUuidId()); 110 + protected void validateUpdate(TenantId tenantId, DeviceCredentials deviceCredentials) {
  111 + DeviceCredentials existingCredentials = deviceCredentialsDao.findById(tenantId, deviceCredentials.getUuidId());
110 if (existingCredentials == null) { 112 if (existingCredentials == null) {
111 throw new DataValidationException("Unable to update non-existent device credentials!"); 113 throw new DataValidationException("Unable to update non-existent device credentials!");
112 } 114 }
113 - DeviceCredentials sameCredentialsId = deviceCredentialsDao.findByCredentialsId(deviceCredentials.getCredentialsId()); 115 + DeviceCredentials sameCredentialsId = deviceCredentialsDao.findByCredentialsId(tenantId, deviceCredentials.getCredentialsId());
114 if (sameCredentialsId != null && !sameCredentialsId.getUuidId().equals(deviceCredentials.getUuidId())) { 116 if (sameCredentialsId != null && !sameCredentialsId.getUuidId().equals(deviceCredentials.getUuidId())) {
115 throw new DataValidationException("Specified credentials are already registered!"); 117 throw new DataValidationException("Specified credentials are already registered!");
116 } 118 }
117 } 119 }
118 120
119 @Override 121 @Override
120 - protected void validateDataImpl(DeviceCredentials deviceCredentials) { 122 + protected void validateDataImpl(TenantId tenantId, DeviceCredentials deviceCredentials) {
121 if (deviceCredentials.getDeviceId() == null) { 123 if (deviceCredentials.getDeviceId() == null) {
122 throw new DataValidationException("Device credentials should be assigned to device!"); 124 throw new DataValidationException("Device credentials should be assigned to device!");
123 } 125 }
@@ -127,7 +129,7 @@ public class DeviceCredentialsServiceImpl implements DeviceCredentialsService { @@ -127,7 +129,7 @@ public class DeviceCredentialsServiceImpl implements DeviceCredentialsService {
127 if (StringUtils.isEmpty(deviceCredentials.getCredentialsId())) { 129 if (StringUtils.isEmpty(deviceCredentials.getCredentialsId())) {
128 throw new DataValidationException("Device credentials id should be specified!"); 130 throw new DataValidationException("Device credentials id should be specified!");
129 } 131 }
130 - Device device = deviceService.findDeviceById(deviceCredentials.getDeviceId()); 132 + Device device = deviceService.findDeviceById(tenantId, deviceCredentials.getDeviceId());
131 if (device == null) { 133 if (device == null) {
132 throw new DataValidationException("Can't assign device credentials to non-existent device!"); 134 throw new DataValidationException("Can't assign device credentials to non-existent device!");
133 } 135 }
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.device;
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.Device; 19 import org.thingsboard.server.common.data.Device;
20 import org.thingsboard.server.common.data.EntitySubtype; 20 import org.thingsboard.server.common.data.EntitySubtype;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.page.TextPageLink; 22 import org.thingsboard.server.common.data.page.TextPageLink;
22 import org.thingsboard.server.dao.Dao; 23 import org.thingsboard.server.dao.Dao;
23 24
@@ -37,7 +38,7 @@ public interface DeviceDao extends Dao<Device> { @@ -37,7 +38,7 @@ public interface DeviceDao extends Dao<Device> {
37 * @param device the device object 38 * @param device the device object
38 * @return saved device object 39 * @return saved device object
39 */ 40 */
40 - Device save(Device device); 41 + Device save(TenantId tenantId, Device device);
41 42
42 /** 43 /**
43 * Find devices by tenantId and page link. 44 * Find devices by tenantId and page link.
@@ -29,19 +29,19 @@ import java.util.List; @@ -29,19 +29,19 @@ import java.util.List;
29 29
30 public interface DeviceService { 30 public interface DeviceService {
31 31
32 - Device findDeviceById(DeviceId deviceId); 32 + Device findDeviceById(TenantId tenantId, DeviceId deviceId);
33 33
34 - ListenableFuture<Device> findDeviceByIdAsync(DeviceId deviceId); 34 + ListenableFuture<Device> findDeviceByIdAsync(TenantId tenantId, DeviceId deviceId);
35 35
36 Device findDeviceByTenantIdAndName(TenantId tenantId, String name); 36 Device findDeviceByTenantIdAndName(TenantId tenantId, String name);
37 37
38 Device saveDevice(Device device); 38 Device saveDevice(Device device);
39 39
40 - Device assignDeviceToCustomer(DeviceId deviceId, CustomerId customerId); 40 + Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, CustomerId customerId);
41 41
42 - Device unassignDeviceFromCustomer(DeviceId deviceId); 42 + Device unassignDeviceFromCustomer(TenantId tenantId, DeviceId deviceId);
43 43
44 - void deleteDevice(DeviceId deviceId); 44 + void deleteDevice(TenantId tenantId, DeviceId deviceId);
45 45
46 TextPageData<Device> findDevicesByTenantId(TenantId tenantId, TextPageLink pageLink); 46 TextPageData<Device> findDevicesByTenantId(TenantId tenantId, TextPageLink pageLink);
47 47
@@ -59,7 +59,7 @@ public interface DeviceService { @@ -59,7 +59,7 @@ public interface DeviceService {
59 59
60 void unassignCustomerDevices(TenantId tenantId, CustomerId customerId); 60 void unassignCustomerDevices(TenantId tenantId, CustomerId customerId);
61 61
62 - ListenableFuture<List<Device>> findDevicesByQuery(DeviceSearchQuery query); 62 + ListenableFuture<List<Device>> findDevicesByQuery(TenantId tenantId, DeviceSearchQuery query);
63 63
64 ListenableFuture<List<EntitySubtype>> findDeviceTypesByTenantId(TenantId tenantId); 64 ListenableFuture<List<EntitySubtype>> findDeviceTypesByTenantId(TenantId tenantId);
65 65
@@ -96,17 +96,17 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -96,17 +96,17 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
96 private CacheManager cacheManager; 96 private CacheManager cacheManager;
97 97
98 @Override 98 @Override
99 - public Device findDeviceById(DeviceId deviceId) { 99 + public Device findDeviceById(TenantId tenantId, DeviceId deviceId) {
100 log.trace("Executing findDeviceById [{}]", deviceId); 100 log.trace("Executing findDeviceById [{}]", deviceId);
101 validateId(deviceId, INCORRECT_DEVICE_ID + deviceId); 101 validateId(deviceId, INCORRECT_DEVICE_ID + deviceId);
102 - return deviceDao.findById(deviceId.getId()); 102 + return deviceDao.findById(tenantId, deviceId.getId());
103 } 103 }
104 104
105 @Override 105 @Override
106 - public ListenableFuture<Device> findDeviceByIdAsync(DeviceId deviceId) { 106 + public ListenableFuture<Device> findDeviceByIdAsync(TenantId tenantId, DeviceId deviceId) {
107 log.trace("Executing findDeviceById [{}]", deviceId); 107 log.trace("Executing findDeviceById [{}]", deviceId);
108 validateId(deviceId, INCORRECT_DEVICE_ID + deviceId); 108 validateId(deviceId, INCORRECT_DEVICE_ID + deviceId);
109 - return deviceDao.findByIdAsync(deviceId.getId()); 109 + return deviceDao.findByIdAsync(tenantId, deviceId.getId());
110 } 110 }
111 111
112 @Cacheable(cacheNames = DEVICE_CACHE, key = "{#tenantId, #name}") 112 @Cacheable(cacheNames = DEVICE_CACHE, key = "{#tenantId, #name}")
@@ -122,38 +122,38 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -122,38 +122,38 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
122 @Override 122 @Override
123 public Device saveDevice(Device device) { 123 public Device saveDevice(Device device) {
124 log.trace("Executing saveDevice [{}]", device); 124 log.trace("Executing saveDevice [{}]", device);
125 - deviceValidator.validate(device);  
126 - Device savedDevice = deviceDao.save(device); 125 + deviceValidator.validate(device, Device::getTenantId);
  126 + Device savedDevice = deviceDao.save(device.getTenantId(), device);
127 if (device.getId() == null) { 127 if (device.getId() == null) {
128 DeviceCredentials deviceCredentials = new DeviceCredentials(); 128 DeviceCredentials deviceCredentials = new DeviceCredentials();
129 deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId())); 129 deviceCredentials.setDeviceId(new DeviceId(savedDevice.getUuidId()));
130 deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); 130 deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN);
131 deviceCredentials.setCredentialsId(RandomStringUtils.randomAlphanumeric(20)); 131 deviceCredentials.setCredentialsId(RandomStringUtils.randomAlphanumeric(20));
132 - deviceCredentialsService.createDeviceCredentials(deviceCredentials); 132 + deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials);
133 } 133 }
134 return savedDevice; 134 return savedDevice;
135 } 135 }
136 136
137 @Override 137 @Override
138 - public Device assignDeviceToCustomer(DeviceId deviceId, CustomerId customerId) {  
139 - Device device = findDeviceById(deviceId); 138 + public Device assignDeviceToCustomer(TenantId tenantId, DeviceId deviceId, CustomerId customerId) {
  139 + Device device = findDeviceById(tenantId, deviceId);
140 device.setCustomerId(customerId); 140 device.setCustomerId(customerId);
141 return saveDevice(device); 141 return saveDevice(device);
142 } 142 }
143 143
144 @Override 144 @Override
145 - public Device unassignDeviceFromCustomer(DeviceId deviceId) {  
146 - Device device = findDeviceById(deviceId); 145 + public Device unassignDeviceFromCustomer(TenantId tenantId, DeviceId deviceId) {
  146 + Device device = findDeviceById(tenantId, deviceId);
147 device.setCustomerId(null); 147 device.setCustomerId(null);
148 return saveDevice(device); 148 return saveDevice(device);
149 } 149 }
150 150
151 @Override 151 @Override
152 - public void deleteDevice(DeviceId deviceId) { 152 + public void deleteDevice(TenantId tenantId, DeviceId deviceId) {
153 log.trace("Executing deleteDevice [{}]", deviceId); 153 log.trace("Executing deleteDevice [{}]", deviceId);
154 validateId(deviceId, INCORRECT_DEVICE_ID + deviceId); 154 validateId(deviceId, INCORRECT_DEVICE_ID + deviceId);
155 155
156 - Device device = deviceDao.findById(deviceId.getId()); 156 + Device device = deviceDao.findById(tenantId, deviceId.getId());
157 try { 157 try {
158 List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(device.getTenantId(), deviceId).get(); 158 List<EntityView> entityViews = entityViewService.findEntityViewsByTenantIdAndEntityIdAsync(device.getTenantId(), deviceId).get();
159 if (entityViews != null && !entityViews.isEmpty()) { 159 if (entityViews != null && !entityViews.isEmpty()) {
@@ -164,11 +164,11 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -164,11 +164,11 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
164 throw new RuntimeException("Exception while finding entity views for deviceId [" + deviceId + "]", e); 164 throw new RuntimeException("Exception while finding entity views for deviceId [" + deviceId + "]", e);
165 } 165 }
166 166
167 - DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(deviceId); 167 + DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(tenantId, deviceId);
168 if (deviceCredentials != null) { 168 if (deviceCredentials != null) {
169 - deviceCredentialsService.deleteDeviceCredentials(deviceCredentials); 169 + deviceCredentialsService.deleteDeviceCredentials(tenantId, deviceCredentials);
170 } 170 }
171 - deleteEntityRelations(deviceId); 171 + deleteEntityRelations(tenantId, deviceId);
172 172
173 List<Object> list = new ArrayList<>(); 173 List<Object> list = new ArrayList<>();
174 list.add(device.getTenantId()); 174 list.add(device.getTenantId());
@@ -176,7 +176,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -176,7 +176,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
176 Cache cache = cacheManager.getCache(DEVICE_CACHE); 176 Cache cache = cacheManager.getCache(DEVICE_CACHE);
177 cache.evict(list); 177 cache.evict(list);
178 178
179 - deviceDao.removeById(deviceId.getId()); 179 + deviceDao.removeById(tenantId, deviceId.getId());
180 } 180 }
181 181
182 @Override 182 @Override
@@ -211,7 +211,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -211,7 +211,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
211 public void deleteDevicesByTenantId(TenantId tenantId) { 211 public void deleteDevicesByTenantId(TenantId tenantId) {
212 log.trace("Executing deleteDevicesByTenantId, tenantId [{}]", tenantId); 212 log.trace("Executing deleteDevicesByTenantId, tenantId [{}]", tenantId);
213 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 213 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
214 - tenantDevicesRemover.removeEntities(tenantId); 214 + tenantDevicesRemover.removeEntities(tenantId, tenantId);
215 } 215 }
216 216
217 @Override 217 @Override
@@ -250,19 +250,19 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -250,19 +250,19 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
250 log.trace("Executing unassignCustomerDevices, tenantId [{}], customerId [{}]", tenantId, customerId); 250 log.trace("Executing unassignCustomerDevices, tenantId [{}], customerId [{}]", tenantId, customerId);
251 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 251 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
252 validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); 252 validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
253 - new CustomerDevicesUnassigner(tenantId).removeEntities(customerId); 253 + customerDeviceUnasigner.removeEntities(tenantId, customerId);
254 } 254 }
255 255
256 @Override 256 @Override
257 - public ListenableFuture<List<Device>> findDevicesByQuery(DeviceSearchQuery query) {  
258 - ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(query.toEntitySearchQuery()); 257 + public ListenableFuture<List<Device>> findDevicesByQuery(TenantId tenantId, DeviceSearchQuery query) {
  258 + ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(tenantId, query.toEntitySearchQuery());
259 ListenableFuture<List<Device>> devices = Futures.transformAsync(relations, r -> { 259 ListenableFuture<List<Device>> devices = Futures.transformAsync(relations, r -> {
260 EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection(); 260 EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection();
261 List<ListenableFuture<Device>> futures = new ArrayList<>(); 261 List<ListenableFuture<Device>> futures = new ArrayList<>();
262 for (EntityRelation relation : r) { 262 for (EntityRelation relation : r) {
263 EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom(); 263 EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom();
264 if (entityId.getEntityType() == EntityType.DEVICE) { 264 if (entityId.getEntityType() == EntityType.DEVICE) {
265 - futures.add(findDeviceByIdAsync(new DeviceId(entityId.getId()))); 265 + futures.add(findDeviceByIdAsync(tenantId, new DeviceId(entityId.getId())));
266 } 266 }
267 } 267 }
268 return Futures.successfulAsList(futures); 268 return Futures.successfulAsList(futures);
@@ -285,7 +285,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -285,7 +285,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
285 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 285 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
286 ListenableFuture<List<EntitySubtype>> tenantDeviceTypes = deviceDao.findTenantDeviceTypesAsync(tenantId.getId()); 286 ListenableFuture<List<EntitySubtype>> tenantDeviceTypes = deviceDao.findTenantDeviceTypesAsync(tenantId.getId());
287 return Futures.transform(tenantDeviceTypes, 287 return Futures.transform(tenantDeviceTypes,
288 - (Function<List<EntitySubtype>, List<EntitySubtype>>) deviceTypes -> { 288 + deviceTypes -> {
289 deviceTypes.sort(Comparator.comparing(EntitySubtype::getType)); 289 deviceTypes.sort(Comparator.comparing(EntitySubtype::getType));
290 return deviceTypes; 290 return deviceTypes;
291 }); 291 });
@@ -295,7 +295,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -295,7 +295,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
295 new DataValidator<Device>() { 295 new DataValidator<Device>() {
296 296
297 @Override 297 @Override
298 - protected void validateCreate(Device device) { 298 + protected void validateCreate(TenantId tenantId, Device device) {
299 deviceDao.findDeviceByTenantIdAndName(device.getTenantId().getId(), device.getName()).ifPresent( 299 deviceDao.findDeviceByTenantIdAndName(device.getTenantId().getId(), device.getName()).ifPresent(
300 d -> { 300 d -> {
301 throw new DataValidationException("Device with such name already exists!"); 301 throw new DataValidationException("Device with such name already exists!");
@@ -304,7 +304,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -304,7 +304,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
304 } 304 }
305 305
306 @Override 306 @Override
307 - protected void validateUpdate(Device device) { 307 + protected void validateUpdate(TenantId tenantId, Device device) {
308 deviceDao.findDeviceByTenantIdAndName(device.getTenantId().getId(), device.getName()).ifPresent( 308 deviceDao.findDeviceByTenantIdAndName(device.getTenantId().getId(), device.getName()).ifPresent(
309 d -> { 309 d -> {
310 if (!d.getUuidId().equals(device.getUuidId())) { 310 if (!d.getUuidId().equals(device.getUuidId())) {
@@ -315,7 +315,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -315,7 +315,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
315 } 315 }
316 316
317 @Override 317 @Override
318 - protected void validateDataImpl(Device device) { 318 + protected void validateDataImpl(TenantId tenantId, Device device) {
319 if (StringUtils.isEmpty(device.getType())) { 319 if (StringUtils.isEmpty(device.getType())) {
320 throw new DataValidationException("Device type should be specified!"); 320 throw new DataValidationException("Device type should be specified!");
321 } 321 }
@@ -325,7 +325,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -325,7 +325,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
325 if (device.getTenantId() == null) { 325 if (device.getTenantId() == null) {
326 throw new DataValidationException("Device should be assigned to tenant!"); 326 throw new DataValidationException("Device should be assigned to tenant!");
327 } else { 327 } else {
328 - Tenant tenant = tenantDao.findById(device.getTenantId().getId()); 328 + Tenant tenant = tenantDao.findById(device.getTenantId(), device.getTenantId().getId());
329 if (tenant == null) { 329 if (tenant == null) {
330 throw new DataValidationException("Device is referencing to non-existent tenant!"); 330 throw new DataValidationException("Device is referencing to non-existent tenant!");
331 } 331 }
@@ -333,7 +333,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -333,7 +333,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
333 if (device.getCustomerId() == null) { 333 if (device.getCustomerId() == null) {
334 device.setCustomerId(new CustomerId(NULL_UUID)); 334 device.setCustomerId(new CustomerId(NULL_UUID));
335 } else if (!device.getCustomerId().getId().equals(NULL_UUID)) { 335 } else if (!device.getCustomerId().getId().equals(NULL_UUID)) {
336 - Customer customer = customerDao.findById(device.getCustomerId().getId()); 336 + Customer customer = customerDao.findById(device.getTenantId(), device.getCustomerId().getId());
337 if (customer == null) { 337 if (customer == null) {
338 throw new DataValidationException("Can't assign device to non-existent customer!"); 338 throw new DataValidationException("Can't assign device to non-existent customer!");
339 } 339 }
@@ -345,36 +345,29 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -345,36 +345,29 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
345 }; 345 };
346 346
347 private PaginatedRemover<TenantId, Device> tenantDevicesRemover = 347 private PaginatedRemover<TenantId, Device> tenantDevicesRemover =
348 - new PaginatedRemover<TenantId, Device>() { 348 + new PaginatedRemover<TenantId, Device>() {
349 349
350 - @Override  
351 - protected List<Device> findEntities(TenantId id, TextPageLink pageLink) {  
352 - return deviceDao.findDevicesByTenantId(id.getId(), pageLink);  
353 - }  
354 -  
355 - @Override  
356 - protected void removeEntity(Device entity) {  
357 - deleteDevice(new DeviceId(entity.getUuidId()));  
358 - }  
359 - };  
360 -  
361 - private class CustomerDevicesUnassigner extends PaginatedRemover<CustomerId, Device> { 350 + @Override
  351 + protected List<Device> findEntities(TenantId tenantId, TenantId id, TextPageLink pageLink) {
  352 + return deviceDao.findDevicesByTenantId(id.getId(), pageLink);
  353 + }
362 354
363 - private TenantId tenantId; 355 + @Override
  356 + protected void removeEntity(TenantId tenantId, Device entity) {
  357 + deleteDevice(tenantId, new DeviceId(entity.getUuidId()));
  358 + }
  359 + };
364 360
365 - CustomerDevicesUnassigner(TenantId tenantId) {  
366 - this.tenantId = tenantId;  
367 - } 361 + private PaginatedRemover<CustomerId, Device> customerDeviceUnasigner = new PaginatedRemover<CustomerId, Device>() {
368 362
369 @Override 363 @Override
370 - protected List<Device> findEntities(CustomerId id, TextPageLink pageLink) { 364 + protected List<Device> findEntities(TenantId tenantId, CustomerId id, TextPageLink pageLink) {
371 return deviceDao.findDevicesByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink); 365 return deviceDao.findDevicesByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink);
372 } 366 }
373 367
374 @Override 368 @Override
375 - protected void removeEntity(Device entity) {  
376 - unassignDeviceFromCustomer(new DeviceId(entity.getUuidId())); 369 + protected void removeEntity(TenantId tenantId, Device entity) {
  370 + unassignDeviceFromCustomer(tenantId, new DeviceId(entity.getUuidId()));
377 } 371 }
378 -  
379 - } 372 + };
380 } 373 }
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.entity; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.entity;
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.springframework.beans.factory.annotation.Autowired; 19 import org.springframework.beans.factory.annotation.Autowired;
20 import org.thingsboard.server.common.data.id.EntityId; 20 import org.thingsboard.server.common.data.id.EntityId;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.dao.relation.RelationService; 22 import org.thingsboard.server.dao.relation.RelationService;
22 23
23 @Slf4j 24 @Slf4j
@@ -26,9 +27,9 @@ public abstract class AbstractEntityService { @@ -26,9 +27,9 @@ public abstract class AbstractEntityService {
26 @Autowired 27 @Autowired
27 protected RelationService relationService; 28 protected RelationService relationService;
28 29
29 - protected void deleteEntityRelations(EntityId entityId) { 30 + protected void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
30 log.trace("Executing deleteEntityRelations [{}]", entityId); 31 log.trace("Executing deleteEntityRelations [{}]", entityId);
31 - relationService.deleteEntityRelations(entityId); 32 + relationService.deleteEntityRelations(tenantId, entityId);
32 } 33 }
33 34
34 } 35 }
@@ -69,42 +69,42 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe @@ -69,42 +69,42 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
69 private RuleChainService ruleChainService; 69 private RuleChainService ruleChainService;
70 70
71 @Override 71 @Override
72 - public void deleteEntityRelations(EntityId entityId) {  
73 - super.deleteEntityRelations(entityId); 72 + public void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
  73 + super.deleteEntityRelations(tenantId, entityId);
74 } 74 }
75 75
76 @Override 76 @Override
77 - public ListenableFuture<String> fetchEntityNameAsync(EntityId entityId) { 77 + public ListenableFuture<String> fetchEntityNameAsync(TenantId tenantId, EntityId entityId) {
78 log.trace("Executing fetchEntityNameAsync [{}]", entityId); 78 log.trace("Executing fetchEntityNameAsync [{}]", entityId);
79 ListenableFuture<String> entityName; 79 ListenableFuture<String> entityName;
80 ListenableFuture<? extends HasName> hasName; 80 ListenableFuture<? extends HasName> hasName;
81 switch (entityId.getEntityType()) { 81 switch (entityId.getEntityType()) {
82 case ASSET: 82 case ASSET:
83 - hasName = assetService.findAssetByIdAsync(new AssetId(entityId.getId())); 83 + hasName = assetService.findAssetByIdAsync(tenantId, new AssetId(entityId.getId()));
84 break; 84 break;
85 case DEVICE: 85 case DEVICE:
86 - hasName = deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); 86 + hasName = deviceService.findDeviceByIdAsync(tenantId, new DeviceId(entityId.getId()));
87 break; 87 break;
88 case ENTITY_VIEW: 88 case ENTITY_VIEW:
89 - hasName = entityViewService.findEntityViewByIdAsync(new EntityViewId(entityId.getId())); 89 + hasName = entityViewService.findEntityViewByIdAsync(tenantId, new EntityViewId(entityId.getId()));
90 break; 90 break;
91 case TENANT: 91 case TENANT:
92 - hasName = tenantService.findTenantByIdAsync(new TenantId(entityId.getId())); 92 + hasName = tenantService.findTenantByIdAsync(tenantId, new TenantId(entityId.getId()));
93 break; 93 break;
94 case CUSTOMER: 94 case CUSTOMER:
95 - hasName = customerService.findCustomerByIdAsync(new CustomerId(entityId.getId())); 95 + hasName = customerService.findCustomerByIdAsync(tenantId, new CustomerId(entityId.getId()));
96 break; 96 break;
97 case USER: 97 case USER:
98 - hasName = userService.findUserByIdAsync(new UserId(entityId.getId())); 98 + hasName = userService.findUserByIdAsync(tenantId, new UserId(entityId.getId()));
99 break; 99 break;
100 case DASHBOARD: 100 case DASHBOARD:
101 - hasName = dashboardService.findDashboardInfoByIdAsync(new DashboardId(entityId.getId())); 101 + hasName = dashboardService.findDashboardInfoByIdAsync(tenantId, new DashboardId(entityId.getId()));
102 break; 102 break;
103 case ALARM: 103 case ALARM:
104 - hasName = alarmService.findAlarmByIdAsync(new AlarmId(entityId.getId())); 104 + hasName = alarmService.findAlarmByIdAsync(tenantId, new AlarmId(entityId.getId()));
105 break; 105 break;
106 case RULE_CHAIN: 106 case RULE_CHAIN:
107 - hasName = ruleChainService.findRuleChainByIdAsync(new RuleChainId(entityId.getId())); 107 + hasName = ruleChainService.findRuleChainByIdAsync(tenantId, new RuleChainId(entityId.getId()));
108 break; 108 break;
109 default: 109 default:
110 throw new IllegalStateException("Not Implemented!"); 110 throw new IllegalStateException("Not Implemented!");
@@ -17,11 +17,12 @@ package org.thingsboard.server.dao.entity; @@ -17,11 +17,12 @@ package org.thingsboard.server.dao.entity;
17 17
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.id.EntityId; 19 import org.thingsboard.server.common.data.id.EntityId;
  20 +import org.thingsboard.server.common.data.id.TenantId;
20 21
21 public interface EntityService { 22 public interface EntityService {
22 23
23 - ListenableFuture<String> fetchEntityNameAsync(EntityId entityId); 24 + ListenableFuture<String> fetchEntityNameAsync(TenantId tenantId, EntityId entityId);
24 25
25 - void deleteEntityRelations(EntityId entityId); 26 + void deleteEntityRelations(TenantId tenantId, EntityId entityId);
26 27
27 } 28 }
@@ -28,6 +28,7 @@ import org.springframework.stereotype.Component; @@ -28,6 +28,7 @@ import org.springframework.stereotype.Component;
28 import org.thingsboard.server.common.data.EntitySubtype; 28 import org.thingsboard.server.common.data.EntitySubtype;
29 import org.thingsboard.server.common.data.EntityType; 29 import org.thingsboard.server.common.data.EntityType;
30 import org.thingsboard.server.common.data.EntityView; 30 import org.thingsboard.server.common.data.EntityView;
  31 +import org.thingsboard.server.common.data.id.TenantId;
31 import org.thingsboard.server.common.data.page.TextPageLink; 32 import org.thingsboard.server.common.data.page.TextPageLink;
32 import org.thingsboard.server.dao.DaoUtil; 33 import org.thingsboard.server.dao.DaoUtil;
33 import org.thingsboard.server.dao.model.EntitySubtypeEntity; 34 import org.thingsboard.server.dao.model.EntitySubtypeEntity;
@@ -82,12 +83,12 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit @@ -82,12 +83,12 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
82 } 83 }
83 84
84 @Override 85 @Override
85 - public EntityView save(EntityView domain) {  
86 - EntityView savedEntityView = super.save(domain); 86 + public EntityView save(TenantId tenantId, EntityView domain) {
  87 + EntityView savedEntityView = super.save(domain.getTenantId(), domain);
87 EntitySubtype entitySubtype = new EntitySubtype(savedEntityView.getTenantId(), EntityType.ENTITY_VIEW, savedEntityView.getType()); 88 EntitySubtype entitySubtype = new EntitySubtype(savedEntityView.getTenantId(), EntityType.ENTITY_VIEW, savedEntityView.getType());
88 EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype); 89 EntitySubtypeEntity entitySubtypeEntity = new EntitySubtypeEntity(entitySubtype);
89 Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity); 90 Statement saveStatement = cluster.getMapper(EntitySubtypeEntity.class).saveQuery(entitySubtypeEntity);
90 - executeWrite(saveStatement); 91 + executeWrite(tenantId, saveStatement);
91 return savedEntityView; 92 return savedEntityView;
92 } 93 }
93 94
@@ -95,7 +96,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit @@ -95,7 +96,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
95 public List<EntityView> findEntityViewsByTenantId(UUID tenantId, TextPageLink pageLink) { 96 public List<EntityView> findEntityViewsByTenantId(UUID tenantId, TextPageLink pageLink) {
96 log.debug("Try to find entity views by tenantId [{}] and pageLink [{}]", tenantId, pageLink); 97 log.debug("Try to find entity views by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
97 List<EntityViewEntity> entityViewEntities = 98 List<EntityViewEntity> entityViewEntities =
98 - findPageWithTextSearch(ENTITY_VIEW_BY_TENANT_AND_SEARCH_TEXT_CF, 99 + findPageWithTextSearch(new TenantId(tenantId), ENTITY_VIEW_BY_TENANT_AND_SEARCH_TEXT_CF,
99 Collections.singletonList(eq(TENANT_ID_PROPERTY, tenantId)), pageLink); 100 Collections.singletonList(eq(TENANT_ID_PROPERTY, tenantId)), pageLink);
100 log.trace("Found entity views [{}] by tenantId [{}] and pageLink [{}]", 101 log.trace("Found entity views [{}] by tenantId [{}] and pageLink [{}]",
101 entityViewEntities, tenantId, pageLink); 102 entityViewEntities, tenantId, pageLink);
@@ -106,7 +107,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit @@ -106,7 +107,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
106 public List<EntityView> findEntityViewsByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) { 107 public List<EntityView> findEntityViewsByTenantIdAndType(UUID tenantId, String type, TextPageLink pageLink) {
107 log.debug("Try to find entity views by tenantId [{}], type [{}] and pageLink [{}]", tenantId, type, pageLink); 108 log.debug("Try to find entity views by tenantId [{}], type [{}] and pageLink [{}]", tenantId, type, pageLink);
108 List<EntityViewEntity> entityViewEntities = 109 List<EntityViewEntity> entityViewEntities =
109 - findPageWithTextSearch(ENTITY_VIEW_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_CF, 110 + findPageWithTextSearch(new TenantId(tenantId), ENTITY_VIEW_BY_TENANT_BY_TYPE_AND_SEARCH_TEXT_CF,
110 Arrays.asList(eq(ENTITY_VIEW_TYPE_PROPERTY, type), 111 Arrays.asList(eq(ENTITY_VIEW_TYPE_PROPERTY, type),
111 eq(TENANT_ID_PROPERTY, tenantId)), pageLink); 112 eq(TENANT_ID_PROPERTY, tenantId)), pageLink);
112 log.trace("Found entity views [{}] by tenantId [{}], type [{}] and pageLink [{}]", 113 log.trace("Found entity views [{}] by tenantId [{}], type [{}] and pageLink [{}]",
@@ -119,14 +120,14 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit @@ -119,14 +120,14 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
119 Select.Where query = select().from(ENTITY_VIEW_BY_TENANT_AND_NAME).where(); 120 Select.Where query = select().from(ENTITY_VIEW_BY_TENANT_AND_NAME).where();
120 query.and(eq(ENTITY_VIEW_TENANT_ID_PROPERTY, tenantId)); 121 query.and(eq(ENTITY_VIEW_TENANT_ID_PROPERTY, tenantId));
121 query.and(eq(ENTITY_VIEW_NAME_PROPERTY, name)); 122 query.and(eq(ENTITY_VIEW_NAME_PROPERTY, name));
122 - return Optional.ofNullable(DaoUtil.getData(findOneByStatement(query))); 123 + return Optional.ofNullable(DaoUtil.getData(findOneByStatement(new TenantId(tenantId), query)));
123 } 124 }
124 125
125 @Override 126 @Override
126 public List<EntityView> findEntityViewsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) { 127 public List<EntityView> findEntityViewsByTenantIdAndCustomerId(UUID tenantId, UUID customerId, TextPageLink pageLink) {
127 log.debug("Try to find entity views by tenantId [{}], customerId[{}] and pageLink [{}]", 128 log.debug("Try to find entity views by tenantId [{}], customerId[{}] and pageLink [{}]",
128 tenantId, customerId, pageLink); 129 tenantId, customerId, pageLink);
129 - List<EntityViewEntity> entityViewEntities = findPageWithTextSearch( 130 + List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(new TenantId(tenantId),
130 ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_CF, 131 ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_CF,
131 Arrays.asList(eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)), 132 Arrays.asList(eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)),
132 pageLink); 133 pageLink);
@@ -139,7 +140,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit @@ -139,7 +140,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
139 public List<EntityView> findEntityViewsByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) { 140 public List<EntityView> findEntityViewsByTenantIdAndCustomerIdAndType(UUID tenantId, UUID customerId, String type, TextPageLink pageLink) {
140 log.debug("Try to find entity views by tenantId [{}], customerId[{}], type [{}] and pageLink [{}]", 141 log.debug("Try to find entity views by tenantId [{}], customerId[{}], type [{}] and pageLink [{}]",
141 tenantId, customerId, type, pageLink); 142 tenantId, customerId, type, pageLink);
142 - List<EntityViewEntity> entityViewEntities = findPageWithTextSearch( 143 + List<EntityViewEntity> entityViewEntities = findPageWithTextSearch(new TenantId(tenantId),
143 ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_TYPE_CF, 144 ENTITY_VIEW_BY_TENANT_AND_CUSTOMER_AND_TYPE_CF,
144 Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type), eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)), 145 Arrays.asList(eq(DEVICE_TYPE_PROPERTY, type), eq(CUSTOMER_ID_PROPERTY, customerId), eq(TENANT_ID_PROPERTY, tenantId)),
145 pageLink); 146 pageLink);
@@ -154,7 +155,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit @@ -154,7 +155,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
154 Select.Where query = select().from(ENTITY_VIEW_BY_TENANT_AND_ENTITY_ID_CF).where(); 155 Select.Where query = select().from(ENTITY_VIEW_BY_TENANT_AND_ENTITY_ID_CF).where();
155 query.and(eq(TENANT_ID_PROPERTY, tenantId)); 156 query.and(eq(TENANT_ID_PROPERTY, tenantId));
156 query.and(eq(ENTITY_ID_COLUMN, entityId)); 157 query.and(eq(ENTITY_ID_COLUMN, entityId));
157 - return findListByStatementAsync(query); 158 + return findListByStatementAsync(new TenantId(tenantId), query);
158 } 159 }
159 160
160 @Override 161 @Override
@@ -164,7 +165,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit @@ -164,7 +165,7 @@ public class CassandraEntityViewDao extends CassandraAbstractSearchTextDao<Entit
164 query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId)); 165 query.and(eq(ENTITY_SUBTYPE_TENANT_ID_PROPERTY, tenantId));
165 query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.ENTITY_VIEW)); 166 query.and(eq(ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY, EntityType.ENTITY_VIEW));
166 query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); 167 query.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
167 - ResultSetFuture resultSetFuture = executeAsyncRead(query); 168 + ResultSetFuture resultSetFuture = executeAsyncRead(new TenantId(tenantId), query);
168 return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() { 169 return Futures.transform(resultSetFuture, new Function<ResultSet, List<EntitySubtype>>() {
169 @Nullable 170 @Nullable
170 @Override 171 @Override
@@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture; @@ -19,6 +19,7 @@ import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.Device; 19 import org.thingsboard.server.common.data.Device;
20 import org.thingsboard.server.common.data.EntitySubtype; 20 import org.thingsboard.server.common.data.EntitySubtype;
21 import org.thingsboard.server.common.data.EntityView; 21 import org.thingsboard.server.common.data.EntityView;
  22 +import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.common.data.page.TextPageLink; 23 import org.thingsboard.server.common.data.page.TextPageLink;
23 import org.thingsboard.server.dao.Dao; 24 import org.thingsboard.server.dao.Dao;
24 25
@@ -37,7 +38,7 @@ public interface EntityViewDao extends Dao<EntityView> { @@ -37,7 +38,7 @@ public interface EntityViewDao extends Dao<EntityView> {
37 * @param entityView the entity-view object 38 * @param entityView the entity-view object
38 * @return saved entity-view object 39 * @return saved entity-view object
39 */ 40 */
40 - EntityView save(EntityView entityView); 41 + EntityView save(TenantId tenantId, EntityView entityView);
41 42
42 /** 43 /**
43 * Find entity views by tenantId and page link. 44 * Find entity views by tenantId and page link.
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.entityview; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.entityview;
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.EntitySubtype; 19 import org.thingsboard.server.common.data.EntitySubtype;
20 import org.thingsboard.server.common.data.EntityView; 20 import org.thingsboard.server.common.data.EntityView;
  21 +import org.thingsboard.server.common.data.Tenant;
21 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery; 22 import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
22 import org.thingsboard.server.common.data.id.CustomerId; 23 import org.thingsboard.server.common.data.id.CustomerId;
23 import org.thingsboard.server.common.data.id.EntityId; 24 import org.thingsboard.server.common.data.id.EntityId;
@@ -35,13 +36,13 @@ public interface EntityViewService { @@ -35,13 +36,13 @@ public interface EntityViewService {
35 36
36 EntityView saveEntityView(EntityView entityView); 37 EntityView saveEntityView(EntityView entityView);
37 38
38 - EntityView assignEntityViewToCustomer(EntityViewId entityViewId, CustomerId customerId); 39 + EntityView assignEntityViewToCustomer(TenantId tenantId, EntityViewId entityViewId, CustomerId customerId);
39 40
40 - EntityView unassignEntityViewFromCustomer(EntityViewId entityViewId); 41 + EntityView unassignEntityViewFromCustomer(TenantId tenantId, EntityViewId entityViewId);
41 42
42 void unassignCustomerEntityViews(TenantId tenantId, CustomerId customerId); 43 void unassignCustomerEntityViews(TenantId tenantId, CustomerId customerId);
43 44
44 - EntityView findEntityViewById(EntityViewId entityViewId); 45 + EntityView findEntityViewById(TenantId tenantId, EntityViewId entityViewId);
45 46
46 EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name); 47 EntityView findEntityViewByTenantIdAndName(TenantId tenantId, String name);
47 48
@@ -53,13 +54,13 @@ public interface EntityViewService { @@ -53,13 +54,13 @@ public interface EntityViewService {
53 54
54 TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndType(TenantId tenantId, CustomerId customerId, TextPageLink pageLink, String type); 55 TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndType(TenantId tenantId, CustomerId customerId, TextPageLink pageLink, String type);
55 56
56 - ListenableFuture<List<EntityView>> findEntityViewsByQuery(EntityViewSearchQuery query); 57 + ListenableFuture<List<EntityView>> findEntityViewsByQuery(TenantId tenantId, EntityViewSearchQuery query);
57 58
58 - ListenableFuture<EntityView> findEntityViewByIdAsync(EntityViewId entityViewId); 59 + ListenableFuture<EntityView> findEntityViewByIdAsync(TenantId tenantId, EntityViewId entityViewId);
59 60
60 ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEntityIdAsync(TenantId tenantId, EntityId entityId); 61 ListenableFuture<List<EntityView>> findEntityViewsByTenantIdAndEntityIdAsync(TenantId tenantId, EntityId entityId);
61 62
62 - void deleteEntityView(EntityViewId entityViewId); 63 + void deleteEntityView(TenantId tenantId, EntityViewId entityViewId);
63 64
64 void deleteEntityViewsByTenantId(TenantId tenantId); 65 void deleteEntityViewsByTenantId(TenantId tenantId);
65 66
@@ -95,23 +95,23 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -95,23 +95,23 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
95 @Override 95 @Override
96 public EntityView saveEntityView(EntityView entityView) { 96 public EntityView saveEntityView(EntityView entityView) {
97 log.trace("Executing save entity view [{}]", entityView); 97 log.trace("Executing save entity view [{}]", entityView);
98 - entityViewValidator.validate(entityView);  
99 - EntityView savedEntityView = entityViewDao.save(entityView); 98 + entityViewValidator.validate(entityView, EntityView::getTenantId);
  99 + EntityView savedEntityView = entityViewDao.save(entityView.getTenantId(), entityView);
100 return savedEntityView; 100 return savedEntityView;
101 } 101 }
102 102
103 @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}") 103 @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
104 @Override 104 @Override
105 - public EntityView assignEntityViewToCustomer(EntityViewId entityViewId, CustomerId customerId) {  
106 - EntityView entityView = findEntityViewById(entityViewId); 105 + public EntityView assignEntityViewToCustomer(TenantId tenantId, EntityViewId entityViewId, CustomerId customerId) {
  106 + EntityView entityView = findEntityViewById(tenantId, entityViewId);
107 entityView.setCustomerId(customerId); 107 entityView.setCustomerId(customerId);
108 return saveEntityView(entityView); 108 return saveEntityView(entityView);
109 } 109 }
110 110
111 @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}") 111 @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
112 @Override 112 @Override
113 - public EntityView unassignEntityViewFromCustomer(EntityViewId entityViewId) {  
114 - EntityView entityView = findEntityViewById(entityViewId); 113 + public EntityView unassignEntityViewFromCustomer(TenantId tenantId, EntityViewId entityViewId) {
  114 + EntityView entityView = findEntityViewById(tenantId, entityViewId);
115 entityView.setCustomerId(null); 115 entityView.setCustomerId(null);
116 return saveEntityView(entityView); 116 return saveEntityView(entityView);
117 } 117 }
@@ -121,15 +121,15 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -121,15 +121,15 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
121 log.trace("Executing unassignCustomerEntityViews, tenantId [{}], customerId [{}]", tenantId, customerId); 121 log.trace("Executing unassignCustomerEntityViews, tenantId [{}], customerId [{}]", tenantId, customerId);
122 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 122 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
123 validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); 123 validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
124 - new CustomerEntityViewsUnAssigner(tenantId).removeEntities(customerId); 124 + customerEntityViewsUnAssigner.removeEntities(tenantId, customerId);
125 } 125 }
126 126
127 @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}") 127 @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
128 @Override 128 @Override
129 - public EntityView findEntityViewById(EntityViewId entityViewId) { 129 + public EntityView findEntityViewById(TenantId tenantId, EntityViewId entityViewId) {
130 log.trace("Executing findEntityViewById [{}]", entityViewId); 130 log.trace("Executing findEntityViewById [{}]", entityViewId);
131 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId); 131 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId);
132 - return entityViewDao.findById(entityViewId.getId()); 132 + return entityViewDao.findById(tenantId, entityViewId.getId());
133 } 133 }
134 134
135 @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #name}") 135 @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #name}")
@@ -187,15 +187,15 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -187,15 +187,15 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
187 } 187 }
188 188
189 @Override 189 @Override
190 - public ListenableFuture<List<EntityView>> findEntityViewsByQuery(EntityViewSearchQuery query) {  
191 - ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(query.toEntitySearchQuery()); 190 + public ListenableFuture<List<EntityView>> findEntityViewsByQuery(TenantId tenantId, EntityViewSearchQuery query) {
  191 + ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(tenantId, query.toEntitySearchQuery());
192 ListenableFuture<List<EntityView>> entityViews = Futures.transformAsync(relations, r -> { 192 ListenableFuture<List<EntityView>> entityViews = Futures.transformAsync(relations, r -> {
193 EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection(); 193 EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection();
194 List<ListenableFuture<EntityView>> futures = new ArrayList<>(); 194 List<ListenableFuture<EntityView>> futures = new ArrayList<>();
195 for (EntityRelation relation : r) { 195 for (EntityRelation relation : r) {
196 EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom(); 196 EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom();
197 if (entityId.getEntityType() == EntityType.ENTITY_VIEW) { 197 if (entityId.getEntityType() == EntityType.ENTITY_VIEW) {
198 - futures.add(findEntityViewByIdAsync(new EntityViewId(entityId.getId()))); 198 + futures.add(findEntityViewByIdAsync(tenantId, new EntityViewId(entityId.getId())));
199 } 199 }
200 } 200 }
201 return Futures.successfulAsList(futures); 201 return Futures.successfulAsList(futures);
@@ -213,10 +213,10 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -213,10 +213,10 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
213 } 213 }
214 214
215 @Override 215 @Override
216 - public ListenableFuture<EntityView> findEntityViewByIdAsync(EntityViewId entityViewId) { 216 + public ListenableFuture<EntityView> findEntityViewByIdAsync(TenantId tenantId, EntityViewId entityViewId) {
217 log.trace("Executing findEntityViewById [{}]", entityViewId); 217 log.trace("Executing findEntityViewById [{}]", entityViewId);
218 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId); 218 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId);
219 - return entityViewDao.findByIdAsync(entityViewId.getId()); 219 + return entityViewDao.findByIdAsync(tenantId, entityViewId.getId());
220 } 220 }
221 221
222 @Override 222 @Override
@@ -253,21 +253,21 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -253,21 +253,21 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
253 253
254 @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}") 254 @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
255 @Override 255 @Override
256 - public void deleteEntityView(EntityViewId entityViewId) { 256 + public void deleteEntityView(TenantId tenantId, EntityViewId entityViewId) {
257 log.trace("Executing deleteEntityView [{}]", entityViewId); 257 log.trace("Executing deleteEntityView [{}]", entityViewId);
258 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId); 258 validateId(entityViewId, INCORRECT_ENTITY_VIEW_ID + entityViewId);
259 - deleteEntityRelations(entityViewId);  
260 - EntityView entityView = entityViewDao.findById(entityViewId.getId()); 259 + deleteEntityRelations(tenantId, entityViewId);
  260 + EntityView entityView = entityViewDao.findById(tenantId, entityViewId.getId());
261 cacheManager.getCache(ENTITY_VIEW_CACHE).evict(Arrays.asList(entityView.getTenantId(), entityView.getEntityId())); 261 cacheManager.getCache(ENTITY_VIEW_CACHE).evict(Arrays.asList(entityView.getTenantId(), entityView.getEntityId()));
262 cacheManager.getCache(ENTITY_VIEW_CACHE).evict(Arrays.asList(entityView.getTenantId(), entityView.getName())); 262 cacheManager.getCache(ENTITY_VIEW_CACHE).evict(Arrays.asList(entityView.getTenantId(), entityView.getName()));
263 - entityViewDao.removeById(entityViewId.getId()); 263 + entityViewDao.removeById(tenantId, entityViewId.getId());
264 } 264 }
265 265
266 @Override 266 @Override
267 public void deleteEntityViewsByTenantId(TenantId tenantId) { 267 public void deleteEntityViewsByTenantId(TenantId tenantId) {
268 log.trace("Executing deleteEntityViewsByTenantId, tenantId [{}]", tenantId); 268 log.trace("Executing deleteEntityViewsByTenantId, tenantId [{}]", tenantId);
269 validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 269 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
270 - tenantEntityViewRemover.removeEntities(tenantId); 270 + tenantEntityViewRemover.removeEntities(tenantId, tenantId);
271 } 271 }
272 272
273 @Override 273 @Override
@@ -286,7 +286,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -286,7 +286,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
286 new DataValidator<EntityView>() { 286 new DataValidator<EntityView>() {
287 287
288 @Override 288 @Override
289 - protected void validateCreate(EntityView entityView) { 289 + protected void validateCreate(TenantId tenantId, EntityView entityView) {
290 entityViewDao.findEntityViewByTenantIdAndName(entityView.getTenantId().getId(), entityView.getName()) 290 entityViewDao.findEntityViewByTenantIdAndName(entityView.getTenantId().getId(), entityView.getName())
291 .ifPresent(e -> { 291 .ifPresent(e -> {
292 throw new DataValidationException("Entity view with such name already exists!"); 292 throw new DataValidationException("Entity view with such name already exists!");
@@ -294,7 +294,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -294,7 +294,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
294 } 294 }
295 295
296 @Override 296 @Override
297 - protected void validateUpdate(EntityView entityView) { 297 + protected void validateUpdate(TenantId tenantId, EntityView entityView) {
298 entityViewDao.findEntityViewByTenantIdAndName(entityView.getTenantId().getId(), entityView.getName()) 298 entityViewDao.findEntityViewByTenantIdAndName(entityView.getTenantId().getId(), entityView.getName())
299 .ifPresent(e -> { 299 .ifPresent(e -> {
300 if (!e.getUuidId().equals(entityView.getUuidId())) { 300 if (!e.getUuidId().equals(entityView.getUuidId())) {
@@ -304,7 +304,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -304,7 +304,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
304 } 304 }
305 305
306 @Override 306 @Override
307 - protected void validateDataImpl(EntityView entityView) { 307 + protected void validateDataImpl(TenantId tenantId, EntityView entityView) {
308 if (StringUtils.isEmpty(entityView.getType())) { 308 if (StringUtils.isEmpty(entityView.getType())) {
309 throw new DataValidationException("Entity View type should be specified!"); 309 throw new DataValidationException("Entity View type should be specified!");
310 } 310 }
@@ -314,7 +314,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -314,7 +314,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
314 if (entityView.getTenantId() == null) { 314 if (entityView.getTenantId() == null) {
315 throw new DataValidationException("Entity view should be assigned to tenant!"); 315 throw new DataValidationException("Entity view should be assigned to tenant!");
316 } else { 316 } else {
317 - Tenant tenant = tenantDao.findById(entityView.getTenantId().getId()); 317 + Tenant tenant = tenantDao.findById(tenantId, entityView.getTenantId().getId());
318 if (tenant == null) { 318 if (tenant == null) {
319 throw new DataValidationException("Entity view is referencing to non-existent tenant!"); 319 throw new DataValidationException("Entity view is referencing to non-existent tenant!");
320 } 320 }
@@ -322,7 +322,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -322,7 +322,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
322 if (entityView.getCustomerId() == null) { 322 if (entityView.getCustomerId() == null) {
323 entityView.setCustomerId(new CustomerId(NULL_UUID)); 323 entityView.setCustomerId(new CustomerId(NULL_UUID));
324 } else if (!entityView.getCustomerId().getId().equals(NULL_UUID)) { 324 } else if (!entityView.getCustomerId().getId().equals(NULL_UUID)) {
325 - Customer customer = customerDao.findById(entityView.getCustomerId().getId()); 325 + Customer customer = customerDao.findById(tenantId, entityView.getCustomerId().getId());
326 if (customer == null) { 326 if (customer == null) {
327 throw new DataValidationException("Can't assign entity view to non-existent customer!"); 327 throw new DataValidationException("Can't assign entity view to non-existent customer!");
328 } 328 }
@@ -333,36 +333,27 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti @@ -333,36 +333,27 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
333 } 333 }
334 }; 334 };
335 335
336 - private PaginatedRemover<TenantId, EntityView> tenantEntityViewRemover =  
337 - new PaginatedRemover<TenantId, EntityView>() {  
338 -  
339 - @Override  
340 - protected List<EntityView> findEntities(TenantId id, TextPageLink pageLink) {  
341 - return entityViewDao.findEntityViewsByTenantId(id.getId(), pageLink);  
342 - }  
343 -  
344 - @Override  
345 - protected void removeEntity(EntityView entity) {  
346 - deleteEntityView(new EntityViewId(entity.getUuidId()));  
347 - }  
348 - };  
349 -  
350 - private class CustomerEntityViewsUnAssigner extends PaginatedRemover<CustomerId, EntityView> {  
351 -  
352 - private TenantId tenantId; 336 + private PaginatedRemover<TenantId, EntityView> tenantEntityViewRemover = new PaginatedRemover<TenantId, EntityView>() {
  337 + @Override
  338 + protected List<EntityView> findEntities(TenantId tenantId, TenantId id, TextPageLink pageLink) {
  339 + return entityViewDao.findEntityViewsByTenantId(id.getId(), pageLink);
  340 + }
353 341
354 - CustomerEntityViewsUnAssigner(TenantId tenantId) {  
355 - this.tenantId = tenantId; 342 + @Override
  343 + protected void removeEntity(TenantId tenantId, EntityView entity) {
  344 + deleteEntityView(tenantId, new EntityViewId(entity.getUuidId()));
356 } 345 }
  346 + };
357 347
  348 + private PaginatedRemover<CustomerId, EntityView> customerEntityViewsUnAssigner = new PaginatedRemover<CustomerId, EntityView>() {
358 @Override 349 @Override
359 - protected List<EntityView> findEntities(CustomerId id, TextPageLink pageLink) { 350 + protected List<EntityView> findEntities(TenantId tenantId, CustomerId id, TextPageLink pageLink) {
360 return entityViewDao.findEntityViewsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink); 351 return entityViewDao.findEntityViewsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink);
361 } 352 }
362 353
363 @Override 354 @Override
364 - protected void removeEntity(EntityView entity) {  
365 - unassignEntityViewFromCustomer(new EntityViewId(entity.getUuidId())); 355 + protected void removeEntity(TenantId tenantId, EntityView entity) {
  356 + unassignEntityViewFromCustomer(tenantId, new EntityViewId(entity.getUuidId()));
366 } 357 }
367 - } 358 + };
368 } 359 }
@@ -40,19 +40,19 @@ public class BaseEventService implements EventService { @@ -40,19 +40,19 @@ public class BaseEventService implements EventService {
40 40
41 @Override 41 @Override
42 public Event save(Event event) { 42 public Event save(Event event) {
43 - eventValidator.validate(event);  
44 - return eventDao.save(event); 43 + eventValidator.validate(event, Event::getTenantId);
  44 + return eventDao.save(event.getTenantId(), event);
45 } 45 }
46 46
47 @Override 47 @Override
48 public ListenableFuture<Event> saveAsync(Event event) { 48 public ListenableFuture<Event> saveAsync(Event event) {
49 - eventValidator.validate(event); 49 + eventValidator.validate(event, Event::getTenantId);
50 return eventDao.saveAsync(event); 50 return eventDao.saveAsync(event);
51 } 51 }
52 52
53 @Override 53 @Override
54 public Optional<Event> saveIfNotExists(Event event) { 54 public Optional<Event> saveIfNotExists(Event event) {
55 - eventValidator.validate(event); 55 + eventValidator.validate(event, Event::getTenantId);
56 if (StringUtils.isEmpty(event.getUid())) { 56 if (StringUtils.isEmpty(event.getUid())) {
57 throw new DataValidationException("Event uid should be specified!."); 57 throw new DataValidationException("Event uid should be specified!.");
58 } 58 }
@@ -97,7 +97,7 @@ public class BaseEventService implements EventService { @@ -97,7 +97,7 @@ public class BaseEventService implements EventService {
97 private DataValidator<Event> eventValidator = 97 private DataValidator<Event> eventValidator =
98 new DataValidator<Event>() { 98 new DataValidator<Event>() {
99 @Override 99 @Override
100 - protected void validateDataImpl(Event event) { 100 + protected void validateDataImpl(TenantId tenantId, Event event) {
101 if (event.getEntityId() == null) { 101 if (event.getEntityId() == null) {
102 throw new DataValidationException("Entity id should be specified!."); 102 throw new DataValidationException("Entity id should be specified!.");
103 } 103 }
@@ -64,7 +64,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE @@ -64,7 +64,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
64 } 64 }
65 65
66 @Override 66 @Override
67 - public Event save(Event event) { 67 + public Event save(TenantId tenantId, Event event) {
68 try { 68 try {
69 return saveAsync(event).get(); 69 return saveAsync(event).get();
70 } catch (InterruptedException | ExecutionException e) { 70 } catch (InterruptedException | ExecutionException e) {
@@ -85,7 +85,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE @@ -85,7 +85,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
85 if (StringUtils.isEmpty(event.getUid())) { 85 if (StringUtils.isEmpty(event.getUid())) {
86 event.setUid(event.getId().toString()); 86 event.setUid(event.getId().toString());
87 } 87 }
88 - ListenableFuture<Optional<Event>> optionalSave = saveAsync(new EventEntity(event), false); 88 + ListenableFuture<Optional<Event>> optionalSave = saveAsync(event.getTenantId(), new EventEntity(event), false);
89 return Futures.transform(optionalSave, opt -> opt.orElse(null)); 89 return Futures.transform(optionalSave, opt -> opt.orElse(null));
90 } 90 }
91 91
@@ -98,7 +98,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE @@ -98,7 +98,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
98 if (event.getId() == null) { 98 if (event.getId() == null) {
99 event.setId(new EventId(UUIDs.timeBased())); 99 event.setId(new EventId(UUIDs.timeBased()));
100 } 100 }
101 - return save(new EventEntity(event), true); 101 + return save(event.getTenantId(), new EventEntity(event), true);
102 } 102 }
103 103
104 @Override 104 @Override
@@ -111,7 +111,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE @@ -111,7 +111,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
111 .and(eq(ModelConstants.EVENT_TYPE_PROPERTY, eventType)) 111 .and(eq(ModelConstants.EVENT_TYPE_PROPERTY, eventType))
112 .and(eq(ModelConstants.EVENT_UID_PROPERTY, eventUid)); 112 .and(eq(ModelConstants.EVENT_UID_PROPERTY, eventUid));
113 log.trace("Execute query [{}]", query); 113 log.trace("Execute query [{}]", query);
114 - EventEntity entity = findOneByStatement(query); 114 + EventEntity entity = findOneByStatement(new TenantId(tenantId), query);
115 if (log.isTraceEnabled()) { 115 if (log.isTraceEnabled()) {
116 log.trace("Search result: [{}] for event entity [{}]", entity != null, entity); 116 log.trace("Search result: [{}] for event entity [{}]", entity != null, entity);
117 } else { 117 } else {
@@ -123,7 +123,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE @@ -123,7 +123,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
123 @Override 123 @Override
124 public List<Event> findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink) { 124 public List<Event> findEvents(UUID tenantId, EntityId entityId, TimePageLink pageLink) {
125 log.trace("Try to find events by tenant [{}], entity [{}]and pageLink [{}]", tenantId, entityId, pageLink); 125 log.trace("Try to find events by tenant [{}], entity [{}]and pageLink [{}]", tenantId, entityId, pageLink);
126 - List<EventEntity> entities = findPageWithTimeSearch(EVENT_BY_ID_VIEW_NAME, 126 + List<EventEntity> entities = findPageWithTimeSearch(new TenantId(tenantId), EVENT_BY_ID_VIEW_NAME,
127 Arrays.asList(eq(ModelConstants.EVENT_TENANT_ID_PROPERTY, tenantId), 127 Arrays.asList(eq(ModelConstants.EVENT_TENANT_ID_PROPERTY, tenantId),
128 eq(ModelConstants.EVENT_ENTITY_TYPE_PROPERTY, entityId.getEntityType()), 128 eq(ModelConstants.EVENT_ENTITY_TYPE_PROPERTY, entityId.getEntityType()),
129 eq(ModelConstants.EVENT_ENTITY_ID_PROPERTY, entityId.getId())), 129 eq(ModelConstants.EVENT_ENTITY_ID_PROPERTY, entityId.getId())),
@@ -135,7 +135,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE @@ -135,7 +135,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
135 @Override 135 @Override
136 public List<Event> findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink) { 136 public List<Event> findEvents(UUID tenantId, EntityId entityId, String eventType, TimePageLink pageLink) {
137 log.trace("Try to find events by tenant [{}], entity [{}], type [{}] and pageLink [{}]", tenantId, entityId, eventType, pageLink); 137 log.trace("Try to find events by tenant [{}], entity [{}], type [{}] and pageLink [{}]", tenantId, entityId, eventType, pageLink);
138 - List<EventEntity> entities = findPageWithTimeSearch(EVENT_BY_TYPE_AND_ID_VIEW_NAME, 138 + List<EventEntity> entities = findPageWithTimeSearch(new TenantId(tenantId), EVENT_BY_TYPE_AND_ID_VIEW_NAME,
139 Arrays.asList(eq(ModelConstants.EVENT_TENANT_ID_PROPERTY, tenantId), 139 Arrays.asList(eq(ModelConstants.EVENT_TENANT_ID_PROPERTY, tenantId),
140 eq(ModelConstants.EVENT_ENTITY_TYPE_PROPERTY, entityId.getEntityType()), 140 eq(ModelConstants.EVENT_ENTITY_TYPE_PROPERTY, entityId.getEntityType()),
141 eq(ModelConstants.EVENT_ENTITY_ID_PROPERTY, entityId.getId()), 141 eq(ModelConstants.EVENT_ENTITY_ID_PROPERTY, entityId.getId()),
@@ -158,19 +158,19 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE @@ -158,19 +158,19 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
158 query.and(eq(ModelConstants.EVENT_TYPE_PROPERTY, eventType)); 158 query.and(eq(ModelConstants.EVENT_TYPE_PROPERTY, eventType));
159 query.limit(limit); 159 query.limit(limit);
160 query.orderBy(QueryBuilder.desc(ModelConstants.EVENT_TYPE_PROPERTY), QueryBuilder.desc(ModelConstants.ID_PROPERTY)); 160 query.orderBy(QueryBuilder.desc(ModelConstants.EVENT_TYPE_PROPERTY), QueryBuilder.desc(ModelConstants.ID_PROPERTY));
161 - List<EventEntity> entities = findListByStatement(query); 161 + List<EventEntity> entities = findListByStatement(new TenantId(tenantId), query);
162 return DaoUtil.convertDataList(entities); 162 return DaoUtil.convertDataList(entities);
163 } 163 }
164 164
165 - private Optional<Event> save(EventEntity entity, boolean ifNotExists) { 165 + private Optional<Event> save(TenantId tenantId, EventEntity entity, boolean ifNotExists) {
166 try { 166 try {
167 - return saveAsync(entity, ifNotExists).get(); 167 + return saveAsync(tenantId, entity, ifNotExists).get();
168 } catch (InterruptedException | ExecutionException e) { 168 } catch (InterruptedException | ExecutionException e) {
169 throw new IllegalStateException("Could not save EventEntity", e); 169 throw new IllegalStateException("Could not save EventEntity", e);
170 } 170 }
171 } 171 }
172 172
173 - private ListenableFuture<Optional<Event>> saveAsync(EventEntity entity, boolean ifNotExists) { 173 + private ListenableFuture<Optional<Event>> saveAsync(TenantId tenantId, EventEntity entity, boolean ifNotExists) {
174 if (entity.getId() == null) { 174 if (entity.getId() == null) {
175 entity.setId(UUIDs.timeBased()); 175 entity.setId(UUIDs.timeBased());
176 } 176 }
@@ -185,7 +185,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE @@ -185,7 +185,7 @@ public class CassandraBaseEventDao extends CassandraAbstractSearchTimeDao<EventE
185 if (ifNotExists) { 185 if (ifNotExists) {
186 insert = insert.ifNotExists(); 186 insert = insert.ifNotExists();
187 } 187 }
188 - ResultSetFuture resultSetFuture = executeAsyncWrite(insert); 188 + ResultSetFuture resultSetFuture = executeAsyncWrite(tenantId, insert);
189 return Futures.transform(resultSetFuture, rs -> { 189 return Futures.transform(resultSetFuture, rs -> {
190 if (rs.wasApplied()) { 190 if (rs.wasApplied()) {
191 return Optional.of(DaoUtil.getData(entity)); 191 return Optional.of(DaoUtil.getData(entity));
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.event; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.event;
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.Event; 19 import org.thingsboard.server.common.data.Event;
20 import org.thingsboard.server.common.data.id.EntityId; 20 import org.thingsboard.server.common.data.id.EntityId;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.page.TimePageLink; 22 import org.thingsboard.server.common.data.page.TimePageLink;
22 import org.thingsboard.server.dao.Dao; 23 import org.thingsboard.server.dao.Dao;
23 24
@@ -36,7 +37,7 @@ public interface EventDao extends Dao<Event> { @@ -36,7 +37,7 @@ public interface EventDao extends Dao<Event> {
36 * @param event the event object 37 * @param event the event object
37 * @return saved event object 38 * @return saved event object
38 */ 39 */
39 - Event save(Event event); 40 + Event save(TenantId tenantId, Event event);
40 41
41 /** 42 /**
42 * Save or update event object async 43 * Save or update event object async
@@ -27,6 +27,7 @@ import com.datastax.driver.core.TypeCodec; @@ -27,6 +27,7 @@ import com.datastax.driver.core.TypeCodec;
27 import com.datastax.driver.core.exceptions.CodecNotFoundException; 27 import com.datastax.driver.core.exceptions.CodecNotFoundException;
28 import lombok.extern.slf4j.Slf4j; 28 import lombok.extern.slf4j.Slf4j;
29 import org.springframework.beans.factory.annotation.Autowired; 29 import org.springframework.beans.factory.annotation.Autowired;
  30 +import org.thingsboard.server.common.data.id.TenantId;
30 import org.thingsboard.server.dao.cassandra.CassandraCluster; 31 import org.thingsboard.server.dao.cassandra.CassandraCluster;
31 import org.thingsboard.server.dao.model.type.AuthorityCodec; 32 import org.thingsboard.server.dao.model.type.AuthorityCodec;
32 import org.thingsboard.server.dao.model.type.ComponentLifecycleStateCodec; 33 import org.thingsboard.server.dao.model.type.ComponentLifecycleStateCodec;
@@ -84,37 +85,37 @@ public abstract class CassandraAbstractDao { @@ -84,37 +85,37 @@ public abstract class CassandraAbstractDao {
84 } 85 }
85 } 86 }
86 87
87 - protected ResultSet executeRead(Statement statement) {  
88 - return execute(statement, defaultReadLevel); 88 + protected ResultSet executeRead(TenantId tenantId, Statement statement) {
  89 + return execute(tenantId, statement, defaultReadLevel);
89 } 90 }
90 91
91 - protected ResultSet executeWrite(Statement statement) {  
92 - return execute(statement, defaultWriteLevel); 92 + protected ResultSet executeWrite(TenantId tenantId, Statement statement) {
  93 + return execute(tenantId, statement, defaultWriteLevel);
93 } 94 }
94 95
95 - protected ResultSetFuture executeAsyncRead(Statement statement) {  
96 - return executeAsync(statement, defaultReadLevel); 96 + protected ResultSetFuture executeAsyncRead(TenantId tenantId, Statement statement) {
  97 + return executeAsync(tenantId, statement, defaultReadLevel);
97 } 98 }
98 99
99 - protected ResultSetFuture executeAsyncWrite(Statement statement) {  
100 - return executeAsync(statement, defaultWriteLevel); 100 + protected ResultSetFuture executeAsyncWrite(TenantId tenantId, Statement statement) {
  101 + return executeAsync(tenantId, statement, defaultWriteLevel);
101 } 102 }
102 103
103 - private ResultSet execute(Statement statement, ConsistencyLevel level) { 104 + private ResultSet execute(TenantId tenantId, Statement statement, ConsistencyLevel level) {
104 if (log.isDebugEnabled()) { 105 if (log.isDebugEnabled()) {
105 log.debug("Execute cassandra statement {}", statementToString(statement)); 106 log.debug("Execute cassandra statement {}", statementToString(statement));
106 } 107 }
107 - return executeAsync(statement, level).getUninterruptibly(); 108 + return executeAsync(tenantId, statement, level).getUninterruptibly();
108 } 109 }
109 110
110 - private ResultSetFuture executeAsync(Statement statement, ConsistencyLevel level) { 111 + private ResultSetFuture executeAsync(TenantId tenantId, Statement statement, ConsistencyLevel level) {
111 if (log.isDebugEnabled()) { 112 if (log.isDebugEnabled()) {
112 log.debug("Execute cassandra async statement {}", statementToString(statement)); 113 log.debug("Execute cassandra async statement {}", statementToString(statement));
113 } 114 }
114 if (statement.getConsistencyLevel() == null) { 115 if (statement.getConsistencyLevel() == null) {
115 statement.setConsistencyLevel(level); 116 statement.setConsistencyLevel(level);
116 } 117 }
117 - return rateLimiter.submit(new CassandraStatementTask(getSession(), statement)); 118 + return rateLimiter.submit(new CassandraStatementTask(tenantId, getSession(), statement));
118 } 119 }
119 120
120 private static String statementToString(Statement statement) { 121 private static String statementToString(Statement statement) {
@@ -27,6 +27,7 @@ import com.google.common.base.Function; @@ -27,6 +27,7 @@ import com.google.common.base.Function;
27 import com.google.common.util.concurrent.Futures; 27 import com.google.common.util.concurrent.Futures;
28 import com.google.common.util.concurrent.ListenableFuture; 28 import com.google.common.util.concurrent.ListenableFuture;
29 import lombok.extern.slf4j.Slf4j; 29 import lombok.extern.slf4j.Slf4j;
  30 +import org.thingsboard.server.common.data.id.TenantId;
30 import org.thingsboard.server.dao.Dao; 31 import org.thingsboard.server.dao.Dao;
31 import org.thingsboard.server.dao.DaoUtil; 32 import org.thingsboard.server.dao.DaoUtil;
32 import org.thingsboard.server.dao.model.BaseEntity; 33 import org.thingsboard.server.dao.model.BaseEntity;
@@ -56,11 +57,11 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte @@ -56,11 +57,11 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
56 return cluster.getMapper(getColumnFamilyClass()); 57 return cluster.getMapper(getColumnFamilyClass());
57 } 58 }
58 59
59 - protected List<E> findListByStatement(Statement statement) { 60 + protected List<E> findListByStatement(TenantId tenantId, Statement statement) {
60 List<E> list = Collections.emptyList(); 61 List<E> list = Collections.emptyList();
61 if (statement != null) { 62 if (statement != null) {
62 statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); 63 statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
63 - ResultSet resultSet = executeRead(statement); 64 + ResultSet resultSet = executeRead(tenantId, statement);
64 Result<E> result = getMapper().map(resultSet); 65 Result<E> result = getMapper().map(resultSet);
65 if (result != null) { 66 if (result != null) {
66 list = result.all(); 67 list = result.all();
@@ -69,10 +70,10 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte @@ -69,10 +70,10 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
69 return list; 70 return list;
70 } 71 }
71 72
72 - protected ListenableFuture<List<D>> findListByStatementAsync(Statement statement) { 73 + protected ListenableFuture<List<D>> findListByStatementAsync(TenantId tenantId, Statement statement) {
73 if (statement != null) { 74 if (statement != null) {
74 statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); 75 statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
75 - ResultSetFuture resultSetFuture = executeAsyncRead(statement); 76 + ResultSetFuture resultSetFuture = executeAsyncRead(tenantId, statement);
76 return Futures.transform(resultSetFuture, new Function<ResultSet, List<D>>() { 77 return Futures.transform(resultSetFuture, new Function<ResultSet, List<D>>() {
77 @Nullable 78 @Nullable
78 @Override 79 @Override
@@ -90,11 +91,11 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte @@ -90,11 +91,11 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
90 return Futures.immediateFuture(Collections.emptyList()); 91 return Futures.immediateFuture(Collections.emptyList());
91 } 92 }
92 93
93 - protected E findOneByStatement(Statement statement) { 94 + protected E findOneByStatement(TenantId tenantId, Statement statement) {
94 E object = null; 95 E object = null;
95 if (statement != null) { 96 if (statement != null) {
96 statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); 97 statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
97 - ResultSet resultSet = executeRead(statement); 98 + ResultSet resultSet = executeRead(tenantId, statement);
98 Result<E> result = getMapper().map(resultSet); 99 Result<E> result = getMapper().map(resultSet);
99 if (result != null) { 100 if (result != null) {
100 object = result.one(); 101 object = result.one();
@@ -103,10 +104,10 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte @@ -103,10 +104,10 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
103 return object; 104 return object;
104 } 105 }
105 106
106 - protected ListenableFuture<D> findOneByStatementAsync(Statement statement) { 107 + protected ListenableFuture<D> findOneByStatementAsync(TenantId tenantId, Statement statement) {
107 if (statement != null) { 108 if (statement != null) {
108 statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); 109 statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel());
109 - ResultSetFuture resultSetFuture = executeAsyncRead(statement); 110 + ResultSetFuture resultSetFuture = executeAsyncRead(tenantId, statement);
110 return Futures.transform(resultSetFuture, new Function<ResultSet, D>() { 111 return Futures.transform(resultSetFuture, new Function<ResultSet, D>() {
111 @Nullable 112 @Nullable
112 @Override 113 @Override
@@ -128,16 +129,16 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte @@ -128,16 +129,16 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
128 return getMapper().saveQuery(dto); 129 return getMapper().saveQuery(dto);
129 } 130 }
130 131
131 - protected EntityResultSet<E> saveWithResult(E entity) { 132 + protected EntityResultSet<E> saveWithResult(TenantId tenantId, E entity) {
132 log.debug("Save entity {}", entity); 133 log.debug("Save entity {}", entity);
133 if (entity.getId() == null) { 134 if (entity.getId() == null) {
134 entity.setId(UUIDs.timeBased()); 135 entity.setId(UUIDs.timeBased());
135 } else if (isDeleteOnSave()) { 136 } else if (isDeleteOnSave()) {
136 - removeById(entity.getId()); 137 + removeById(tenantId, entity.getId());
137 } 138 }
138 Statement saveStatement = getSaveQuery(entity); 139 Statement saveStatement = getSaveQuery(entity);
139 saveStatement.setConsistencyLevel(cluster.getDefaultWriteConsistencyLevel()); 140 saveStatement.setConsistencyLevel(cluster.getDefaultWriteConsistencyLevel());
140 - ResultSet resultSet = executeWrite(saveStatement); 141 + ResultSet resultSet = executeWrite(tenantId, saveStatement);
141 return new EntityResultSet<>(resultSet, entity); 142 return new EntityResultSet<>(resultSet, entity);
142 } 143 }
143 144
@@ -146,7 +147,7 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte @@ -146,7 +147,7 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
146 } 147 }
147 148
148 @Override 149 @Override
149 - public D save(D domain) { 150 + public D save(TenantId tenantId, D domain) {
150 E entity; 151 E entity;
151 try { 152 try {
152 entity = getColumnFamilyClass().getConstructor(domain.getClass()).newInstance(domain); 153 entity = getColumnFamilyClass().getConstructor(domain.getClass()).newInstance(domain);
@@ -156,48 +157,39 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte @@ -156,48 +157,39 @@ public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> exte
156 } 157 }
157 entity = updateSearchTextIfPresent(entity); 158 entity = updateSearchTextIfPresent(entity);
158 log.debug("Saving entity {}", entity); 159 log.debug("Saving entity {}", entity);
159 - entity = saveWithResult(entity).getEntity(); 160 + entity = saveWithResult(tenantId, entity).getEntity();
160 return DaoUtil.getData(entity); 161 return DaoUtil.getData(entity);
161 } 162 }
162 163
163 @Override 164 @Override
164 - public D findById(UUID key) { 165 + public D findById(TenantId tenantId, UUID key) {
165 log.debug("Get entity by key {}", key); 166 log.debug("Get entity by key {}", key);
166 Select.Where query = select().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key)); 167 Select.Where query = select().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key));
167 log.trace("Execute query {}", query); 168 log.trace("Execute query {}", query);
168 - E entity = findOneByStatement(query); 169 + E entity = findOneByStatement(tenantId, query);
169 return DaoUtil.getData(entity); 170 return DaoUtil.getData(entity);
170 } 171 }
171 172
172 @Override 173 @Override
173 - public ListenableFuture<D> findByIdAsync(UUID key) { 174 + public ListenableFuture<D> findByIdAsync(TenantId tenantId, UUID key) {
174 log.debug("Get entity by key {}", key); 175 log.debug("Get entity by key {}", key);
175 Select.Where query = select().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key)); 176 Select.Where query = select().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key));
176 log.trace("Execute query {}", query); 177 log.trace("Execute query {}", query);
177 - return findOneByStatementAsync(query); 178 + return findOneByStatementAsync(tenantId, query);
178 } 179 }
179 180
180 @Override 181 @Override
181 - public boolean removeById(UUID key) { 182 + public boolean removeById(TenantId tenantId, UUID key) {
182 Statement delete = QueryBuilder.delete().all().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key)); 183 Statement delete = QueryBuilder.delete().all().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key));
183 log.debug("Remove request: {}", delete.toString()); 184 log.debug("Remove request: {}", delete.toString());
184 - return executeWrite(delete).wasApplied(); 185 + return executeWrite(tenantId, delete).wasApplied();
185 } 186 }
186 187
187 @Override 188 @Override
188 - public List<D> find() { 189 + public List<D> find(TenantId tenantId) {
189 log.debug("Get all entities from column family {}", getColumnFamilyName()); 190 log.debug("Get all entities from column family {}", getColumnFamilyName());
190 - List<E> entities = findListByStatement(QueryBuilder.select().all().from(getColumnFamilyName()).setConsistencyLevel(cluster.getDefaultReadConsistencyLevel())); 191 + List<E> entities = findListByStatement(tenantId, QueryBuilder.select().all().from(getColumnFamilyName()).setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()));
191 return DaoUtil.convertDataList(entities); 192 return DaoUtil.convertDataList(entities);
192 } 193 }
193 -  
194 - protected static <T> Function<BaseEntity<T>, T> toDataFunction() {  
195 - return new Function<BaseEntity<T>, T>() {  
196 - @Nullable  
197 - @Override  
198 - public T apply(@Nullable BaseEntity<T> entity) {  
199 - return entity != null ? entity.toData() : null;  
200 - }  
201 - };  
202 - } 194 +
203 } 195 }
@@ -21,6 +21,7 @@ import com.datastax.driver.core.querybuilder.Select; @@ -21,6 +21,7 @@ import com.datastax.driver.core.querybuilder.Select;
21 import com.datastax.driver.core.querybuilder.Select.Where; 21 import com.datastax.driver.core.querybuilder.Select.Where;
22 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
23 import org.apache.commons.lang3.StringUtils; 23 import org.apache.commons.lang3.StringUtils;
  24 +import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.data.page.TextPageLink; 25 import org.thingsboard.server.common.data.page.TextPageLink;
25 import org.thingsboard.server.dao.model.ModelConstants; 26 import org.thingsboard.server.dao.model.ModelConstants;
26 import org.thingsboard.server.dao.model.SearchTextEntity; 27 import org.thingsboard.server.dao.model.SearchTextEntity;
@@ -43,38 +44,38 @@ public abstract class CassandraAbstractSearchTextDao<E extends SearchTextEntity< @@ -43,38 +44,38 @@ public abstract class CassandraAbstractSearchTextDao<E extends SearchTextEntity<
43 return entity; 44 return entity;
44 } 45 }
45 46
46 - protected List<E> findPageWithTextSearch(String searchView, List<Clause> clauses, TextPageLink pageLink) { 47 + protected List<E> findPageWithTextSearch(TenantId tenantId, String searchView, List<Clause> clauses, TextPageLink pageLink) {
47 Select select = select().from(searchView); 48 Select select = select().from(searchView);
48 Where query = select.where(); 49 Where query = select.where();
49 for (Clause clause : clauses) { 50 for (Clause clause : clauses) {
50 query.and(clause); 51 query.and(clause);
51 - } 52 + }
52 query.limit(pageLink.getLimit()); 53 query.limit(pageLink.getLimit());
53 if (!StringUtils.isEmpty(pageLink.getTextOffset())) { 54 if (!StringUtils.isEmpty(pageLink.getTextOffset())) {
54 query.and(eq(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextOffset())); 55 query.and(eq(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextOffset()));
55 query.and(QueryBuilder.lt(ModelConstants.ID_PROPERTY, pageLink.getIdOffset())); 56 query.and(QueryBuilder.lt(ModelConstants.ID_PROPERTY, pageLink.getIdOffset()));
56 - List<E> result = findListByStatement(query); 57 + List<E> result = findListByStatement(tenantId, query);
57 if (result.size() < pageLink.getLimit()) { 58 if (result.size() < pageLink.getLimit()) {
58 select = select().from(searchView); 59 select = select().from(searchView);
59 query = select.where(); 60 query = select.where();
60 for (Clause clause : clauses) { 61 for (Clause clause : clauses) {
61 query.and(clause); 62 query.and(clause);
62 - } 63 + }
63 query.and(QueryBuilder.gt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextOffset())); 64 query.and(QueryBuilder.gt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextOffset()));
64 if (!StringUtils.isEmpty(pageLink.getTextSearch())) { 65 if (!StringUtils.isEmpty(pageLink.getTextSearch())) {
65 query.and(QueryBuilder.lt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearchBound())); 66 query.and(QueryBuilder.lt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearchBound()));
66 } 67 }
67 int limit = pageLink.getLimit() - result.size(); 68 int limit = pageLink.getLimit() - result.size();
68 query.limit(limit); 69 query.limit(limit);
69 - result.addAll(findListByStatement(query)); 70 + result.addAll(findListByStatement(tenantId, query));
70 } 71 }
71 return result; 72 return result;
72 } else if (!StringUtils.isEmpty(pageLink.getTextSearch())) { 73 } else if (!StringUtils.isEmpty(pageLink.getTextSearch())) {
73 query.and(QueryBuilder.gte(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearch())); 74 query.and(QueryBuilder.gte(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearch()));
74 query.and(QueryBuilder.lt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearchBound())); 75 query.and(QueryBuilder.lt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearchBound()));
75 - return findListByStatement(query); 76 + return findListByStatement(tenantId, query);
76 } else { 77 } else {
77 - return findListByStatement(query); 78 + return findListByStatement(tenantId, query);
78 } 79 }
79 } 80 }
80 81
@@ -21,6 +21,7 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; @@ -21,6 +21,7 @@ import com.datastax.driver.core.querybuilder.QueryBuilder;
21 import com.datastax.driver.core.querybuilder.Select; 21 import com.datastax.driver.core.querybuilder.Select;
22 import com.datastax.driver.core.querybuilder.Select.Where; 22 import com.datastax.driver.core.querybuilder.Select.Where;
23 import com.datastax.driver.core.utils.UUIDs; 23 import com.datastax.driver.core.utils.UUIDs;
  24 +import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.data.page.TimePageLink; 25 import org.thingsboard.server.common.data.page.TimePageLink;
25 import org.thingsboard.server.dao.model.BaseEntity; 26 import org.thingsboard.server.dao.model.BaseEntity;
26 import org.thingsboard.server.dao.model.ModelConstants; 27 import org.thingsboard.server.dao.model.ModelConstants;
@@ -35,24 +36,24 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select; @@ -35,24 +36,24 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select;
35 public abstract class CassandraAbstractSearchTimeDao<E extends BaseEntity<D>, D> extends CassandraAbstractModelDao<E, D> { 36 public abstract class CassandraAbstractSearchTimeDao<E extends BaseEntity<D>, D> extends CassandraAbstractModelDao<E, D> {
36 37
37 38
38 - protected List<E> findPageWithTimeSearch(String searchView, List<Clause> clauses, TimePageLink pageLink) {  
39 - return findPageWithTimeSearch(searchView, clauses, Collections.emptyList(), pageLink); 39 + protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, TimePageLink pageLink) {
  40 + return findPageWithTimeSearch(tenantId, searchView, clauses, Collections.emptyList(), pageLink);
40 } 41 }
41 42
42 - protected List<E> findPageWithTimeSearch(String searchView, List<Clause> clauses, Ordering ordering, TimePageLink pageLink) {  
43 - return findPageWithTimeSearch(searchView, clauses, Collections.singletonList(ordering), pageLink); 43 + protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, Ordering ordering, TimePageLink pageLink) {
  44 + return findPageWithTimeSearch(tenantId, searchView, clauses, Collections.singletonList(ordering), pageLink);
44 } 45 }
45 46
46 - protected List<E> findPageWithTimeSearch(String searchView, List<Clause> clauses, List<Ordering> topLevelOrderings, TimePageLink pageLink) {  
47 - return findPageWithTimeSearch(searchView, clauses, topLevelOrderings, pageLink, ModelConstants.ID_PROPERTY); 47 + protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, List<Ordering> topLevelOrderings, TimePageLink pageLink) {
  48 + return findPageWithTimeSearch(tenantId, searchView, clauses, topLevelOrderings, pageLink, ModelConstants.ID_PROPERTY);
48 } 49 }
49 50
50 - protected List<E> findPageWithTimeSearch(String searchView, List<Clause> clauses, TimePageLink pageLink, String idColumn) {  
51 - return findPageWithTimeSearch(searchView, clauses, Collections.emptyList(), pageLink, idColumn); 51 + protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, TimePageLink pageLink, String idColumn) {
  52 + return findPageWithTimeSearch(tenantId, searchView, clauses, Collections.emptyList(), pageLink, idColumn);
52 } 53 }
53 54
54 - protected List<E> findPageWithTimeSearch(String searchView, List<Clause> clauses, List<Ordering> topLevelOrderings, TimePageLink pageLink, String idColumn) {  
55 - return findListByStatement(buildQuery(searchView, clauses, topLevelOrderings, pageLink, idColumn)); 55 + protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, List<Ordering> topLevelOrderings, TimePageLink pageLink, String idColumn) {
  56 + return findListByStatement(tenantId, buildQuery(searchView, clauses, topLevelOrderings, pageLink, idColumn));
56 } 57 }
57 58
58 public static Where buildQuery(String searchView, List<Clause> clauses, TimePageLink pageLink, String idColumn) { 59 public static Where buildQuery(String searchView, List<Clause> clauses, TimePageLink pageLink, String idColumn) {
@@ -22,11 +22,16 @@ import lombok.extern.slf4j.Slf4j; @@ -22,11 +22,16 @@ import lombok.extern.slf4j.Slf4j;
22 import org.springframework.beans.factory.annotation.Value; 22 import org.springframework.beans.factory.annotation.Value;
23 import org.springframework.scheduling.annotation.Scheduled; 23 import org.springframework.scheduling.annotation.Scheduled;
24 import org.springframework.stereotype.Component; 24 import org.springframework.stereotype.Component;
  25 +import org.thingsboard.server.common.data.EntityType;
  26 +import org.thingsboard.server.common.data.id.TenantId;
  27 +import org.thingsboard.server.common.msg.tools.TbRateLimits;
25 import org.thingsboard.server.dao.util.AbstractBufferedRateExecutor; 28 import org.thingsboard.server.dao.util.AbstractBufferedRateExecutor;
26 import org.thingsboard.server.dao.util.AsyncTaskContext; 29 import org.thingsboard.server.dao.util.AsyncTaskContext;
27 import org.thingsboard.server.dao.util.NoSqlAnyDao; 30 import org.thingsboard.server.dao.util.NoSqlAnyDao;
28 31
29 import javax.annotation.PreDestroy; 32 import javax.annotation.PreDestroy;
  33 +import java.util.concurrent.ConcurrentHashMap;
  34 +import java.util.concurrent.ConcurrentMap;
30 35
31 /** 36 /**
32 * Created by ashvayka on 24.10.18. 37 * Created by ashvayka on 24.10.18.
@@ -42,17 +47,19 @@ public class CassandraBufferedRateExecutor extends AbstractBufferedRateExecutor< @@ -42,17 +47,19 @@ public class CassandraBufferedRateExecutor extends AbstractBufferedRateExecutor<
42 @Value("${cassandra.query.permit_max_wait_time}") long maxWaitTime, 47 @Value("${cassandra.query.permit_max_wait_time}") long maxWaitTime,
43 @Value("${cassandra.query.dispatcher_threads:2}") int dispatcherThreads, 48 @Value("${cassandra.query.dispatcher_threads:2}") int dispatcherThreads,
44 @Value("${cassandra.query.callback_threads:2}") int callbackThreads, 49 @Value("${cassandra.query.callback_threads:2}") int callbackThreads,
45 - @Value("${cassandra.query.poll_ms:50}") long pollMs) {  
46 - super(queueLimit, concurrencyLimit, maxWaitTime, dispatcherThreads, callbackThreads, pollMs); 50 + @Value("${cassandra.query.poll_ms:50}") long pollMs,
  51 + @Value("${cassandra.query.tenant_rate_limits.enabled}") boolean tenantRateLimitsEnabled,
  52 + @Value("${cassandra.query.tenant_rate_limits.configuration}") String tenantRateLimitsConfiguration) {
  53 + super(queueLimit, concurrencyLimit, maxWaitTime, dispatcherThreads, callbackThreads, pollMs, tenantRateLimitsEnabled, tenantRateLimitsConfiguration);
47 } 54 }
48 55
49 @Scheduled(fixedDelayString = "${cassandra.query.rate_limit_print_interval_ms}") 56 @Scheduled(fixedDelayString = "${cassandra.query.rate_limit_print_interval_ms}")
50 public void printStats() { 57 public void printStats() {
51 - log.info("Permits queueSize [{}] totalAdded [{}] totalLaunched [{}] totalReleased [{}] totalFailed [{}] totalExpired [{}] totalRejected [{}] currBuffer [{}] ", 58 + log.info("Permits queueSize [{}] totalAdded [{}] totalLaunched [{}] totalReleased [{}] totalFailed [{}] totalExpired [{}] totalRejected [{}] totalRateLimited [{}] currBuffer [{}] ",
52 getQueueSize(), 59 getQueueSize(),
53 totalAdded.getAndSet(0), totalLaunched.getAndSet(0), totalReleased.getAndSet(0), 60 totalAdded.getAndSet(0), totalLaunched.getAndSet(0), totalReleased.getAndSet(0),
54 totalFailed.getAndSet(0), totalExpired.getAndSet(0), totalRejected.getAndSet(0), 61 totalFailed.getAndSet(0), totalExpired.getAndSet(0), totalRejected.getAndSet(0),
55 - concurrencyLevel.get()); 62 + totalRateLimited.getAndSet(0), concurrencyLevel.get());
56 } 63 }
57 64
58 @PreDestroy 65 @PreDestroy
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.nosql; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.nosql;
18 import com.datastax.driver.core.Session; 18 import com.datastax.driver.core.Session;
19 import com.datastax.driver.core.Statement; 19 import com.datastax.driver.core.Statement;
20 import lombok.Data; 20 import lombok.Data;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.dao.util.AsyncTask; 22 import org.thingsboard.server.dao.util.AsyncTask;
22 23
23 /** 24 /**
@@ -26,6 +27,7 @@ import org.thingsboard.server.dao.util.AsyncTask; @@ -26,6 +27,7 @@ import org.thingsboard.server.dao.util.AsyncTask;
26 @Data 27 @Data
27 public class CassandraStatementTask implements AsyncTask { 28 public class CassandraStatementTask implements AsyncTask {
28 29
  30 + private final TenantId tenantId;
29 private final Session session; 31 private final Session session;
30 private final Statement statement; 32 private final Statement statement;
31 33
@@ -29,6 +29,7 @@ import org.springframework.stereotype.Component; @@ -29,6 +29,7 @@ import org.springframework.stereotype.Component;
29 import org.thingsboard.server.common.data.EntityType; 29 import org.thingsboard.server.common.data.EntityType;
30 import org.thingsboard.server.common.data.id.EntityId; 30 import org.thingsboard.server.common.data.id.EntityId;
31 import org.thingsboard.server.common.data.id.EntityIdFactory; 31 import org.thingsboard.server.common.data.id.EntityIdFactory;
  32 +import org.thingsboard.server.common.data.id.TenantId;
32 import org.thingsboard.server.common.data.page.TimePageLink; 33 import org.thingsboard.server.common.data.page.TimePageLink;
33 import org.thingsboard.server.common.data.relation.EntityRelation; 34 import org.thingsboard.server.common.data.relation.EntityRelation;
34 import org.thingsboard.server.common.data.relation.RelationTypeGroup; 35 import org.thingsboard.server.common.data.relation.RelationTypeGroup;
@@ -83,45 +84,45 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati @@ -83,45 +84,45 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati
83 } 84 }
84 85
85 @Override 86 @Override
86 - public ListenableFuture<List<EntityRelation>> findAllByFrom(EntityId from, RelationTypeGroup typeGroup) { 87 + public ListenableFuture<List<EntityRelation>> findAllByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup) {
87 BoundStatement stmt = getFindAllByFromStmt().bind() 88 BoundStatement stmt = getFindAllByFromStmt().bind()
88 .setUUID(0, from.getId()) 89 .setUUID(0, from.getId())
89 .setString(1, from.getEntityType().name()) 90 .setString(1, from.getEntityType().name())
90 .set(2, typeGroup, relationTypeGroupCodec); 91 .set(2, typeGroup, relationTypeGroupCodec);
91 - return executeAsyncRead(from, stmt); 92 + return executeAsyncRead(tenantId, from, stmt);
92 } 93 }
93 94
94 @Override 95 @Override
95 - public ListenableFuture<List<EntityRelation>> findAllByFromAndType(EntityId from, String relationType, RelationTypeGroup typeGroup) { 96 + public ListenableFuture<List<EntityRelation>> findAllByFromAndType(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup) {
96 BoundStatement stmt = getFindAllByFromAndTypeStmt().bind() 97 BoundStatement stmt = getFindAllByFromAndTypeStmt().bind()
97 .setUUID(0, from.getId()) 98 .setUUID(0, from.getId())
98 .setString(1, from.getEntityType().name()) 99 .setString(1, from.getEntityType().name())
99 .set(2, typeGroup, relationTypeGroupCodec) 100 .set(2, typeGroup, relationTypeGroupCodec)
100 .setString(3, relationType); 101 .setString(3, relationType);
101 - return executeAsyncRead(from, stmt); 102 + return executeAsyncRead(tenantId, from, stmt);
102 } 103 }
103 104
104 @Override 105 @Override
105 - public ListenableFuture<List<EntityRelation>> findAllByTo(EntityId to, RelationTypeGroup typeGroup) { 106 + public ListenableFuture<List<EntityRelation>> findAllByTo(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup) {
106 BoundStatement stmt = getFindAllByToStmt().bind() 107 BoundStatement stmt = getFindAllByToStmt().bind()
107 .setUUID(0, to.getId()) 108 .setUUID(0, to.getId())
108 .setString(1, to.getEntityType().name()) 109 .setString(1, to.getEntityType().name())
109 .set(2, typeGroup, relationTypeGroupCodec); 110 .set(2, typeGroup, relationTypeGroupCodec);
110 - return executeAsyncRead(to, stmt); 111 + return executeAsyncRead(tenantId, to, stmt);
111 } 112 }
112 113
113 @Override 114 @Override
114 - public ListenableFuture<List<EntityRelation>> findAllByToAndType(EntityId to, String relationType, RelationTypeGroup typeGroup) { 115 + public ListenableFuture<List<EntityRelation>> findAllByToAndType(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup) {
115 BoundStatement stmt = getFindAllByToAndTypeStmt().bind() 116 BoundStatement stmt = getFindAllByToAndTypeStmt().bind()
116 .setUUID(0, to.getId()) 117 .setUUID(0, to.getId())
117 .setString(1, to.getEntityType().name()) 118 .setString(1, to.getEntityType().name())
118 .set(2, typeGroup, relationTypeGroupCodec) 119 .set(2, typeGroup, relationTypeGroupCodec)
119 .setString(3, relationType); 120 .setString(3, relationType);
120 - return executeAsyncRead(to, stmt); 121 + return executeAsyncRead(tenantId, to, stmt);
121 } 122 }
122 123
123 @Override 124 @Override
124 - public ListenableFuture<Boolean> checkRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { 125 + public ListenableFuture<Boolean> checkRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
125 BoundStatement stmt = getCheckRelationStmt().bind() 126 BoundStatement stmt = getCheckRelationStmt().bind()
126 .setUUID(0, from.getId()) 127 .setUUID(0, from.getId())
127 .setString(1, from.getEntityType().name()) 128 .setString(1, from.getEntityType().name())
@@ -129,11 +130,11 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati @@ -129,11 +130,11 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati
129 .setString(3, to.getEntityType().name()) 130 .setString(3, to.getEntityType().name())
130 .set(4, typeGroup, relationTypeGroupCodec) 131 .set(4, typeGroup, relationTypeGroupCodec)
131 .setString(5, relationType); 132 .setString(5, relationType);
132 - return getFuture(executeAsyncRead(stmt), rs -> rs != null ? rs.one() != null : false); 133 + return getFuture(executeAsyncRead(tenantId, stmt), rs -> rs != null ? rs.one() != null : false);
133 } 134 }
134 135
135 @Override 136 @Override
136 - public ListenableFuture<EntityRelation> getRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { 137 + public ListenableFuture<EntityRelation> getRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
137 BoundStatement stmt = getCheckRelationStmt().bind() 138 BoundStatement stmt = getCheckRelationStmt().bind()
138 .setUUID(0, from.getId()) 139 .setUUID(0, from.getId())
139 .setString(1, from.getEntityType().name()) 140 .setString(1, from.getEntityType().name())
@@ -141,24 +142,24 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati @@ -141,24 +142,24 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati
141 .setString(3, to.getEntityType().name()) 142 .setString(3, to.getEntityType().name())
142 .set(4, typeGroup, relationTypeGroupCodec) 143 .set(4, typeGroup, relationTypeGroupCodec)
143 .setString(5, relationType); 144 .setString(5, relationType);
144 - return getFuture(executeAsyncRead(stmt), rs -> rs != null ? getEntityRelation(rs.one()) : null); 145 + return getFuture(executeAsyncRead(tenantId, stmt), rs -> rs != null ? getEntityRelation(rs.one()) : null);
145 } 146 }
146 147
147 @Override 148 @Override
148 - public boolean saveRelation(EntityRelation relation) {  
149 - BoundStatement stmt = getSaveRelationStatement(relation);  
150 - ResultSet rs = executeWrite(stmt); 149 + public boolean saveRelation(TenantId tenantId, EntityRelation relation) {
  150 + BoundStatement stmt = getSaveRelationStatement(tenantId, relation);
  151 + ResultSet rs = executeWrite(tenantId, stmt);
151 return rs.wasApplied(); 152 return rs.wasApplied();
152 } 153 }
153 154
154 @Override 155 @Override
155 - public ListenableFuture<Boolean> saveRelationAsync(EntityRelation relation) {  
156 - BoundStatement stmt = getSaveRelationStatement(relation);  
157 - ResultSetFuture future = executeAsyncWrite(stmt); 156 + public ListenableFuture<Boolean> saveRelationAsync(TenantId tenantId, EntityRelation relation) {
  157 + BoundStatement stmt = getSaveRelationStatement(tenantId, relation);
  158 + ResultSetFuture future = executeAsyncWrite(tenantId, stmt);
158 return getBooleanListenableFuture(future); 159 return getBooleanListenableFuture(future);
159 } 160 }
160 161
161 - private BoundStatement getSaveRelationStatement(EntityRelation relation) { 162 + private BoundStatement getSaveRelationStatement(TenantId tenantId, EntityRelation relation) {
162 BoundStatement stmt = getSaveStmt().bind() 163 BoundStatement stmt = getSaveStmt().bind()
163 .setUUID(0, relation.getFrom().getId()) 164 .setUUID(0, relation.getFrom().getId())
164 .setString(1, relation.getFrom().getEntityType().name()) 165 .setString(1, relation.getFrom().getEntityType().name())
@@ -171,30 +172,30 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati @@ -171,30 +172,30 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati
171 } 172 }
172 173
173 @Override 174 @Override
174 - public boolean deleteRelation(EntityRelation relation) {  
175 - return deleteRelation(relation.getFrom(), relation.getTo(), relation.getType(), relation.getTypeGroup()); 175 + public boolean deleteRelation(TenantId tenantId, EntityRelation relation) {
  176 + return deleteRelation(tenantId, relation.getFrom(), relation.getTo(), relation.getType(), relation.getTypeGroup());
176 } 177 }
177 178
178 @Override 179 @Override
179 - public ListenableFuture<Boolean> deleteRelationAsync(EntityRelation relation) {  
180 - return deleteRelationAsync(relation.getFrom(), relation.getTo(), relation.getType(), relation.getTypeGroup()); 180 + public ListenableFuture<Boolean> deleteRelationAsync(TenantId tenantId, EntityRelation relation) {
  181 + return deleteRelationAsync(tenantId, relation.getFrom(), relation.getTo(), relation.getType(), relation.getTypeGroup());
181 } 182 }
182 183
183 @Override 184 @Override
184 - public boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {  
185 - BoundStatement stmt = getDeleteRelationStatement(from, to, relationType, typeGroup);  
186 - ResultSet rs = executeWrite(stmt); 185 + public boolean deleteRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
  186 + BoundStatement stmt = getDeleteRelationStatement(tenantId, from, to, relationType, typeGroup);
  187 + ResultSet rs = executeWrite(tenantId, stmt);
187 return rs.wasApplied(); 188 return rs.wasApplied();
188 } 189 }
189 190
190 @Override 191 @Override
191 - public ListenableFuture<Boolean> deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {  
192 - BoundStatement stmt = getDeleteRelationStatement(from, to, relationType, typeGroup);  
193 - ResultSetFuture future = executeAsyncWrite(stmt); 192 + public ListenableFuture<Boolean> deleteRelationAsync(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
  193 + BoundStatement stmt = getDeleteRelationStatement(tenantId, from, to, relationType, typeGroup);
  194 + ResultSetFuture future = executeAsyncWrite(tenantId, stmt);
194 return getBooleanListenableFuture(future); 195 return getBooleanListenableFuture(future);
195 } 196 }
196 197
197 - private BoundStatement getDeleteRelationStatement(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { 198 + private BoundStatement getDeleteRelationStatement(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
198 BoundStatement stmt = getDeleteStmt().bind() 199 BoundStatement stmt = getDeleteStmt().bind()
199 .setUUID(0, from.getId()) 200 .setUUID(0, from.getId())
200 .setString(1, from.getEntityType().name()) 201 .setString(1, from.getEntityType().name())
@@ -206,26 +207,26 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati @@ -206,26 +207,26 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati
206 } 207 }
207 208
208 @Override 209 @Override
209 - public boolean deleteOutboundRelations(EntityId entity) { 210 + public boolean deleteOutboundRelations(TenantId tenantId, EntityId entity) {
210 BoundStatement stmt = getDeleteAllByEntityStmt().bind() 211 BoundStatement stmt = getDeleteAllByEntityStmt().bind()
211 .setUUID(0, entity.getId()) 212 .setUUID(0, entity.getId())
212 .setString(1, entity.getEntityType().name()); 213 .setString(1, entity.getEntityType().name());
213 - ResultSet rs = executeWrite(stmt); 214 + ResultSet rs = executeWrite(tenantId, stmt);
214 return rs.wasApplied(); 215 return rs.wasApplied();
215 } 216 }
216 217
217 218
218 @Override 219 @Override
219 - public ListenableFuture<Boolean> deleteOutboundRelationsAsync(EntityId entity) { 220 + public ListenableFuture<Boolean> deleteOutboundRelationsAsync(TenantId tenantId, EntityId entity) {
220 BoundStatement stmt = getDeleteAllByEntityStmt().bind() 221 BoundStatement stmt = getDeleteAllByEntityStmt().bind()
221 .setUUID(0, entity.getId()) 222 .setUUID(0, entity.getId())
222 .setString(1, entity.getEntityType().name()); 223 .setString(1, entity.getEntityType().name());
223 - ResultSetFuture future = executeAsyncWrite(stmt); 224 + ResultSetFuture future = executeAsyncWrite(tenantId, stmt);
224 return getBooleanListenableFuture(future); 225 return getBooleanListenableFuture(future);
225 } 226 }
226 227
227 @Override 228 @Override
228 - public ListenableFuture<List<EntityRelation>> findRelations(EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType childType, TimePageLink pageLink) { 229 + public ListenableFuture<List<EntityRelation>> findRelations(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType childType, TimePageLink pageLink) {
229 Select.Where query = CassandraAbstractSearchTimeDao.buildQuery(ModelConstants.RELATION_BY_TYPE_AND_CHILD_TYPE_VIEW_NAME, 230 Select.Where query = CassandraAbstractSearchTimeDao.buildQuery(ModelConstants.RELATION_BY_TYPE_AND_CHILD_TYPE_VIEW_NAME,
230 Arrays.asList(eq(ModelConstants.RELATION_FROM_ID_PROPERTY, from.getId()), 231 Arrays.asList(eq(ModelConstants.RELATION_FROM_ID_PROPERTY, from.getId()),
231 eq(ModelConstants.RELATION_FROM_TYPE_PROPERTY, from.getEntityType().name()), 232 eq(ModelConstants.RELATION_FROM_TYPE_PROPERTY, from.getEntityType().name()),
@@ -241,7 +242,7 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati @@ -241,7 +242,7 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati
241 QueryBuilder.asc(ModelConstants.RELATION_TO_TYPE_PROPERTY) 242 QueryBuilder.asc(ModelConstants.RELATION_TO_TYPE_PROPERTY)
242 ), 243 ),
243 pageLink, ModelConstants.RELATION_TO_ID_PROPERTY); 244 pageLink, ModelConstants.RELATION_TO_ID_PROPERTY);
244 - return getFuture(executeAsyncRead(query), this::getEntityRelations); 245 + return getFuture(executeAsyncRead(tenantId, query), this::getEntityRelations);
245 } 246 }
246 247
247 private PreparedStatement getSaveStmt() { 248 private PreparedStatement getSaveStmt() {
@@ -347,9 +348,9 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati @@ -347,9 +348,9 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati
347 return EntityIdFactory.getByTypeAndUuid(row.getString(typeColumn), row.getUUID(uuidColumn)); 348 return EntityIdFactory.getByTypeAndUuid(row.getString(typeColumn), row.getUUID(uuidColumn));
348 } 349 }
349 350
350 - private ListenableFuture<List<EntityRelation>> executeAsyncRead(EntityId from, BoundStatement stmt) { 351 + private ListenableFuture<List<EntityRelation>> executeAsyncRead(TenantId tenantId, EntityId from, BoundStatement stmt) {
351 log.debug("Generated query [{}] for entity {}", stmt, from); 352 log.debug("Generated query [{}] for entity {}", stmt, from);
352 - return getFuture(executeAsyncRead(stmt), rs -> getEntityRelations(rs)); 353 + return getFuture(executeAsyncRead(tenantId, stmt), rs -> getEntityRelations(rs));
353 } 354 }
354 355
355 private ListenableFuture<Boolean> getBooleanListenableFuture(ResultSetFuture rsFuture) { 356 private ListenableFuture<Boolean> getBooleanListenableFuture(ResultSetFuture rsFuture) {
@@ -26,7 +26,9 @@ import org.springframework.cache.annotation.Cacheable; @@ -26,7 +26,9 @@ import org.springframework.cache.annotation.Cacheable;
26 import org.springframework.cache.annotation.Caching; 26 import org.springframework.cache.annotation.Caching;
27 import org.springframework.stereotype.Service; 27 import org.springframework.stereotype.Service;
28 import org.springframework.util.StringUtils; 28 import org.springframework.util.StringUtils;
  29 +import org.thingsboard.server.common.data.Tenant;
29 import org.thingsboard.server.common.data.id.EntityId; 30 import org.thingsboard.server.common.data.id.EntityId;
  31 +import org.thingsboard.server.common.data.id.TenantId;
30 import org.thingsboard.server.common.data.relation.EntityRelation; 32 import org.thingsboard.server.common.data.relation.EntityRelation;
31 import org.thingsboard.server.common.data.relation.EntityRelationInfo; 33 import org.thingsboard.server.common.data.relation.EntityRelationInfo;
32 import org.thingsboard.server.common.data.relation.EntityRelationsQuery; 34 import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
@@ -66,27 +68,27 @@ public class BaseRelationService implements RelationService { @@ -66,27 +68,27 @@ public class BaseRelationService implements RelationService {
66 private CacheManager cacheManager; 68 private CacheManager cacheManager;
67 69
68 @Override 70 @Override
69 - public ListenableFuture<Boolean> checkRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { 71 + public ListenableFuture<Boolean> checkRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
70 log.trace("Executing checkRelation [{}][{}][{}][{}]", from, to, relationType, typeGroup); 72 log.trace("Executing checkRelation [{}][{}][{}][{}]", from, to, relationType, typeGroup);
71 validate(from, to, relationType, typeGroup); 73 validate(from, to, relationType, typeGroup);
72 - return relationDao.checkRelation(from, to, relationType, typeGroup); 74 + return relationDao.checkRelation(tenantId, from, to, relationType, typeGroup);
73 } 75 }
74 76
75 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #to, #relationType, #typeGroup}") 77 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #to, #relationType, #typeGroup}")
76 @Override 78 @Override
77 - public EntityRelation getRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { 79 + public EntityRelation getRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
78 try { 80 try {
79 - return getRelationAsync(from, to, relationType, typeGroup).get(); 81 + return getRelationAsync(tenantId, from, to, relationType, typeGroup).get();
80 } catch (InterruptedException | ExecutionException e) { 82 } catch (InterruptedException | ExecutionException e) {
81 throw new RuntimeException(e); 83 throw new RuntimeException(e);
82 } 84 }
83 } 85 }
84 86
85 @Override 87 @Override
86 - public ListenableFuture<EntityRelation> getRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { 88 + public ListenableFuture<EntityRelation> getRelationAsync(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
87 log.trace("Executing EntityRelation [{}][{}][{}][{}]", from, to, relationType, typeGroup); 89 log.trace("Executing EntityRelation [{}][{}][{}][{}]", from, to, relationType, typeGroup);
88 validate(from, to, relationType, typeGroup); 90 validate(from, to, relationType, typeGroup);
89 - return relationDao.getRelation(from, to, relationType, typeGroup); 91 + return relationDao.getRelation(tenantId, from, to, relationType, typeGroup);
90 } 92 }
91 93
92 @Caching(evict = { 94 @Caching(evict = {
@@ -97,10 +99,10 @@ public class BaseRelationService implements RelationService { @@ -97,10 +99,10 @@ public class BaseRelationService implements RelationService {
97 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#relation.to, #relation.type, #relation.typeGroup, 'TO'}") 99 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#relation.to, #relation.type, #relation.typeGroup, 'TO'}")
98 }) 100 })
99 @Override 101 @Override
100 - public boolean saveRelation(EntityRelation relation) { 102 + public boolean saveRelation(TenantId tenantId, EntityRelation relation) {
101 log.trace("Executing saveRelation [{}]", relation); 103 log.trace("Executing saveRelation [{}]", relation);
102 validate(relation); 104 validate(relation);
103 - return relationDao.saveRelation(relation); 105 + return relationDao.saveRelation(tenantId, relation);
104 } 106 }
105 107
106 @Caching(evict = { 108 @Caching(evict = {
@@ -111,10 +113,10 @@ public class BaseRelationService implements RelationService { @@ -111,10 +113,10 @@ public class BaseRelationService implements RelationService {
111 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#relation.to, #relation.type, #relation.typeGroup, 'TO'}") 113 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#relation.to, #relation.type, #relation.typeGroup, 'TO'}")
112 }) 114 })
113 @Override 115 @Override
114 - public ListenableFuture<Boolean> saveRelationAsync(EntityRelation relation) { 116 + public ListenableFuture<Boolean> saveRelationAsync(TenantId tenantId, EntityRelation relation) {
115 log.trace("Executing saveRelationAsync [{}]", relation); 117 log.trace("Executing saveRelationAsync [{}]", relation);
116 validate(relation); 118 validate(relation);
117 - return relationDao.saveRelationAsync(relation); 119 + return relationDao.saveRelationAsync(tenantId, relation);
118 } 120 }
119 121
120 @Caching(evict = { 122 @Caching(evict = {
@@ -125,10 +127,10 @@ public class BaseRelationService implements RelationService { @@ -125,10 +127,10 @@ public class BaseRelationService implements RelationService {
125 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#relation.to, #relation.type, #relation.typeGroup, 'TO'}") 127 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#relation.to, #relation.type, #relation.typeGroup, 'TO'}")
126 }) 128 })
127 @Override 129 @Override
128 - public boolean deleteRelation(EntityRelation relation) { 130 + public boolean deleteRelation(TenantId tenantId, EntityRelation relation) {
129 log.trace("Executing deleteRelation [{}]", relation); 131 log.trace("Executing deleteRelation [{}]", relation);
130 validate(relation); 132 validate(relation);
131 - return relationDao.deleteRelation(relation); 133 + return relationDao.deleteRelation(tenantId, relation);
132 } 134 }
133 135
134 @Caching(evict = { 136 @Caching(evict = {
@@ -139,10 +141,10 @@ public class BaseRelationService implements RelationService { @@ -139,10 +141,10 @@ public class BaseRelationService implements RelationService {
139 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#relation.to, #relation.type, #relation.typeGroup, 'TO'}") 141 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#relation.to, #relation.type, #relation.typeGroup, 'TO'}")
140 }) 142 })
141 @Override 143 @Override
142 - public ListenableFuture<Boolean> deleteRelationAsync(EntityRelation relation) { 144 + public ListenableFuture<Boolean> deleteRelationAsync(TenantId tenantId, EntityRelation relation) {
143 log.trace("Executing deleteRelationAsync [{}]", relation); 145 log.trace("Executing deleteRelationAsync [{}]", relation);
144 validate(relation); 146 validate(relation);
145 - return relationDao.deleteRelationAsync(relation); 147 + return relationDao.deleteRelationAsync(tenantId, relation);
146 } 148 }
147 149
148 @Caching(evict = { 150 @Caching(evict = {
@@ -153,10 +155,10 @@ public class BaseRelationService implements RelationService { @@ -153,10 +155,10 @@ public class BaseRelationService implements RelationService {
153 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}") 155 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}")
154 }) 156 })
155 @Override 157 @Override
156 - public boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { 158 + public boolean deleteRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
157 log.trace("Executing deleteRelation [{}][{}][{}][{}]", from, to, relationType, typeGroup); 159 log.trace("Executing deleteRelation [{}][{}][{}][{}]", from, to, relationType, typeGroup);
158 validate(from, to, relationType, typeGroup); 160 validate(from, to, relationType, typeGroup);
159 - return relationDao.deleteRelation(from, to, relationType, typeGroup); 161 + return relationDao.deleteRelation(tenantId, from, to, relationType, typeGroup);
160 } 162 }
161 163
162 @Caching(evict = { 164 @Caching(evict = {
@@ -167,69 +169,69 @@ public class BaseRelationService implements RelationService { @@ -167,69 +169,69 @@ public class BaseRelationService implements RelationService {
167 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}") 169 @CacheEvict(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}")
168 }) 170 })
169 @Override 171 @Override
170 - public ListenableFuture<Boolean> deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { 172 + public ListenableFuture<Boolean> deleteRelationAsync(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) {
171 log.trace("Executing deleteRelationAsync [{}][{}][{}][{}]", from, to, relationType, typeGroup); 173 log.trace("Executing deleteRelationAsync [{}][{}][{}][{}]", from, to, relationType, typeGroup);
172 validate(from, to, relationType, typeGroup); 174 validate(from, to, relationType, typeGroup);
173 - return relationDao.deleteRelationAsync(from, to, relationType, typeGroup); 175 + return relationDao.deleteRelationAsync(tenantId, from, to, relationType, typeGroup);
174 } 176 }
175 177
176 @Override 178 @Override
177 - public void deleteEntityRelations(EntityId entityId) { 179 + public void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
178 try { 180 try {
179 - deleteEntityRelationsAsync(entityId).get(); 181 + deleteEntityRelationsAsync(tenantId, entityId).get();
180 } catch (InterruptedException | ExecutionException e) { 182 } catch (InterruptedException | ExecutionException e) {
181 throw new RuntimeException(e); 183 throw new RuntimeException(e);
182 } 184 }
183 } 185 }
184 186
185 @Override 187 @Override
186 - public ListenableFuture<Void> deleteEntityRelationsAsync(EntityId entityId) { 188 + public ListenableFuture<Void> deleteEntityRelationsAsync(TenantId tenantId, EntityId entityId) {
187 Cache cache = cacheManager.getCache(RELATIONS_CACHE); 189 Cache cache = cacheManager.getCache(RELATIONS_CACHE);
188 log.trace("Executing deleteEntityRelationsAsync [{}]", entityId); 190 log.trace("Executing deleteEntityRelationsAsync [{}]", entityId);
189 validate(entityId); 191 validate(entityId);
190 List<ListenableFuture<List<EntityRelation>>> inboundRelationsList = new ArrayList<>(); 192 List<ListenableFuture<List<EntityRelation>>> inboundRelationsList = new ArrayList<>();
191 for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) { 193 for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
192 - inboundRelationsList.add(relationDao.findAllByTo(entityId, typeGroup)); 194 + inboundRelationsList.add(relationDao.findAllByTo(tenantId, entityId, typeGroup));
193 } 195 }
194 196
195 ListenableFuture<List<List<EntityRelation>>> inboundRelations = Futures.allAsList(inboundRelationsList); 197 ListenableFuture<List<List<EntityRelation>>> inboundRelations = Futures.allAsList(inboundRelationsList);
196 198
197 List<ListenableFuture<List<EntityRelation>>> outboundRelationsList = new ArrayList<>(); 199 List<ListenableFuture<List<EntityRelation>>> outboundRelationsList = new ArrayList<>();
198 for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) { 200 for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) {
199 - outboundRelationsList.add(relationDao.findAllByFrom(entityId, typeGroup)); 201 + outboundRelationsList.add(relationDao.findAllByFrom(tenantId, entityId, typeGroup));
200 } 202 }
201 203
202 ListenableFuture<List<List<EntityRelation>>> outboundRelations = Futures.allAsList(outboundRelationsList); 204 ListenableFuture<List<List<EntityRelation>>> outboundRelations = Futures.allAsList(outboundRelationsList);
203 205
204 ListenableFuture<List<Boolean>> inboundDeletions = Futures.transformAsync(inboundRelations, 206 ListenableFuture<List<Boolean>> inboundDeletions = Futures.transformAsync(inboundRelations,
205 relations -> { 207 relations -> {
206 - List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(relations, cache, true); 208 + List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, cache, true);
207 return Futures.allAsList(results); 209 return Futures.allAsList(results);
208 }); 210 });
209 211
210 ListenableFuture<List<Boolean>> outboundDeletions = Futures.transformAsync(outboundRelations, 212 ListenableFuture<List<Boolean>> outboundDeletions = Futures.transformAsync(outboundRelations,
211 relations -> { 213 relations -> {
212 - List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(relations, cache, false); 214 + List<ListenableFuture<Boolean>> results = deleteRelationGroupsAsync(tenantId, relations, cache, false);
213 return Futures.allAsList(results); 215 return Futures.allAsList(results);
214 }); 216 });
215 217
216 ListenableFuture<List<List<Boolean>>> deletionsFuture = Futures.allAsList(inboundDeletions, outboundDeletions); 218 ListenableFuture<List<List<Boolean>>> deletionsFuture = Futures.allAsList(inboundDeletions, outboundDeletions);
217 219
218 - return Futures.transform(Futures.transformAsync(deletionsFuture, (deletions) -> relationDao.deleteOutboundRelationsAsync(entityId)), result -> null); 220 + return Futures.transform(Futures.transformAsync(deletionsFuture, (deletions) -> relationDao.deleteOutboundRelationsAsync(tenantId, entityId)), result -> null);
219 } 221 }
220 222
221 - private List<ListenableFuture<Boolean>> deleteRelationGroupsAsync(List<List<EntityRelation>> relations, Cache cache, boolean deleteFromDb) { 223 + private List<ListenableFuture<Boolean>> deleteRelationGroupsAsync(TenantId tenantId, List<List<EntityRelation>> relations, Cache cache, boolean deleteFromDb) {
222 List<ListenableFuture<Boolean>> results = new ArrayList<>(); 224 List<ListenableFuture<Boolean>> results = new ArrayList<>();
223 for (List<EntityRelation> relationList : relations) { 225 for (List<EntityRelation> relationList : relations) {
224 - relationList.forEach(relation -> results.add(deleteAsync(cache, relation, deleteFromDb))); 226 + relationList.forEach(relation -> results.add(deleteAsync(tenantId, cache, relation, deleteFromDb)));
225 } 227 }
226 return results; 228 return results;
227 } 229 }
228 230
229 - private ListenableFuture<Boolean> deleteAsync(Cache cache, EntityRelation relation, boolean deleteFromDb) { 231 + private ListenableFuture<Boolean> deleteAsync(TenantId tenantId, Cache cache, EntityRelation relation, boolean deleteFromDb) {
230 cacheEviction(relation, cache); 232 cacheEviction(relation, cache);
231 if (deleteFromDb) { 233 if (deleteFromDb) {
232 - return relationDao.deleteRelationAsync(relation); 234 + return relationDao.deleteRelationAsync(tenantId, relation);
233 } else { 235 } else {
234 return Futures.immediateFuture(false); 236 return Futures.immediateFuture(false);
235 } 237 }
@@ -272,18 +274,18 @@ public class BaseRelationService implements RelationService { @@ -272,18 +274,18 @@ public class BaseRelationService implements RelationService {
272 274
273 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #typeGroup, 'FROM'}") 275 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #typeGroup, 'FROM'}")
274 @Override 276 @Override
275 - public List<EntityRelation> findByFrom(EntityId from, RelationTypeGroup typeGroup) { 277 + public List<EntityRelation> findByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup) {
276 validate(from); 278 validate(from);
277 validateTypeGroup(typeGroup); 279 validateTypeGroup(typeGroup);
278 try { 280 try {
279 - return relationDao.findAllByFrom(from, typeGroup).get(); 281 + return relationDao.findAllByFrom(tenantId, from, typeGroup).get();
280 } catch (InterruptedException | ExecutionException e) { 282 } catch (InterruptedException | ExecutionException e) {
281 throw new RuntimeException(e); 283 throw new RuntimeException(e);
282 } 284 }
283 } 285 }
284 286
285 @Override 287 @Override
286 - public ListenableFuture<List<EntityRelation>> findByFromAsync(EntityId from, RelationTypeGroup typeGroup) { 288 + public ListenableFuture<List<EntityRelation>> findByFromAsync(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup) {
287 log.trace("Executing findByFrom [{}][{}]", from, typeGroup); 289 log.trace("Executing findByFrom [{}][{}]", from, typeGroup);
288 validate(from); 290 validate(from);
289 validateTypeGroup(typeGroup); 291 validateTypeGroup(typeGroup);
@@ -298,7 +300,7 @@ public class BaseRelationService implements RelationService { @@ -298,7 +300,7 @@ public class BaseRelationService implements RelationService {
298 if (fromCache != null) { 300 if (fromCache != null) {
299 return Futures.immediateFuture(fromCache); 301 return Futures.immediateFuture(fromCache);
300 } else { 302 } else {
301 - ListenableFuture<List<EntityRelation>> relationsFuture = relationDao.findAllByFrom(from, typeGroup); 303 + ListenableFuture<List<EntityRelation>> relationsFuture = relationDao.findAllByFrom(tenantId, from, typeGroup);
302 Futures.addCallback(relationsFuture, 304 Futures.addCallback(relationsFuture,
303 new FutureCallback<List<EntityRelation>>() { 305 new FutureCallback<List<EntityRelation>>() {
304 @Override 306 @Override
@@ -313,16 +315,16 @@ public class BaseRelationService implements RelationService { @@ -313,16 +315,16 @@ public class BaseRelationService implements RelationService {
313 } 315 }
314 316
315 @Override 317 @Override
316 - public ListenableFuture<List<EntityRelationInfo>> findInfoByFrom(EntityId from, RelationTypeGroup typeGroup) { 318 + public ListenableFuture<List<EntityRelationInfo>> findInfoByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup) {
317 log.trace("Executing findInfoByFrom [{}][{}]", from, typeGroup); 319 log.trace("Executing findInfoByFrom [{}][{}]", from, typeGroup);
318 validate(from); 320 validate(from);
319 validateTypeGroup(typeGroup); 321 validateTypeGroup(typeGroup);
320 - ListenableFuture<List<EntityRelation>> relations = relationDao.findAllByFrom(from, typeGroup); 322 + ListenableFuture<List<EntityRelation>> relations = relationDao.findAllByFrom(tenantId, from, typeGroup);
321 return Futures.transformAsync(relations, 323 return Futures.transformAsync(relations,
322 relations1 -> { 324 relations1 -> {
323 List<ListenableFuture<EntityRelationInfo>> futures = new ArrayList<>(); 325 List<ListenableFuture<EntityRelationInfo>> futures = new ArrayList<>();
324 relations1.forEach(relation -> 326 relations1.forEach(relation ->
325 - futures.add(fetchRelationInfoAsync(relation, 327 + futures.add(fetchRelationInfoAsync(tenantId, relation,
326 EntityRelation::getTo, 328 EntityRelation::getTo,
327 EntityRelationInfo::setToName)) 329 EntityRelationInfo::setToName))
328 ); 330 );
@@ -332,37 +334,37 @@ public class BaseRelationService implements RelationService { @@ -332,37 +334,37 @@ public class BaseRelationService implements RelationService {
332 334
333 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #relationType, #typeGroup, 'FROM'}") 335 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #relationType, #typeGroup, 'FROM'}")
334 @Override 336 @Override
335 - public List<EntityRelation> findByFromAndType(EntityId from, String relationType, RelationTypeGroup typeGroup) { 337 + public List<EntityRelation> findByFromAndType(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup) {
336 try { 338 try {
337 - return findByFromAndTypeAsync(from, relationType, typeGroup).get(); 339 + return findByFromAndTypeAsync(tenantId, from, relationType, typeGroup).get();
338 } catch (InterruptedException | ExecutionException e) { 340 } catch (InterruptedException | ExecutionException e) {
339 throw new RuntimeException(e); 341 throw new RuntimeException(e);
340 } 342 }
341 } 343 }
342 344
343 @Override 345 @Override
344 - public ListenableFuture<List<EntityRelation>> findByFromAndTypeAsync(EntityId from, String relationType, RelationTypeGroup typeGroup) { 346 + public ListenableFuture<List<EntityRelation>> findByFromAndTypeAsync(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup) {
345 log.trace("Executing findByFromAndType [{}][{}][{}]", from, relationType, typeGroup); 347 log.trace("Executing findByFromAndType [{}][{}][{}]", from, relationType, typeGroup);
346 validate(from); 348 validate(from);
347 validateType(relationType); 349 validateType(relationType);
348 validateTypeGroup(typeGroup); 350 validateTypeGroup(typeGroup);
349 - return relationDao.findAllByFromAndType(from, relationType, typeGroup); 351 + return relationDao.findAllByFromAndType(tenantId, from, relationType, typeGroup);
350 } 352 }
351 353
352 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#to, #typeGroup, 'TO'}") 354 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#to, #typeGroup, 'TO'}")
353 @Override 355 @Override
354 - public List<EntityRelation> findByTo(EntityId to, RelationTypeGroup typeGroup) { 356 + public List<EntityRelation> findByTo(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup) {
355 validate(to); 357 validate(to);
356 validateTypeGroup(typeGroup); 358 validateTypeGroup(typeGroup);
357 try { 359 try {
358 - return relationDao.findAllByTo(to, typeGroup).get(); 360 + return relationDao.findAllByTo(tenantId, to, typeGroup).get();
359 } catch (InterruptedException | ExecutionException e) { 361 } catch (InterruptedException | ExecutionException e) {
360 throw new RuntimeException(e); 362 throw new RuntimeException(e);
361 } 363 }
362 } 364 }
363 365
364 @Override 366 @Override
365 - public ListenableFuture<List<EntityRelation>> findByToAsync(EntityId to, RelationTypeGroup typeGroup) { 367 + public ListenableFuture<List<EntityRelation>> findByToAsync(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup) {
366 log.trace("Executing findByTo [{}][{}]", to, typeGroup); 368 log.trace("Executing findByTo [{}][{}]", to, typeGroup);
367 validate(to); 369 validate(to);
368 validateTypeGroup(typeGroup); 370 validateTypeGroup(typeGroup);
@@ -377,7 +379,7 @@ public class BaseRelationService implements RelationService { @@ -377,7 +379,7 @@ public class BaseRelationService implements RelationService {
377 if (fromCache != null) { 379 if (fromCache != null) {
378 return Futures.immediateFuture(fromCache); 380 return Futures.immediateFuture(fromCache);
379 } else { 381 } else {
380 - ListenableFuture<List<EntityRelation>> relationsFuture = relationDao.findAllByTo(to, typeGroup); 382 + ListenableFuture<List<EntityRelation>> relationsFuture = relationDao.findAllByTo(tenantId, to, typeGroup);
381 Futures.addCallback(relationsFuture, 383 Futures.addCallback(relationsFuture,
382 new FutureCallback<List<EntityRelation>>() { 384 new FutureCallback<List<EntityRelation>>() {
383 @Override 385 @Override
@@ -392,16 +394,16 @@ public class BaseRelationService implements RelationService { @@ -392,16 +394,16 @@ public class BaseRelationService implements RelationService {
392 } 394 }
393 395
394 @Override 396 @Override
395 - public ListenableFuture<List<EntityRelationInfo>> findInfoByTo(EntityId to, RelationTypeGroup typeGroup) { 397 + public ListenableFuture<List<EntityRelationInfo>> findInfoByTo(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup) {
396 log.trace("Executing findInfoByTo [{}][{}]", to, typeGroup); 398 log.trace("Executing findInfoByTo [{}][{}]", to, typeGroup);
397 validate(to); 399 validate(to);
398 validateTypeGroup(typeGroup); 400 validateTypeGroup(typeGroup);
399 - ListenableFuture<List<EntityRelation>> relations = relationDao.findAllByTo(to, typeGroup); 401 + ListenableFuture<List<EntityRelation>> relations = relationDao.findAllByTo(tenantId, to, typeGroup);
400 return Futures.transformAsync(relations, 402 return Futures.transformAsync(relations,
401 relations1 -> { 403 relations1 -> {
402 List<ListenableFuture<EntityRelationInfo>> futures = new ArrayList<>(); 404 List<ListenableFuture<EntityRelationInfo>> futures = new ArrayList<>();
403 relations1.forEach(relation -> 405 relations1.forEach(relation ->
404 - futures.add(fetchRelationInfoAsync(relation, 406 + futures.add(fetchRelationInfoAsync(tenantId, relation,
405 EntityRelation::getFrom, 407 EntityRelation::getFrom,
406 EntityRelationInfo::setFromName)) 408 EntityRelationInfo::setFromName))
407 ); 409 );
@@ -409,10 +411,10 @@ public class BaseRelationService implements RelationService { @@ -409,10 +411,10 @@ public class BaseRelationService implements RelationService {
409 }); 411 });
410 } 412 }
411 413
412 - private ListenableFuture<EntityRelationInfo> fetchRelationInfoAsync(EntityRelation relation, 414 + private ListenableFuture<EntityRelationInfo> fetchRelationInfoAsync(TenantId tenantId, EntityRelation relation,
413 Function<EntityRelation, EntityId> entityIdGetter, 415 Function<EntityRelation, EntityId> entityIdGetter,
414 BiConsumer<EntityRelationInfo, String> entityNameSetter) { 416 BiConsumer<EntityRelationInfo, String> entityNameSetter) {
415 - ListenableFuture<String> entityName = entityService.fetchEntityNameAsync(entityIdGetter.apply(relation)); 417 + ListenableFuture<String> entityName = entityService.fetchEntityNameAsync(tenantId, entityIdGetter.apply(relation));
416 return Futures.transform(entityName, entityName1 -> { 418 return Futures.transform(entityName, entityName1 -> {
417 EntityRelationInfo entityRelationInfo1 = new EntityRelationInfo(relation); 419 EntityRelationInfo entityRelationInfo1 = new EntityRelationInfo(relation);
418 entityNameSetter.accept(entityRelationInfo1, entityName1); 420 entityNameSetter.accept(entityRelationInfo1, entityName1);
@@ -422,25 +424,25 @@ public class BaseRelationService implements RelationService { @@ -422,25 +424,25 @@ public class BaseRelationService implements RelationService {
422 424
423 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}") 425 @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#to, #relationType, #typeGroup, 'TO'}")
424 @Override 426 @Override
425 - public List<EntityRelation> findByToAndType(EntityId to, String relationType, RelationTypeGroup typeGroup) { 427 + public List<EntityRelation> findByToAndType(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup) {
426 try { 428 try {
427 - return findByToAndTypeAsync(to, relationType, typeGroup).get(); 429 + return findByToAndTypeAsync(tenantId, to, relationType, typeGroup).get();
428 } catch (InterruptedException | ExecutionException e) { 430 } catch (InterruptedException | ExecutionException e) {
429 throw new RuntimeException(e); 431 throw new RuntimeException(e);
430 } 432 }
431 } 433 }
432 434
433 @Override 435 @Override
434 - public ListenableFuture<List<EntityRelation>> findByToAndTypeAsync(EntityId to, String relationType, RelationTypeGroup typeGroup) { 436 + public ListenableFuture<List<EntityRelation>> findByToAndTypeAsync(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup) {
435 log.trace("Executing findByToAndType [{}][{}][{}]", to, relationType, typeGroup); 437 log.trace("Executing findByToAndType [{}][{}][{}]", to, relationType, typeGroup);
436 validate(to); 438 validate(to);
437 validateType(relationType); 439 validateType(relationType);
438 validateTypeGroup(typeGroup); 440 validateTypeGroup(typeGroup);
439 - return relationDao.findAllByToAndType(to, relationType, typeGroup); 441 + return relationDao.findAllByToAndType(tenantId, to, relationType, typeGroup);
440 } 442 }
441 443
442 @Override 444 @Override
443 - public ListenableFuture<List<EntityRelation>> findByQuery(EntityRelationsQuery query) { 445 + public ListenableFuture<List<EntityRelation>> findByQuery(TenantId tenantId, EntityRelationsQuery query) {
444 log.trace("Executing findByQuery [{}]", query); 446 log.trace("Executing findByQuery [{}]", query);
445 RelationsSearchParameters params = query.getParameters(); 447 RelationsSearchParameters params = query.getParameters();
446 final List<EntityTypeFilter> filters = query.getFilters(); 448 final List<EntityTypeFilter> filters = query.getFilters();
@@ -451,7 +453,7 @@ public class BaseRelationService implements RelationService { @@ -451,7 +453,7 @@ public class BaseRelationService implements RelationService {
451 int maxLvl = params.getMaxLevel() > 0 ? params.getMaxLevel() : Integer.MAX_VALUE; 453 int maxLvl = params.getMaxLevel() > 0 ? params.getMaxLevel() : Integer.MAX_VALUE;
452 454
453 try { 455 try {
454 - ListenableFuture<Set<EntityRelation>> relationSet = findRelationsRecursively(params.getEntityId(), params.getDirection(), params.getRelationTypeGroup(), maxLvl, new ConcurrentHashMap<>()); 456 + ListenableFuture<Set<EntityRelation>> relationSet = findRelationsRecursively(tenantId, params.getEntityId(), params.getDirection(), params.getRelationTypeGroup(), maxLvl, new ConcurrentHashMap<>());
455 return Futures.transform(relationSet, input -> { 457 return Futures.transform(relationSet, input -> {
456 List<EntityRelation> relations = new ArrayList<>(); 458 List<EntityRelation> relations = new ArrayList<>();
457 if (filters == null || filters.isEmpty()) { 459 if (filters == null || filters.isEmpty()) {
@@ -472,15 +474,15 @@ public class BaseRelationService implements RelationService { @@ -472,15 +474,15 @@ public class BaseRelationService implements RelationService {
472 } 474 }
473 475
474 @Override 476 @Override
475 - public ListenableFuture<List<EntityRelationInfo>> findInfoByQuery(EntityRelationsQuery query) { 477 + public ListenableFuture<List<EntityRelationInfo>> findInfoByQuery(TenantId tenantId, EntityRelationsQuery query) {
476 log.trace("Executing findInfoByQuery [{}]", query); 478 log.trace("Executing findInfoByQuery [{}]", query);
477 - ListenableFuture<List<EntityRelation>> relations = findByQuery(query); 479 + ListenableFuture<List<EntityRelation>> relations = findByQuery(tenantId, query);
478 EntitySearchDirection direction = query.getParameters().getDirection(); 480 EntitySearchDirection direction = query.getParameters().getDirection();
479 return Futures.transformAsync(relations, 481 return Futures.transformAsync(relations,
480 relations1 -> { 482 relations1 -> {
481 List<ListenableFuture<EntityRelationInfo>> futures = new ArrayList<>(); 483 List<ListenableFuture<EntityRelationInfo>> futures = new ArrayList<>();
482 relations1.forEach(relation -> 484 relations1.forEach(relation ->
483 - futures.add(fetchRelationInfoAsync(relation, 485 + futures.add(fetchRelationInfoAsync(tenantId, relation,
484 relation2 -> direction == EntitySearchDirection.FROM ? relation2.getTo() : relation2.getFrom(), 486 relation2 -> direction == EntitySearchDirection.FROM ? relation2.getTo() : relation2.getFrom(),
485 (EntityRelationInfo relationInfo, String entityName) -> { 487 (EntityRelationInfo relationInfo, String entityName) -> {
486 if (direction == EntitySearchDirection.FROM) { 488 if (direction == EntitySearchDirection.FROM) {
@@ -567,7 +569,7 @@ public class BaseRelationService implements RelationService { @@ -567,7 +569,7 @@ public class BaseRelationService implements RelationService {
567 } 569 }
568 } 570 }
569 571
570 - private ListenableFuture<Set<EntityRelation>> findRelationsRecursively(final EntityId rootId, final EntitySearchDirection direction, 572 + private ListenableFuture<Set<EntityRelation>> findRelationsRecursively(final TenantId tenantId, final EntityId rootId, final EntitySearchDirection direction,
571 RelationTypeGroup relationTypeGroup, int lvl, 573 RelationTypeGroup relationTypeGroup, int lvl,
572 final ConcurrentHashMap<EntityId, Boolean> uniqueMap) throws Exception { 574 final ConcurrentHashMap<EntityId, Boolean> uniqueMap) throws Exception {
573 if (lvl == 0) { 575 if (lvl == 0) {
@@ -575,7 +577,7 @@ public class BaseRelationService implements RelationService { @@ -575,7 +577,7 @@ public class BaseRelationService implements RelationService {
575 } 577 }
576 lvl--; 578 lvl--;
577 //TODO: try to remove this blocking operation 579 //TODO: try to remove this blocking operation
578 - Set<EntityRelation> children = new HashSet<>(findRelations(rootId, direction, relationTypeGroup).get()); 580 + Set<EntityRelation> children = new HashSet<>(findRelations(tenantId, rootId, direction, relationTypeGroup).get());
579 Set<EntityId> childrenIds = new HashSet<>(); 581 Set<EntityId> childrenIds = new HashSet<>();
580 for (EntityRelation childRelation : children) { 582 for (EntityRelation childRelation : children) {
581 log.trace("Found Relation: {}", childRelation); 583 log.trace("Found Relation: {}", childRelation);
@@ -594,7 +596,7 @@ public class BaseRelationService implements RelationService { @@ -594,7 +596,7 @@ public class BaseRelationService implements RelationService {
594 } 596 }
595 List<ListenableFuture<Set<EntityRelation>>> futures = new ArrayList<>(); 597 List<ListenableFuture<Set<EntityRelation>>> futures = new ArrayList<>();
596 for (EntityId entityId : childrenIds) { 598 for (EntityId entityId : childrenIds) {
597 - futures.add(findRelationsRecursively(entityId, direction, relationTypeGroup, lvl, uniqueMap)); 599 + futures.add(findRelationsRecursively(tenantId, entityId, direction, relationTypeGroup, lvl, uniqueMap));
598 } 600 }
599 //TODO: try to remove this blocking operation 601 //TODO: try to remove this blocking operation
600 List<Set<EntityRelation>> relations = Futures.successfulAsList(futures).get(); 602 List<Set<EntityRelation>> relations = Futures.successfulAsList(futures).get();
@@ -602,15 +604,15 @@ public class BaseRelationService implements RelationService { @@ -602,15 +604,15 @@ public class BaseRelationService implements RelationService {
602 return Futures.immediateFuture(children); 604 return Futures.immediateFuture(children);
603 } 605 }
604 606
605 - private ListenableFuture<List<EntityRelation>> findRelations(final EntityId rootId, final EntitySearchDirection direction, RelationTypeGroup relationTypeGroup) { 607 + private ListenableFuture<List<EntityRelation>> findRelations(final TenantId tenantId, final EntityId rootId, final EntitySearchDirection direction, RelationTypeGroup relationTypeGroup) {
606 ListenableFuture<List<EntityRelation>> relations; 608 ListenableFuture<List<EntityRelation>> relations;
607 if (relationTypeGroup == null) { 609 if (relationTypeGroup == null) {
608 relationTypeGroup = RelationTypeGroup.COMMON; 610 relationTypeGroup = RelationTypeGroup.COMMON;
609 } 611 }
610 if (direction == EntitySearchDirection.FROM) { 612 if (direction == EntitySearchDirection.FROM) {
611 - relations = findByFromAsync(rootId, relationTypeGroup); 613 + relations = findByFromAsync(tenantId, rootId, relationTypeGroup);
612 } else { 614 } else {
613 - relations = findByToAsync(rootId, relationTypeGroup); 615 + relations = findByToAsync(tenantId, rootId, relationTypeGroup);
614 } 616 }
615 return relations; 617 return relations;
616 } 618 }
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.relation; @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.relation;
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.EntityType; 19 import org.thingsboard.server.common.data.EntityType;
20 import org.thingsboard.server.common.data.id.EntityId; 20 import org.thingsboard.server.common.data.id.EntityId;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.page.TimePageLink; 22 import org.thingsboard.server.common.data.page.TimePageLink;
22 import org.thingsboard.server.common.data.relation.EntityRelation; 23 import org.thingsboard.server.common.data.relation.EntityRelation;
23 import org.thingsboard.server.common.data.relation.RelationTypeGroup; 24 import org.thingsboard.server.common.data.relation.RelationTypeGroup;
@@ -29,34 +30,34 @@ import java.util.List; @@ -29,34 +30,34 @@ import java.util.List;
29 */ 30 */
30 public interface RelationDao { 31 public interface RelationDao {
31 32
32 - ListenableFuture<List<EntityRelation>> findAllByFrom(EntityId from, RelationTypeGroup typeGroup); 33 + ListenableFuture<List<EntityRelation>> findAllByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup);
33 34
34 - ListenableFuture<List<EntityRelation>> findAllByFromAndType(EntityId from, String relationType, RelationTypeGroup typeGroup); 35 + ListenableFuture<List<EntityRelation>> findAllByFromAndType(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup);
35 36
36 - ListenableFuture<List<EntityRelation>> findAllByTo(EntityId to, RelationTypeGroup typeGroup); 37 + ListenableFuture<List<EntityRelation>> findAllByTo(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup);
37 38
38 - ListenableFuture<List<EntityRelation>> findAllByToAndType(EntityId to, String relationType, RelationTypeGroup typeGroup); 39 + ListenableFuture<List<EntityRelation>> findAllByToAndType(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup);
39 40
40 - ListenableFuture<Boolean> checkRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 41 + ListenableFuture<Boolean> checkRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
41 42
42 - ListenableFuture<EntityRelation> getRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 43 + ListenableFuture<EntityRelation> getRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
43 44
44 - boolean saveRelation(EntityRelation relation); 45 + boolean saveRelation(TenantId tenantId, EntityRelation relation);
45 46
46 - ListenableFuture<Boolean> saveRelationAsync(EntityRelation relation); 47 + ListenableFuture<Boolean> saveRelationAsync(TenantId tenantId, EntityRelation relation);
47 48
48 - boolean deleteRelation(EntityRelation relation); 49 + boolean deleteRelation(TenantId tenantId, EntityRelation relation);
49 50
50 - ListenableFuture<Boolean> deleteRelationAsync(EntityRelation relation); 51 + ListenableFuture<Boolean> deleteRelationAsync(TenantId tenantId, EntityRelation relation);
51 52
52 - boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 53 + boolean deleteRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
53 54
54 - ListenableFuture<Boolean> deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 55 + ListenableFuture<Boolean> deleteRelationAsync(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
55 56
56 - boolean deleteOutboundRelations(EntityId entity); 57 + boolean deleteOutboundRelations(TenantId tenantId, EntityId entity);
57 58
58 - ListenableFuture<Boolean> deleteOutboundRelationsAsync(EntityId entity); 59 + ListenableFuture<Boolean> deleteOutboundRelationsAsync(TenantId tenantId, EntityId entity);
59 60
60 - ListenableFuture<List<EntityRelation>> findRelations(EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType toType, TimePageLink pageLink); 61 + ListenableFuture<List<EntityRelation>> findRelations(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType toType, TimePageLink pageLink);
61 62
62 } 63 }
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.relation; @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.relation;
17 17
18 import com.google.common.util.concurrent.ListenableFuture; 18 import com.google.common.util.concurrent.ListenableFuture;
19 import org.thingsboard.server.common.data.id.EntityId; 19 import org.thingsboard.server.common.data.id.EntityId;
  20 +import org.thingsboard.server.common.data.id.TenantId;
20 import org.thingsboard.server.common.data.relation.EntityRelation; 21 import org.thingsboard.server.common.data.relation.EntityRelation;
21 import org.thingsboard.server.common.data.relation.EntityRelationInfo; 22 import org.thingsboard.server.common.data.relation.EntityRelationInfo;
22 import org.thingsboard.server.common.data.relation.EntityRelationsQuery; 23 import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
@@ -30,51 +31,51 @@ import java.util.concurrent.ExecutionException; @@ -30,51 +31,51 @@ import java.util.concurrent.ExecutionException;
30 */ 31 */
31 public interface RelationService { 32 public interface RelationService {
32 33
33 - ListenableFuture<Boolean> checkRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 34 + ListenableFuture<Boolean> checkRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
34 35
35 - EntityRelation getRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 36 + EntityRelation getRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
36 37
37 - ListenableFuture<EntityRelation> getRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 38 + ListenableFuture<EntityRelation> getRelationAsync(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
38 39
39 - boolean saveRelation(EntityRelation relation); 40 + boolean saveRelation(TenantId tenantId, EntityRelation relation);
40 41
41 - ListenableFuture<Boolean> saveRelationAsync(EntityRelation relation); 42 + ListenableFuture<Boolean> saveRelationAsync(TenantId tenantId, EntityRelation relation);
42 43
43 - boolean deleteRelation(EntityRelation relation); 44 + boolean deleteRelation(TenantId tenantId, EntityRelation relation);
44 45
45 - ListenableFuture<Boolean> deleteRelationAsync(EntityRelation relation); 46 + ListenableFuture<Boolean> deleteRelationAsync(TenantId tenantId, EntityRelation relation);
46 47
47 - boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 48 + boolean deleteRelation(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
48 49
49 - ListenableFuture<Boolean> deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); 50 + ListenableFuture<Boolean> deleteRelationAsync(TenantId tenantId, EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup);
50 51
51 - void deleteEntityRelations(EntityId entity); 52 + void deleteEntityRelations(TenantId tenantId, EntityId entity);
52 53
53 - ListenableFuture<Void> deleteEntityRelationsAsync(EntityId entity); 54 + ListenableFuture<Void> deleteEntityRelationsAsync(TenantId tenantId, EntityId entity);
54 55
55 - List<EntityRelation> findByFrom(EntityId from, RelationTypeGroup typeGroup); 56 + List<EntityRelation> findByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup);
56 57
57 - ListenableFuture<List<EntityRelation>> findByFromAsync(EntityId from, RelationTypeGroup typeGroup); 58 + ListenableFuture<List<EntityRelation>> findByFromAsync(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup);
58 59
59 - ListenableFuture<List<EntityRelationInfo>> findInfoByFrom(EntityId from, RelationTypeGroup typeGroup); 60 + ListenableFuture<List<EntityRelationInfo>> findInfoByFrom(TenantId tenantId, EntityId from, RelationTypeGroup typeGroup);
60 61
61 - List<EntityRelation> findByFromAndType(EntityId from, String relationType, RelationTypeGroup typeGroup); 62 + List<EntityRelation> findByFromAndType(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup);
62 63
63 - ListenableFuture<List<EntityRelation>> findByFromAndTypeAsync(EntityId from, String relationType, RelationTypeGroup typeGroup); 64 + ListenableFuture<List<EntityRelation>> findByFromAndTypeAsync(TenantId tenantId, EntityId from, String relationType, RelationTypeGroup typeGroup);
64 65
65 - List<EntityRelation> findByTo(EntityId to, RelationTypeGroup typeGroup); 66 + List<EntityRelation> findByTo(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup);
66 67
67 - ListenableFuture<List<EntityRelation>> findByToAsync(EntityId to, RelationTypeGroup typeGroup); 68 + ListenableFuture<List<EntityRelation>> findByToAsync(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup);
68 69
69 - ListenableFuture<List<EntityRelationInfo>> findInfoByTo(EntityId to, RelationTypeGroup typeGroup); 70 + ListenableFuture<List<EntityRelationInfo>> findInfoByTo(TenantId tenantId, EntityId to, RelationTypeGroup typeGroup);
70 71
71 - List<EntityRelation> findByToAndType(EntityId to, String relationType, RelationTypeGroup typeGroup); 72 + List<EntityRelation> findByToAndType(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup);
72 73
73 - ListenableFuture<List<EntityRelation>> findByToAndTypeAsync(EntityId to, String relationType, RelationTypeGroup typeGroup); 74 + ListenableFuture<List<EntityRelation>> findByToAndTypeAsync(TenantId tenantId, EntityId to, String relationType, RelationTypeGroup typeGroup);
74 75
75 - ListenableFuture<List<EntityRelation>> findByQuery(EntityRelationsQuery query); 76 + ListenableFuture<List<EntityRelation>> findByQuery(TenantId tenantId, EntityRelationsQuery query);
76 77
77 - ListenableFuture<List<EntityRelationInfo>> findInfoByQuery(EntityRelationsQuery query); 78 + ListenableFuture<List<EntityRelationInfo>> findInfoByQuery(TenantId tenantId, EntityRelationsQuery query);
78 79
79 // TODO: This method may be useful for some validations in the future 80 // TODO: This method may be useful for some validations in the future
80 // ListenableFuture<Boolean> checkRecursiveRelation(EntityId from, EntityId to); 81 // ListenableFuture<Boolean> checkRecursiveRelation(EntityId from, EntityId to);
@@ -67,11 +67,11 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -67,11 +67,11 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
67 67
68 @Override 68 @Override
69 public RuleChain saveRuleChain(RuleChain ruleChain) { 69 public RuleChain saveRuleChain(RuleChain ruleChain) {
70 - ruleChainValidator.validate(ruleChain);  
71 - RuleChain savedRuleChain = ruleChainDao.save(ruleChain); 70 + ruleChainValidator.validate(ruleChain, RuleChain::getTenantId);
  71 + RuleChain savedRuleChain = ruleChainDao.save(ruleChain.getTenantId(), ruleChain);
72 if (ruleChain.isRoot() && ruleChain.getId() == null) { 72 if (ruleChain.isRoot() && ruleChain.getId() == null) {
73 try { 73 try {
74 - createRelation(new EntityRelation(savedRuleChain.getTenantId(), savedRuleChain.getId(), 74 + createRelation(ruleChain.getTenantId(), new EntityRelation(savedRuleChain.getTenantId(), savedRuleChain.getId(),
75 EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); 75 EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
76 } catch (ExecutionException | InterruptedException e) { 76 } catch (ExecutionException | InterruptedException e) {
77 log.warn("[{}] Failed to create tenant to root rule chain relation. from: [{}], to: [{}]", 77 log.warn("[{}] Failed to create tenant to root rule chain relation. from: [{}], to: [{}]",
@@ -83,20 +83,20 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -83,20 +83,20 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
83 } 83 }
84 84
85 @Override 85 @Override
86 - public boolean setRootRuleChain(RuleChainId ruleChainId) {  
87 - RuleChain ruleChain = ruleChainDao.findById(ruleChainId.getId()); 86 + public boolean setRootRuleChain(TenantId tenantId, RuleChainId ruleChainId) {
  87 + RuleChain ruleChain = ruleChainDao.findById(tenantId, ruleChainId.getId());
88 if (!ruleChain.isRoot()) { 88 if (!ruleChain.isRoot()) {
89 RuleChain previousRootRuleChain = getRootTenantRuleChain(ruleChain.getTenantId()); 89 RuleChain previousRootRuleChain = getRootTenantRuleChain(ruleChain.getTenantId());
90 if (!previousRootRuleChain.getId().equals(ruleChain.getId())) { 90 if (!previousRootRuleChain.getId().equals(ruleChain.getId())) {
91 try { 91 try {
92 - deleteRelation(new EntityRelation(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(), 92 + deleteRelation(tenantId, new EntityRelation(previousRootRuleChain.getTenantId(), previousRootRuleChain.getId(),
93 EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); 93 EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
94 previousRootRuleChain.setRoot(false); 94 previousRootRuleChain.setRoot(false);
95 - ruleChainDao.save(previousRootRuleChain);  
96 - createRelation(new EntityRelation(ruleChain.getTenantId(), ruleChain.getId(), 95 + ruleChainDao.save(tenantId, previousRootRuleChain);
  96 + createRelation(tenantId, new EntityRelation(ruleChain.getTenantId(), ruleChain.getId(),
97 EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); 97 EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
98 ruleChain.setRoot(true); 98 ruleChain.setRoot(true);
99 - ruleChainDao.save(ruleChain); 99 + ruleChainDao.save(tenantId, ruleChain);
100 return true; 100 return true;
101 } catch (ExecutionException | InterruptedException e) { 101 } catch (ExecutionException | InterruptedException e) {
102 log.warn("[{}] Failed to set root rule chain, ruleChainId: [{}]", ruleChainId); 102 log.warn("[{}] Failed to set root rule chain, ruleChainId: [{}]", ruleChainId);
@@ -108,9 +108,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -108,9 +108,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
108 } 108 }
109 109
110 @Override 110 @Override
111 - public RuleChainMetaData saveRuleChainMetaData(RuleChainMetaData ruleChainMetaData) { 111 + public RuleChainMetaData saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData) {
112 Validator.validateId(ruleChainMetaData.getRuleChainId(), "Incorrect rule chain id."); 112 Validator.validateId(ruleChainMetaData.getRuleChainId(), "Incorrect rule chain id.");
113 - RuleChain ruleChain = findRuleChainById(ruleChainMetaData.getRuleChainId()); 113 + RuleChain ruleChain = findRuleChainById(tenantId, ruleChainMetaData.getRuleChainId());
114 if (ruleChain == null) { 114 if (ruleChain == null) {
115 return null; 115 return null;
116 } 116 }
@@ -130,9 +130,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -130,9 +130,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
130 } 130 }
131 } 131 }
132 132
133 - List<RuleNode> existingRuleNodes = getRuleChainNodes(ruleChainMetaData.getRuleChainId()); 133 + List<RuleNode> existingRuleNodes = getRuleChainNodes(tenantId, ruleChainMetaData.getRuleChainId());
134 for (RuleNode existingNode : existingRuleNodes) { 134 for (RuleNode existingNode : existingRuleNodes) {
135 - deleteEntityRelations(existingNode.getId()); 135 + deleteEntityRelations(tenantId, existingNode.getId());
136 Integer index = ruleNodeIndexMap.get(existingNode.getId()); 136 Integer index = ruleNodeIndexMap.get(existingNode.getId());
137 if (index != null) { 137 if (index != null) {
138 toAddOrUpdate.add(ruleChainMetaData.getNodes().get(index)); 138 toAddOrUpdate.add(ruleChainMetaData.getNodes().get(index));
@@ -142,9 +142,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -142,9 +142,9 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
142 } 142 }
143 for (RuleNode node : toAddOrUpdate) { 143 for (RuleNode node : toAddOrUpdate) {
144 node.setRuleChainId(ruleChain.getId()); 144 node.setRuleChainId(ruleChain.getId());
145 - RuleNode savedNode = ruleNodeDao.save(node); 145 + RuleNode savedNode = ruleNodeDao.save(tenantId, node);
146 try { 146 try {
147 - createRelation(new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(), 147 + createRelation(tenantId, new EntityRelation(ruleChainMetaData.getRuleChainId(), savedNode.getId(),
148 EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN)); 148 EntityRelation.CONTAINS_TYPE, RelationTypeGroup.RULE_CHAIN));
149 } catch (ExecutionException | InterruptedException e) { 149 } catch (ExecutionException | InterruptedException e) {
150 log.warn("[{}] Failed to create rule chain to rule node relation. from: [{}], to: [{}]", 150 log.warn("[{}] Failed to create rule chain to rule node relation. from: [{}], to: [{}]",
@@ -156,7 +156,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -156,7 +156,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
156 ruleNodeIndexMap.put(savedNode.getId(), index); 156 ruleNodeIndexMap.put(savedNode.getId(), index);
157 } 157 }
158 for (RuleNode node : toDelete) { 158 for (RuleNode node : toDelete) {
159 - deleteRuleNode(node.getId()); 159 + deleteRuleNode(tenantId, node.getId());
160 } 160 }
161 RuleNodeId firstRuleNodeId = null; 161 RuleNodeId firstRuleNodeId = null;
162 if (ruleChainMetaData.getFirstNodeIndex() != null) { 162 if (ruleChainMetaData.getFirstNodeIndex() != null) {
@@ -165,7 +165,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -165,7 +165,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
165 if ((ruleChain.getFirstRuleNodeId() != null && !ruleChain.getFirstRuleNodeId().equals(firstRuleNodeId)) 165 if ((ruleChain.getFirstRuleNodeId() != null && !ruleChain.getFirstRuleNodeId().equals(firstRuleNodeId))
166 || (ruleChain.getFirstRuleNodeId() == null && firstRuleNodeId != null)) { 166 || (ruleChain.getFirstRuleNodeId() == null && firstRuleNodeId != null)) {
167 ruleChain.setFirstRuleNodeId(firstRuleNodeId); 167 ruleChain.setFirstRuleNodeId(firstRuleNodeId);
168 - ruleChainDao.save(ruleChain); 168 + ruleChainDao.save(tenantId, ruleChain);
169 } 169 }
170 if (ruleChainMetaData.getConnections() != null) { 170 if (ruleChainMetaData.getConnections() != null) {
171 for (NodeConnectionInfo nodeConnection : ruleChainMetaData.getConnections()) { 171 for (NodeConnectionInfo nodeConnection : ruleChainMetaData.getConnections()) {
@@ -173,7 +173,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -173,7 +173,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
173 EntityId to = nodes.get(nodeConnection.getToIndex()).getId(); 173 EntityId to = nodes.get(nodeConnection.getToIndex()).getId();
174 String type = nodeConnection.getType(); 174 String type = nodeConnection.getType();
175 try { 175 try {
176 - createRelation(new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE)); 176 + createRelation(tenantId, new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE));
177 } catch (ExecutionException | InterruptedException e) { 177 } catch (ExecutionException | InterruptedException e) {
178 log.warn("[{}] Failed to create rule node relation. from: [{}], to: [{}]", from, to); 178 log.warn("[{}] Failed to create rule node relation. from: [{}], to: [{}]", from, to);
179 throw new RuntimeException(e); 179 throw new RuntimeException(e);
@@ -186,7 +186,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -186,7 +186,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
186 EntityId to = nodeToRuleChainConnection.getTargetRuleChainId(); 186 EntityId to = nodeToRuleChainConnection.getTargetRuleChainId();
187 String type = nodeToRuleChainConnection.getType(); 187 String type = nodeToRuleChainConnection.getType();
188 try { 188 try {
189 - createRelation(new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE, nodeToRuleChainConnection.getAdditionalInfo())); 189 + createRelation(tenantId, new EntityRelation(from, to, type, RelationTypeGroup.RULE_NODE, nodeToRuleChainConnection.getAdditionalInfo()));
190 } catch (ExecutionException | InterruptedException e) { 190 } catch (ExecutionException | InterruptedException e) {
191 log.warn("[{}] Failed to create rule node to rule chain relation. from: [{}], to: [{}]", from, to); 191 log.warn("[{}] Failed to create rule node to rule chain relation. from: [{}], to: [{}]", from, to);
192 throw new RuntimeException(e); 192 throw new RuntimeException(e);
@@ -194,19 +194,19 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -194,19 +194,19 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
194 } 194 }
195 } 195 }
196 196
197 - return loadRuleChainMetaData(ruleChainMetaData.getRuleChainId()); 197 + return loadRuleChainMetaData(tenantId, ruleChainMetaData.getRuleChainId());
198 } 198 }
199 199
200 @Override 200 @Override
201 - public RuleChainMetaData loadRuleChainMetaData(RuleChainId ruleChainId) { 201 + public RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId) {
202 Validator.validateId(ruleChainId, "Incorrect rule chain id."); 202 Validator.validateId(ruleChainId, "Incorrect rule chain id.");
203 - RuleChain ruleChain = findRuleChainById(ruleChainId); 203 + RuleChain ruleChain = findRuleChainById(tenantId, ruleChainId);
204 if (ruleChain == null) { 204 if (ruleChain == null) {
205 return null; 205 return null;
206 } 206 }
207 RuleChainMetaData ruleChainMetaData = new RuleChainMetaData(); 207 RuleChainMetaData ruleChainMetaData = new RuleChainMetaData();
208 ruleChainMetaData.setRuleChainId(ruleChainId); 208 ruleChainMetaData.setRuleChainId(ruleChainId);
209 - List<RuleNode> ruleNodes = getRuleChainNodes(ruleChainId); 209 + List<RuleNode> ruleNodes = getRuleChainNodes(tenantId, ruleChainId);
210 Map<RuleNodeId, Integer> ruleNodeIndexMap = new HashMap<>(); 210 Map<RuleNodeId, Integer> ruleNodeIndexMap = new HashMap<>();
211 for (RuleNode node : ruleNodes) { 211 for (RuleNode node : ruleNodes) {
212 ruleNodeIndexMap.put(node.getId(), ruleNodes.indexOf(node)); 212 ruleNodeIndexMap.put(node.getId(), ruleNodes.indexOf(node));
@@ -217,7 +217,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -217,7 +217,7 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
217 } 217 }
218 for (RuleNode node : ruleNodes) { 218 for (RuleNode node : ruleNodes) {
219 int fromIndex = ruleNodeIndexMap.get(node.getId()); 219 int fromIndex = ruleNodeIndexMap.get(node.getId());
220 - List<EntityRelation> nodeRelations = getRuleNodeRelations(node.getId()); 220 + List<EntityRelation> nodeRelations = getRuleNodeRelations(tenantId, node.getId());
221 for (EntityRelation nodeRelation : nodeRelations) { 221 for (EntityRelation nodeRelation : nodeRelations) {
222 String type = nodeRelation.getType(); 222 String type = nodeRelation.getType();
223 if (nodeRelation.getTo().getEntityType() == EntityType.RULE_NODE) { 223 if (nodeRelation.getTo().getEntityType() == EntityType.RULE_NODE) {
@@ -234,54 +234,54 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -234,54 +234,54 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
234 } 234 }
235 235
236 @Override 236 @Override
237 - public RuleChain findRuleChainById(RuleChainId ruleChainId) { 237 + public RuleChain findRuleChainById(TenantId tenantId, RuleChainId ruleChainId) {
238 Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); 238 Validator.validateId(ruleChainId, "Incorrect rule chain id for search request.");
239 - return ruleChainDao.findById(ruleChainId.getId()); 239 + return ruleChainDao.findById(tenantId, ruleChainId.getId());
240 } 240 }
241 241
242 @Override 242 @Override
243 - public RuleNode findRuleNodeById(RuleNodeId ruleNodeId) { 243 + public RuleNode findRuleNodeById(TenantId tenantId, RuleNodeId ruleNodeId) {
244 Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); 244 Validator.validateId(ruleNodeId, "Incorrect rule node id for search request.");
245 - return ruleNodeDao.findById(ruleNodeId.getId()); 245 + return ruleNodeDao.findById(tenantId, ruleNodeId.getId());
246 } 246 }
247 247
248 @Override 248 @Override
249 - public ListenableFuture<RuleChain> findRuleChainByIdAsync(RuleChainId ruleChainId) { 249 + public ListenableFuture<RuleChain> findRuleChainByIdAsync(TenantId tenantId, RuleChainId ruleChainId) {
250 Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); 250 Validator.validateId(ruleChainId, "Incorrect rule chain id for search request.");
251 - return ruleChainDao.findByIdAsync(ruleChainId.getId()); 251 + return ruleChainDao.findByIdAsync(tenantId, ruleChainId.getId());
252 } 252 }
253 253
254 @Override 254 @Override
255 - public ListenableFuture<RuleNode> findRuleNodeByIdAsync(RuleNodeId ruleNodeId) { 255 + public ListenableFuture<RuleNode> findRuleNodeByIdAsync(TenantId tenantId, RuleNodeId ruleNodeId) {
256 Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); 256 Validator.validateId(ruleNodeId, "Incorrect rule node id for search request.");
257 - return ruleNodeDao.findByIdAsync(ruleNodeId.getId()); 257 + return ruleNodeDao.findByIdAsync(tenantId, ruleNodeId.getId());
258 } 258 }
259 259
260 @Override 260 @Override
261 public RuleChain getRootTenantRuleChain(TenantId tenantId) { 261 public RuleChain getRootTenantRuleChain(TenantId tenantId) {
262 Validator.validateId(tenantId, "Incorrect tenant id for search request."); 262 Validator.validateId(tenantId, "Incorrect tenant id for search request.");
263 - List<EntityRelation> relations = relationService.findByFrom(tenantId, RelationTypeGroup.RULE_CHAIN); 263 + List<EntityRelation> relations = relationService.findByFrom(tenantId, tenantId, RelationTypeGroup.RULE_CHAIN);
264 if (relations != null && !relations.isEmpty()) { 264 if (relations != null && !relations.isEmpty()) {
265 EntityRelation relation = relations.get(0); 265 EntityRelation relation = relations.get(0);
266 RuleChainId ruleChainId = new RuleChainId(relation.getTo().getId()); 266 RuleChainId ruleChainId = new RuleChainId(relation.getTo().getId());
267 - return findRuleChainById(ruleChainId); 267 + return findRuleChainById(tenantId, ruleChainId);
268 } else { 268 } else {
269 return null; 269 return null;
270 } 270 }
271 } 271 }
272 272
273 @Override 273 @Override
274 - public List<RuleNode> getRuleChainNodes(RuleChainId ruleChainId) { 274 + public List<RuleNode> getRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId) {
275 Validator.validateId(ruleChainId, "Incorrect rule chain id for search request."); 275 Validator.validateId(ruleChainId, "Incorrect rule chain id for search request.");
276 - List<EntityRelation> relations = getRuleChainToNodeRelations(ruleChainId);  
277 - List<RuleNode> ruleNodes = relations.stream().map(relation -> ruleNodeDao.findById(relation.getTo().getId())).collect(Collectors.toList()); 276 + List<EntityRelation> relations = getRuleChainToNodeRelations(tenantId, ruleChainId);
  277 + List<RuleNode> ruleNodes = relations.stream().map(relation -> ruleNodeDao.findById(tenantId, relation.getTo().getId())).collect(Collectors.toList());
278 return ruleNodes; 278 return ruleNodes;
279 } 279 }
280 280
281 @Override 281 @Override
282 - public List<EntityRelation> getRuleNodeRelations(RuleNodeId ruleNodeId) { 282 + public List<EntityRelation> getRuleNodeRelations(TenantId tenantId, RuleNodeId ruleNodeId) {
283 Validator.validateId(ruleNodeId, "Incorrect rule node id for search request."); 283 Validator.validateId(ruleNodeId, "Incorrect rule node id for search request.");
284 - return relationService.findByFrom(ruleNodeId, RelationTypeGroup.RULE_NODE); 284 + return relationService.findByFrom(tenantId, ruleNodeId, RelationTypeGroup.RULE_NODE);
285 } 285 }
286 286
287 @Override 287 @Override
@@ -293,60 +293,60 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -293,60 +293,60 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
293 } 293 }
294 294
295 @Override 295 @Override
296 - public void deleteRuleChainById(RuleChainId ruleChainId) { 296 + public void deleteRuleChainById(TenantId tenantId, RuleChainId ruleChainId) {
297 Validator.validateId(ruleChainId, "Incorrect rule chain id for delete request."); 297 Validator.validateId(ruleChainId, "Incorrect rule chain id for delete request.");
298 - RuleChain ruleChain = ruleChainDao.findById(ruleChainId.getId()); 298 + RuleChain ruleChain = ruleChainDao.findById(tenantId, ruleChainId.getId());
299 if (ruleChain != null && ruleChain.isRoot()) { 299 if (ruleChain != null && ruleChain.isRoot()) {
300 throw new DataValidationException("Deletion of Root Tenant Rule Chain is prohibited!"); 300 throw new DataValidationException("Deletion of Root Tenant Rule Chain is prohibited!");
301 } 301 }
302 - checkRuleNodesAndDelete(ruleChainId); 302 + checkRuleNodesAndDelete(tenantId, ruleChainId);
303 } 303 }
304 304
305 @Override 305 @Override
306 public void deleteRuleChainsByTenantId(TenantId tenantId) { 306 public void deleteRuleChainsByTenantId(TenantId tenantId) {
307 Validator.validateId(tenantId, "Incorrect tenant id for delete rule chains request."); 307 Validator.validateId(tenantId, "Incorrect tenant id for delete rule chains request.");
308 - tenantRuleChainsRemover.removeEntities(tenantId); 308 + tenantRuleChainsRemover.removeEntities(tenantId, tenantId);
309 } 309 }
310 310
311 - private void checkRuleNodesAndDelete(RuleChainId ruleChainId) {  
312 - List<EntityRelation> nodeRelations = getRuleChainToNodeRelations(ruleChainId); 311 + private void checkRuleNodesAndDelete(TenantId tenantId, RuleChainId ruleChainId) {
  312 + List<EntityRelation> nodeRelations = getRuleChainToNodeRelations(tenantId, ruleChainId);
313 for (EntityRelation relation : nodeRelations) { 313 for (EntityRelation relation : nodeRelations) {
314 - deleteRuleNode(relation.getTo()); 314 + deleteRuleNode(tenantId, relation.getTo());
315 } 315 }
316 - deleteEntityRelations(ruleChainId);  
317 - ruleChainDao.removeById(ruleChainId.getId()); 316 + deleteEntityRelations(tenantId, ruleChainId);
  317 + ruleChainDao.removeById(tenantId, ruleChainId.getId());
318 } 318 }
319 319
320 - private List<EntityRelation> getRuleChainToNodeRelations(RuleChainId ruleChainId) {  
321 - return relationService.findByFrom(ruleChainId, RelationTypeGroup.RULE_CHAIN); 320 + private List<EntityRelation> getRuleChainToNodeRelations(TenantId tenantId, RuleChainId ruleChainId) {
  321 + return relationService.findByFrom(tenantId, ruleChainId, RelationTypeGroup.RULE_CHAIN);
322 } 322 }
323 323
324 - private void deleteRuleNode(EntityId entityId) {  
325 - deleteEntityRelations(entityId);  
326 - ruleNodeDao.removeById(entityId.getId()); 324 + private void deleteRuleNode(TenantId tenantId, EntityId entityId) {
  325 + deleteEntityRelations(tenantId, entityId);
  326 + ruleNodeDao.removeById(tenantId, entityId.getId());
327 } 327 }
328 328
329 - private void createRelation(EntityRelation relation) throws ExecutionException, InterruptedException { 329 + private void createRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {
330 log.debug("Creating relation: {}", relation); 330 log.debug("Creating relation: {}", relation);
331 - relationService.saveRelation(relation); 331 + relationService.saveRelation(tenantId, relation);
332 } 332 }
333 333
334 - private void deleteRelation(EntityRelation relation) throws ExecutionException, InterruptedException { 334 + private void deleteRelation(TenantId tenantId, EntityRelation relation) throws ExecutionException, InterruptedException {
335 log.debug("Deleting relation: {}", relation); 335 log.debug("Deleting relation: {}", relation);
336 - relationService.deleteRelation(relation); 336 + relationService.deleteRelation(tenantId, relation);
337 } 337 }
338 338
339 private DataValidator<RuleChain> ruleChainValidator = 339 private DataValidator<RuleChain> ruleChainValidator =
340 new DataValidator<RuleChain>() { 340 new DataValidator<RuleChain>() {
341 @Override 341 @Override
342 - protected void validateDataImpl(RuleChain ruleChain) { 342 + protected void validateDataImpl(TenantId tenantId, RuleChain ruleChain) {
343 if (StringUtils.isEmpty(ruleChain.getName())) { 343 if (StringUtils.isEmpty(ruleChain.getName())) {
344 throw new DataValidationException("Rule chain name should be specified!."); 344 throw new DataValidationException("Rule chain name should be specified!.");
345 } 345 }
346 if (ruleChain.getTenantId() == null || ruleChain.getTenantId().isNullUid()) { 346 if (ruleChain.getTenantId() == null || ruleChain.getTenantId().isNullUid()) {
347 throw new DataValidationException("Rule chain should be assigned to tenant!"); 347 throw new DataValidationException("Rule chain should be assigned to tenant!");
348 } 348 }
349 - Tenant tenant = tenantDao.findById(ruleChain.getTenantId().getId()); 349 + Tenant tenant = tenantDao.findById(tenantId, ruleChain.getTenantId().getId());
350 if (tenant == null) { 350 if (tenant == null) {
351 throw new DataValidationException("Rule chain is referencing to non-existent tenant!"); 351 throw new DataValidationException("Rule chain is referencing to non-existent tenant!");
352 } 352 }
@@ -363,13 +363,13 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC @@ -363,13 +363,13 @@ public class BaseRuleChainService extends AbstractEntityService implements RuleC
363 new PaginatedRemover<TenantId, RuleChain>() { 363 new PaginatedRemover<TenantId, RuleChain>() {
364 364
365 @Override 365 @Override
366 - protected List<RuleChain> findEntities(TenantId id, TextPageLink pageLink) { 366 + protected List<RuleChain> findEntities(TenantId tenantId, TenantId id, TextPageLink pageLink) {
367 return ruleChainDao.findRuleChainsByTenantId(id.getId(), pageLink); 367 return ruleChainDao.findRuleChainsByTenantId(id.getId(), pageLink);
368 } 368 }
369 369
370 @Override 370 @Override
371 - protected void removeEntity(RuleChain entity) {  
372 - checkRuleNodesAndDelete(entity.getId()); 371 + protected void removeEntity(TenantId tenantId, RuleChain entity) {
  372 + checkRuleNodesAndDelete(tenantId, entity.getId());
373 } 373 }
374 }; 374 };
375 } 375 }
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.rule; @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.rule;
17 17
18 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
19 import org.springframework.stereotype.Component; 19 import org.springframework.stereotype.Component;
  20 +import org.thingsboard.server.common.data.id.TenantId;
20 import org.thingsboard.server.common.data.page.TextPageLink; 21 import org.thingsboard.server.common.data.page.TextPageLink;
21 import org.thingsboard.server.common.data.rule.RuleChain; 22 import org.thingsboard.server.common.data.rule.RuleChain;
22 import org.thingsboard.server.dao.DaoUtil; 23 import org.thingsboard.server.dao.DaoUtil;
@@ -51,7 +52,7 @@ public class CassandraRuleChainDao extends CassandraAbstractSearchTextDao<RuleCh @@ -51,7 +52,7 @@ public class CassandraRuleChainDao extends CassandraAbstractSearchTextDao<RuleCh
51 @Override 52 @Override
52 public List<RuleChain> findRuleChainsByTenantId(UUID tenantId, TextPageLink pageLink) { 53 public List<RuleChain> findRuleChainsByTenantId(UUID tenantId, TextPageLink pageLink) {
53 log.debug("Try to find rule chains by tenantId [{}] and pageLink [{}]", tenantId, pageLink); 54 log.debug("Try to find rule chains by tenantId [{}] and pageLink [{}]", tenantId, pageLink);
54 - List<RuleChainEntity> ruleChainEntities = findPageWithTextSearch(RULE_CHAIN_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, 55 + List<RuleChainEntity> ruleChainEntities = findPageWithTextSearch(new TenantId(tenantId), RULE_CHAIN_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME,
55 Collections.singletonList(eq(RULE_CHAIN_TENANT_ID_PROPERTY, tenantId)), 56 Collections.singletonList(eq(RULE_CHAIN_TENANT_ID_PROPERTY, tenantId)),
56 pageLink); 57 pageLink);
57 58
@@ -36,29 +36,29 @@ public interface RuleChainService { @@ -36,29 +36,29 @@ public interface RuleChainService {
36 36
37 RuleChain saveRuleChain(RuleChain ruleChain); 37 RuleChain saveRuleChain(RuleChain ruleChain);
38 38
39 - boolean setRootRuleChain(RuleChainId ruleChainId); 39 + boolean setRootRuleChain(TenantId tenantId, RuleChainId ruleChainId);
40 40
41 - RuleChainMetaData saveRuleChainMetaData(RuleChainMetaData ruleChainMetaData); 41 + RuleChainMetaData saveRuleChainMetaData(TenantId tenantId, RuleChainMetaData ruleChainMetaData);
42 42
43 - RuleChainMetaData loadRuleChainMetaData(RuleChainId ruleChainId); 43 + RuleChainMetaData loadRuleChainMetaData(TenantId tenantId, RuleChainId ruleChainId);
44 44
45 - RuleChain findRuleChainById(RuleChainId ruleChainId); 45 + RuleChain findRuleChainById(TenantId tenantId, RuleChainId ruleChainId);
46 46
47 - RuleNode findRuleNodeById(RuleNodeId ruleNodeId); 47 + RuleNode findRuleNodeById(TenantId tenantId, RuleNodeId ruleNodeId);
48 48
49 - ListenableFuture<RuleChain> findRuleChainByIdAsync(RuleChainId ruleChainId); 49 + ListenableFuture<RuleChain> findRuleChainByIdAsync(TenantId tenantId, RuleChainId ruleChainId);
50 50
51 - ListenableFuture<RuleNode> findRuleNodeByIdAsync(RuleNodeId ruleNodeId); 51 + ListenableFuture<RuleNode> findRuleNodeByIdAsync(TenantId tenantId, RuleNodeId ruleNodeId);
52 52
53 RuleChain getRootTenantRuleChain(TenantId tenantId); 53 RuleChain getRootTenantRuleChain(TenantId tenantId);
54 54
55 - List<RuleNode> getRuleChainNodes(RuleChainId ruleChainId); 55 + List<RuleNode> getRuleChainNodes(TenantId tenantId, RuleChainId ruleChainId);
56 56
57 - List<EntityRelation> getRuleNodeRelations(RuleNodeId ruleNodeId); 57 + List<EntityRelation> getRuleNodeRelations(TenantId tenantId, RuleNodeId ruleNodeId);
58 58
59 TextPageData<RuleChain> findTenantRuleChains(TenantId tenantId, TextPageLink pageLink); 59 TextPageData<RuleChain> findTenantRuleChains(TenantId tenantId, TextPageLink pageLink);
60 60
61 - void deleteRuleChainById(RuleChainId ruleChainId); 61 + void deleteRuleChainById(TenantId tenantId, RuleChainId ruleChainId);
62 62
63 void deleteRuleChainsByTenantId(TenantId tenantId); 63 void deleteRuleChainsByTenantId(TenantId tenantId);
64 64
@@ -19,70 +19,73 @@ import com.fasterxml.jackson.databind.JsonNode; @@ -19,70 +19,73 @@ import com.fasterxml.jackson.databind.JsonNode;
19 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
20 import org.apache.commons.validator.routines.EmailValidator; 20 import org.apache.commons.validator.routines.EmailValidator;
21 import org.thingsboard.server.common.data.BaseData; 21 import org.thingsboard.server.common.data.BaseData;
  22 +import org.thingsboard.server.common.data.id.TenantId;
22 import org.thingsboard.server.dao.exception.DataValidationException; 23 import org.thingsboard.server.dao.exception.DataValidationException;
23 24
24 import java.util.HashSet; 25 import java.util.HashSet;
25 import java.util.Iterator; 26 import java.util.Iterator;
26 import java.util.Set; 27 import java.util.Set;
  28 +import java.util.function.Function;
27 29
28 @Slf4j 30 @Slf4j
29 public abstract class DataValidator<D extends BaseData<?>> { 31 public abstract class DataValidator<D extends BaseData<?>> {
30 32
31 private static EmailValidator emailValidator = EmailValidator.getInstance(); 33 private static EmailValidator emailValidator = EmailValidator.getInstance();
32 -  
33 - public void validate(D data) { 34 +
  35 + public void validate(D data, Function<D, TenantId> tenantIdFunction) {
34 try { 36 try {
35 if (data == null) { 37 if (data == null) {
36 throw new DataValidationException("Data object can't be null!"); 38 throw new DataValidationException("Data object can't be null!");
37 } 39 }
38 - validateDataImpl(data); 40 + TenantId tenantId = tenantIdFunction.apply(data);
  41 + validateDataImpl(tenantId, data);
39 if (data.getId() == null) { 42 if (data.getId() == null) {
40 - validateCreate(data); 43 + validateCreate(tenantId, data);
41 } else { 44 } else {
42 - validateUpdate(data); 45 + validateUpdate(tenantId, data);
43 } 46 }
44 } catch (DataValidationException e) { 47 } catch (DataValidationException e) {
45 log.error("Data object is invalid: [{}]", e.getMessage()); 48 log.error("Data object is invalid: [{}]", e.getMessage());
46 throw e; 49 throw e;
47 } 50 }
48 } 51 }
49 -  
50 - protected void validateDataImpl(D data) { 52 +
  53 + protected void validateDataImpl(TenantId tenantId, D data) {
51 } 54 }
52 -  
53 - protected void validateCreate(D data) { 55 +
  56 + protected void validateCreate(TenantId tenantId, D data) {
54 } 57 }
55 58
56 - protected void validateUpdate(D data) { 59 + protected void validateUpdate(TenantId tenantId, D data) {
57 } 60 }
58 - 61 +
59 protected boolean isSameData(D existentData, D actualData) { 62 protected boolean isSameData(D existentData, D actualData) {
60 return actualData.getId() != null && existentData.getId().equals(actualData.getId()); 63 return actualData.getId() != null && existentData.getId().equals(actualData.getId());
61 } 64 }
62 - 65 +
63 protected static void validateEmail(String email) { 66 protected static void validateEmail(String email) {
64 if (!emailValidator.isValid(email)) { 67 if (!emailValidator.isValid(email)) {
65 throw new DataValidationException("Invalid email address format '" + email + "'!"); 68 throw new DataValidationException("Invalid email address format '" + email + "'!");
66 } 69 }
67 } 70 }
68 - 71 +
69 protected static void validateJsonStructure(JsonNode expectedNode, JsonNode actualNode) { 72 protected static void validateJsonStructure(JsonNode expectedNode, JsonNode actualNode) {
70 - Set<String> expectedFields = new HashSet<>(); 73 + Set<String> expectedFields = new HashSet<>();
71 Iterator<String> fieldsIterator = expectedNode.fieldNames(); 74 Iterator<String> fieldsIterator = expectedNode.fieldNames();
72 while (fieldsIterator.hasNext()) { 75 while (fieldsIterator.hasNext()) {
73 expectedFields.add(fieldsIterator.next()); 76 expectedFields.add(fieldsIterator.next());
74 } 77 }
75 -  
76 - Set<String> actualFields = new HashSet<>(); 78 +
  79 + Set<String> actualFields = new HashSet<>();
77 fieldsIterator = actualNode.fieldNames(); 80 fieldsIterator = actualNode.fieldNames();
78 while (fieldsIterator.hasNext()) { 81 while (fieldsIterator.hasNext()) {
79 actualFields.add(fieldsIterator.next()); 82 actualFields.add(fieldsIterator.next());
80 } 83 }
81 - 84 +
82 if (!expectedFields.containsAll(actualFields) || !actualFields.containsAll(expectedFields)) { 85 if (!expectedFields.containsAll(actualFields) || !actualFields.containsAll(expectedFields)) {
83 throw new DataValidationException("Provided json structure is different from stored one '" + actualNode + "'!"); 86 throw new DataValidationException("Provided json structure is different from stored one '" + actualNode + "'!");
84 } 87 }
85 - 88 +
86 for (String field : actualFields) { 89 for (String field : actualFields) {
87 if (!actualNode.get(field).isTextual()) { 90 if (!actualNode.get(field).isTextual()) {
88 throw new DataValidationException("Provided json structure can't contain non-text values '" + actualNode + "'!"); 91 throw new DataValidationException("Provided json structure can't contain non-text values '" + actualNode + "'!");
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.service; 16 package org.thingsboard.server.dao.service;
17 17
18 import org.thingsboard.server.common.data.id.IdBased; 18 import org.thingsboard.server.common.data.id.IdBased;
  19 +import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.page.TextPageLink; 20 import org.thingsboard.server.common.data.page.TextPageLink;
20 21
21 import java.util.List; 22 import java.util.List;
@@ -25,13 +26,13 @@ public abstract class PaginatedRemover<I, D extends IdBased<?>> { @@ -25,13 +26,13 @@ public abstract class PaginatedRemover<I, D extends IdBased<?>> {
25 26
26 private static final int DEFAULT_LIMIT = 100; 27 private static final int DEFAULT_LIMIT = 100;
27 28
28 - public void removeEntities(I id) { 29 + public void removeEntities(TenantId tenantId, I id) {
29 TextPageLink pageLink = new TextPageLink(DEFAULT_LIMIT); 30 TextPageLink pageLink = new TextPageLink(DEFAULT_LIMIT);
30 boolean hasNext = true; 31 boolean hasNext = true;
31 while (hasNext) { 32 while (hasNext) {
32 - List<D> entities = findEntities(id, pageLink); 33 + List<D> entities = findEntities(tenantId, id, pageLink);
33 for (D entity : entities) { 34 for (D entity : entities) {
34 - removeEntity(entity); 35 + removeEntity(tenantId, entity);
35 } 36 }
36 hasNext = entities.size() == pageLink.getLimit(); 37 hasNext = entities.size() == pageLink.getLimit();
37 if (hasNext) { 38 if (hasNext) {
@@ -42,8 +43,8 @@ public abstract class PaginatedRemover<I, D extends IdBased<?>> { @@ -42,8 +43,8 @@ public abstract class PaginatedRemover<I, D extends IdBased<?>> {
42 } 43 }
43 } 44 }
44 45
45 - protected abstract List<D> findEntities(I id, TextPageLink pageLink); 46 + protected abstract List<D> findEntities(TenantId tenantId,I id, TextPageLink pageLink);
46 47
47 - protected abstract void removeEntity(D entity); 48 + protected abstract void removeEntity(TenantId tenantId, D entity);
48 49
49 } 50 }
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.settings; 16 package org.thingsboard.server.dao.settings;
17 17
18 import org.thingsboard.server.common.data.AdminSettings; 18 import org.thingsboard.server.common.data.AdminSettings;
  19 +import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.dao.Dao; 20 import org.thingsboard.server.dao.Dao;
20 21
21 public interface AdminSettingsDao extends Dao<AdminSettings> { 22 public interface AdminSettingsDao extends Dao<AdminSettings> {
@@ -26,7 +27,7 @@ public interface AdminSettingsDao extends Dao<AdminSettings> { @@ -26,7 +27,7 @@ public interface AdminSettingsDao extends Dao<AdminSettings> {
26 * @param adminSettings the admin settings object 27 * @param adminSettings the admin settings object
27 * @return saved admin settings object 28 * @return saved admin settings object
28 */ 29 */
29 - AdminSettings save(AdminSettings adminSettings); 30 + AdminSettings save(TenantId tenantId, AdminSettings adminSettings);
30 31
31 /** 32 /**
32 * Find admin settings by key. 33 * Find admin settings by key.
@@ -34,6 +35,6 @@ public interface AdminSettingsDao extends Dao<AdminSettings> { @@ -34,6 +35,6 @@ public interface AdminSettingsDao extends Dao<AdminSettings> {
34 * @param key the key 35 * @param key the key
35 * @return the admin settings object 36 * @return the admin settings object
36 */ 37 */
37 - AdminSettings findByKey(String key); 38 + AdminSettings findByKey(TenantId tenantId, String key);
38 39
39 } 40 }
@@ -17,13 +17,14 @@ package org.thingsboard.server.dao.settings; @@ -17,13 +17,14 @@ package org.thingsboard.server.dao.settings;
17 17
18 import org.thingsboard.server.common.data.AdminSettings; 18 import org.thingsboard.server.common.data.AdminSettings;
19 import org.thingsboard.server.common.data.id.AdminSettingsId; 19 import org.thingsboard.server.common.data.id.AdminSettingsId;
  20 +import org.thingsboard.server.common.data.id.TenantId;
20 21
21 public interface AdminSettingsService { 22 public interface AdminSettingsService {
22 23
23 - AdminSettings findAdminSettingsById(AdminSettingsId adminSettingsId); 24 + AdminSettings findAdminSettingsById(TenantId tenantId, AdminSettingsId adminSettingsId);
24 25
25 - AdminSettings findAdminSettingsByKey(String key); 26 + AdminSettings findAdminSettingsByKey(TenantId tenantId, String key);
26 27
27 - AdminSettings saveAdminSettings(AdminSettings adminSettings); 28 + AdminSettings saveAdminSettings(TenantId tenantId, AdminSettings adminSettings);
28 29
29 } 30 }