Commit 104450c10276ba45ffd651e9a55a54288c71a107
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 | } |