Browse Source

Message queue limit per tenant. Message queue periodic cleanup.

pull/804/head
Igor Kulikov 8 years ago
parent
commit
25f82d384b
  1. 3
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  2. 8
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainActorMessageProcessor.java
  3. 7
      application/src/main/java/org/thingsboard/server/actors/shared/ComponentMsgProcessor.java
  4. 102
      application/src/main/java/org/thingsboard/server/service/queue/DefaultMsgQueueService.java
  5. 32
      application/src/main/java/org/thingsboard/server/service/queue/MsgQueueService.java
  6. 13
      application/src/main/resources/thingsboard.yml
  7. 3
      application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java
  8. 6
      application/src/test/java/org/thingsboard/server/rules/flow/AbstractRuleEngineFlowIntegrationTest.java
  9. 2
      application/src/test/java/org/thingsboard/server/rules/lifecycle/AbstractRuleEngineLifecycleIntegrationTest.java
  10. 10
      dao/src/main/java/org/thingsboard/server/dao/queue/MsgQueue.java
  11. 4
      dao/src/main/java/org/thingsboard/server/dao/queue/QueueBenchmark.java
  12. 21
      dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/CassandraMsgQueue.java
  13. 2
      dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/MsgAck.java
  14. 4
      dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/QueuePartitioner.java
  15. 2
      dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/UnprocessedMsgFilter.java
  16. 6
      dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraAckRepository.java
  17. 4
      dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraMsgRepository.java
  18. 4
      dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraProcessedPartitionRepository.java
  19. 4
      dao/src/main/java/org/thingsboard/server/dao/queue/db/repository/AckRepository.java
  20. 2
      dao/src/main/java/org/thingsboard/server/dao/queue/db/repository/MsgRepository.java
  21. 2
      dao/src/main/java/org/thingsboard/server/dao/queue/db/repository/ProcessedPartitionRepository.java
  22. 2
      dao/src/main/java/org/thingsboard/server/dao/queue/db/sql/SqlMsgQueue.java
  23. 2
      dao/src/main/java/org/thingsboard/server/dao/queue/memory/InMemoryMsgKey.java
  24. 118
      dao/src/main/java/org/thingsboard/server/dao/queue/memory/InMemoryMsgQueue.java
  25. 114
      dao/src/main/java/org/thingsboard/server/dao/sql/queue/InMemoryMsgQueue.java
  26. 5
      dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/QueuePartitionerTest.java
  27. 4
      dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/UnprocessedMsgFilterTest.java
  28. 5
      dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraAckRepositoryTest.java
  29. 3
      dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraMsgRepositoryTest.java
  30. 3
      dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraProcessedPartitionRepositoryTest.java

3
application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java

@ -63,6 +63,7 @@ import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.executors.DbCallbackExecutorService; import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.executors.ExternalCallExecutorService; import org.thingsboard.server.service.executors.ExternalCallExecutorService;
import org.thingsboard.server.service.mail.MailExecutorService; import org.thingsboard.server.service.mail.MailExecutorService;
import org.thingsboard.server.service.queue.MsgQueueService;
import org.thingsboard.server.service.rpc.DeviceRpcService; import org.thingsboard.server.service.rpc.DeviceRpcService;
import org.thingsboard.server.service.script.JsExecutorService; import org.thingsboard.server.service.script.JsExecutorService;
import org.thingsboard.server.service.state.DeviceStateService; import org.thingsboard.server.service.state.DeviceStateService;
@ -196,7 +197,7 @@ public class ActorSystemContext {
@Autowired @Autowired
@Getter @Getter
private MsgQueue msgQueue; private MsgQueueService msgQueueService;
@Autowired @Autowired
@Getter @Getter

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

@ -95,12 +95,12 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
private void reprocess(List<RuleNode> ruleNodeList) { private void reprocess(List<RuleNode> ruleNodeList) {
for (RuleNode ruleNode : ruleNodeList) { for (RuleNode ruleNode : ruleNodeList) {
for (TbMsg tbMsg : queue.findUnprocessed(ruleNode.getId().getId(), 0L)) { for (TbMsg tbMsg : queue.findUnprocessed(tenantId, ruleNode.getId().getId(), 0L)) {
pushMsgToNode(nodeActors.get(ruleNode.getId()), tbMsg, ""); pushMsgToNode(nodeActors.get(ruleNode.getId()), tbMsg, "");
} }
} }
if (firstNode != null) { if (firstNode != null) {
for (TbMsg tbMsg : queue.findUnprocessed(entityId.getId(), 0L)) { for (TbMsg tbMsg : queue.findUnprocessed(tenantId, entityId.getId(), 0L)) {
pushMsgToNode(firstNode, tbMsg, ""); pushMsgToNode(firstNode, tbMsg, "");
} }
} }
@ -215,7 +215,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
int relationsCount = relations.size(); int relationsCount = relations.size();
EntityId ackId = msg.getRuleNodeId() != null ? msg.getRuleNodeId() : msg.getRuleChainId(); EntityId ackId = msg.getRuleNodeId() != null ? msg.getRuleNodeId() : msg.getRuleChainId();
if (relationsCount == 0) { if (relationsCount == 0) {
queue.ack(msg, ackId.getId(), msg.getClusterPartition()); queue.ack(tenantId, msg, ackId.getId(), msg.getClusterPartition());
} else if (relationsCount == 1) { } else if (relationsCount == 1) {
for (RuleNodeRelation relation : relations) { for (RuleNodeRelation relation : relations) {
pushToTarget(msg, relation.getOut(), relation.getType()); pushToTarget(msg, relation.getOut(), relation.getType());
@ -233,7 +233,7 @@ public class RuleChainActorMessageProcessor extends ComponentMsgProcessor<RuleCh
} }
} }
//TODO: Ideally this should happen in async way when all targets confirm that the copied messages are successfully written to corresponding target queues. //TODO: Ideally this should happen in async way when all targets confirm that the copied messages are successfully written to corresponding target queues.
queue.ack(msg, ackId.getId(), msg.getClusterPartition()); queue.ack(tenantId, msg, ackId.getId(), msg.getClusterPartition());
} }
} }

7
application/src/main/java/org/thingsboard/server/actors/shared/ComponentMsgProcessor.java

@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.dao.queue.MsgQueue; import org.thingsboard.server.dao.queue.MsgQueue;
import org.thingsboard.server.service.queue.MsgQueueService;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -35,14 +36,14 @@ public abstract class ComponentMsgProcessor<T extends EntityId> extends Abstract
protected final TenantId tenantId; protected final TenantId tenantId;
protected final T entityId; protected final T entityId;
protected final MsgQueue queue; protected final MsgQueueService queue;
protected ComponentLifecycleState state; protected ComponentLifecycleState state;
protected ComponentMsgProcessor(ActorSystemContext systemContext, LoggingAdapter logger, TenantId tenantId, T id) { protected ComponentMsgProcessor(ActorSystemContext systemContext, LoggingAdapter logger, TenantId tenantId, T id) {
super(systemContext, logger); super(systemContext, logger);
this.tenantId = tenantId; this.tenantId = tenantId;
this.entityId = id; this.entityId = id;
this.queue = systemContext.getMsgQueue(); this.queue = systemContext.getMsgQueueService();
} }
public abstract void start(ActorContext context) throws Exception; public abstract void start(ActorContext context) throws Exception;
@ -88,7 +89,7 @@ public abstract class ComponentMsgProcessor<T extends EntityId> extends Abstract
protected void putToQueue(final TbMsg tbMsg, final Consumer<TbMsg> onSuccess) { protected void putToQueue(final TbMsg tbMsg, final Consumer<TbMsg> onSuccess) {
EntityId entityId = tbMsg.getRuleNodeId() != null ? tbMsg.getRuleNodeId() : tbMsg.getRuleChainId(); EntityId entityId = tbMsg.getRuleNodeId() != null ? tbMsg.getRuleNodeId() : tbMsg.getRuleChainId();
Futures.addCallback(queue.put(tbMsg, entityId.getId(), 0), new FutureCallback<Void>() { Futures.addCallback(queue.put(this.tenantId, tbMsg, entityId.getId(), 0), new FutureCallback<Void>() {
@Override @Override
public void onSuccess(@Nullable Void result) { public void onSuccess(@Nullable Void result) {
onSuccess.accept(tbMsg); onSuccess.accept(tbMsg);

102
application/src/main/java/org/thingsboard/server/service/queue/DefaultMsgQueueService.java

@ -0,0 +1,102 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.queue;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.dao.queue.MsgQueue;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
@Service
@Slf4j
public class DefaultMsgQueueService implements MsgQueueService {
@Value("${rule.queue.max_size}")
private long queueMaxSize;
@Value("${rule.queue.cleanup_period}")
private long queueCleanUpPeriod;
@Autowired
private MsgQueue msgQueue;
private ScheduledExecutorService cleanupExecutor;
private Map<TenantId, AtomicLong> pendingCountPerTenant = new ConcurrentHashMap<>();
@PostConstruct
public void init() {
if (queueCleanUpPeriod > 0) {
cleanupExecutor = Executors.newSingleThreadScheduledExecutor();
cleanupExecutor.scheduleAtFixedRate(() -> cleanup(),
queueCleanUpPeriod, queueCleanUpPeriod, TimeUnit.SECONDS);
}
}
@PreDestroy
public void stop() {
if (cleanupExecutor != null) {
cleanupExecutor.shutdownNow();
}
}
@Override
public ListenableFuture<Void> put(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition) {
AtomicLong pendingMsgCount = pendingCountPerTenant.computeIfAbsent(tenantId, key -> new AtomicLong());
if (pendingMsgCount.incrementAndGet() < queueMaxSize) {
return msgQueue.put(tenantId, msg, nodeId, clusterPartition);
} else {
pendingMsgCount.decrementAndGet();
return Futures.immediateFailedFuture(new RuntimeException("Message queue is full!"));
}
}
@Override
public ListenableFuture<Void> ack(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition) {
ListenableFuture<Void> result = msgQueue.ack(tenantId, msg, nodeId, clusterPartition);
AtomicLong pendingMsgCount = pendingCountPerTenant.computeIfAbsent(tenantId, key -> new AtomicLong());
pendingMsgCount.decrementAndGet();
return result;
}
@Override
public Iterable<TbMsg> findUnprocessed(TenantId tenantId, UUID nodeId, long clusterPartition) {
return msgQueue.findUnprocessed(tenantId, nodeId, clusterPartition);
}
private void cleanup() {
pendingCountPerTenant.forEach((tenantId, pendingMsgCount) -> {
pendingMsgCount.set(0);
msgQueue.cleanUp(tenantId);
});
}
}

32
application/src/main/java/org/thingsboard/server/service/queue/MsgQueueService.java

@ -0,0 +1,32 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.queue;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.UUID;
public interface MsgQueueService {
ListenableFuture<Void> put(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition);
ListenableFuture<Void> ack(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition);
Iterable<TbMsg> findUnprocessed(TenantId tenantId, UUID nodeId, long clusterPartition);
}

13
application/src/main/resources/thingsboard.yml

@ -305,17 +305,20 @@ spring:
rule: rule:
queue: queue:
type: "memory" #Message queue type (memory or db)
max_size: 10000 type: "${RULE_QUEUE_TYPE:memory}"
#Message queue maximum size (per tenant)
max_size: "${RULE_QUEUE_MAX_SIZE:100}"
#Message queue cleanup period in seconds
cleanup_period: "${RULE_QUEUE_CLEANUP_PERIOD:3600}"
# PostgreSQL DAO Configuration # PostgreSQL DAO Configuration
#spring: #spring:
# data: # data:
# jpa: # sql:
# repositories: # repositories:
# enabled: "true" # enabled: "true"
# jpa: # sql:
# hibernate: # hibernate:
# ddl-auto: "validate" # ddl-auto: "validate"
# database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQLDialect}" # database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQLDialect}"

3
application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java

@ -29,6 +29,7 @@ import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData; import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.dao.queue.MsgQueue; import org.thingsboard.server.dao.queue.MsgQueue;
import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.service.queue.MsgQueueService;
import java.io.IOException; import java.io.IOException;
@ -41,7 +42,7 @@ public class AbstractRuleEngineControllerTest extends AbstractControllerTest {
protected RuleChainService ruleChainService; protected RuleChainService ruleChainService;
@Autowired @Autowired
protected MsgQueue msgQueue; protected MsgQueueService msgQueueService;
protected RuleChain saveRuleChain(RuleChain ruleChain) throws Exception { protected RuleChain saveRuleChain(RuleChain ruleChain) throws Exception {
return doPost("/api/ruleChain", ruleChain, RuleChain.class); return doPost("/api/ruleChain", ruleChain, RuleChain.class);

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

@ -189,7 +189,7 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
Assert.assertEquals("serverAttributeValue1", getMetadata(outEvent).get("ss_serverAttributeKey1").asText()); Assert.assertEquals("serverAttributeValue1", getMetadata(outEvent).get("ss_serverAttributeKey1").asText());
Assert.assertEquals("serverAttributeValue2", getMetadata(outEvent).get("ss_serverAttributeKey2").asText()); Assert.assertEquals("serverAttributeValue2", getMetadata(outEvent).get("ss_serverAttributeKey2").asText());
List<TbMsg> unAckMsgList = Lists.newArrayList(msgQueue.findUnprocessed(ruleChain.getId().getId(), 0L)); List<TbMsg> unAckMsgList = Lists.newArrayList(msgQueueService.findUnprocessed(savedTenant.getId(), ruleChain.getId().getId(), 0L));
Assert.assertEquals(0, unAckMsgList.size()); Assert.assertEquals(0, unAckMsgList.size());
} }
@ -306,10 +306,10 @@ public abstract class AbstractRuleEngineFlowIntegrationTest extends AbstractRule
Assert.assertEquals("serverAttributeValue1", getMetadata(outEvent).get("ss_serverAttributeKey1").asText()); Assert.assertEquals("serverAttributeValue1", getMetadata(outEvent).get("ss_serverAttributeKey1").asText());
Assert.assertEquals("serverAttributeValue2", getMetadata(outEvent).get("ss_serverAttributeKey2").asText()); Assert.assertEquals("serverAttributeValue2", getMetadata(outEvent).get("ss_serverAttributeKey2").asText());
List<TbMsg> unAckMsgList = Lists.newArrayList(msgQueue.findUnprocessed(rootRuleChain.getId().getId(), 0L)); List<TbMsg> unAckMsgList = Lists.newArrayList(msgQueueService.findUnprocessed(savedTenant.getId(), rootRuleChain.getId().getId(), 0L));
Assert.assertEquals(0, unAckMsgList.size()); Assert.assertEquals(0, unAckMsgList.size());
unAckMsgList = Lists.newArrayList(msgQueue.findUnprocessed(secondaryRuleChain.getId().getId(), 0L)); unAckMsgList = Lists.newArrayList(msgQueueService.findUnprocessed(savedTenant.getId(), secondaryRuleChain.getId().getId(), 0L));
Assert.assertEquals(0, unAckMsgList.size()); Assert.assertEquals(0, unAckMsgList.size());
} }

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

@ -186,7 +186,7 @@ public abstract class AbstractRuleEngineLifecycleIntegrationTest extends Abstrac
new TbMsgMetaData(), new TbMsgMetaData(),
"{}", "{}",
ruleChain.getId(), null, 0L); ruleChain.getId(), null, 0L);
msgQueue.put(tbMsg, ruleChain.getId().getId(), 0L); msgQueueService.put(device.getTenantId(), tbMsg, ruleChain.getId().getId(), 0L);
Thread.sleep(1000); Thread.sleep(1000);

10
dao/src/main/java/org/thingsboard/server/dao/queue/MsgQueue.java

@ -16,15 +16,19 @@
package org.thingsboard.server.dao.queue; package org.thingsboard.server.dao.queue;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import java.util.UUID; import java.util.UUID;
public interface MsgQueue { public interface MsgQueue {
ListenableFuture<Void> put(TbMsg msg, UUID nodeId, long clusterPartition); ListenableFuture<Void> put(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition);
ListenableFuture<Void> ack(TbMsg msg, UUID nodeId, long clusterPartition); ListenableFuture<Void> ack(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition);
Iterable<TbMsg> findUnprocessed(TenantId tenantId, UUID nodeId, long clusterPartition);
ListenableFuture<Void> cleanUp(TenantId tenantId);
Iterable<TbMsg> findUnprocessed(UUID nodeId, long clusterPartition);
} }

4
dao/src/main/java/org/thingsboard/server/dao/queue/QueueBenchmark.java

@ -28,8 +28,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId; import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgDataType; import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.TbMsgMetaData;
@ -80,7 +82,7 @@ public class QueueBenchmark implements CommandLineRunner {
try { try {
TbMsg msg = randomMsg(); TbMsg msg = randomMsg();
UUID nodeId = UUIDs.timeBased(); UUID nodeId = UUIDs.timeBased();
ListenableFuture<Void> put = msgQueue.put(msg, nodeId, 100L); ListenableFuture<Void> put = msgQueue.put(new TenantId(EntityId.NULL_UUID), msg, nodeId, 100L);
// ListenableFuture<Void> put = msgQueue.ack(msg, nodeId, 100L); // ListenableFuture<Void> put = msgQueue.ack(msg, nodeId, 100L);
Futures.addCallback(put, new FutureCallback<Void>() { Futures.addCallback(put, new FutureCallback<Void>() {
@Override @Override

21
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/CassandraMsgQueue.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/CassandraMsgQueue.java

@ -13,24 +13,28 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra; package org.thingsboard.server.dao.queue.db.nosql;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.dao.queue.MsgQueue; import org.thingsboard.server.dao.queue.MsgQueue;
import org.thingsboard.server.dao.service.queue.cassandra.repository.AckRepository; import org.thingsboard.server.dao.queue.db.repository.AckRepository;
import org.thingsboard.server.dao.service.queue.cassandra.repository.MsgRepository; import org.thingsboard.server.dao.queue.db.repository.MsgRepository;
import org.thingsboard.server.dao.util.NoSqlDao; import org.thingsboard.server.dao.util.NoSqlDao;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@Component @Component
@ConditionalOnProperty(prefix = "rule.queue", value = "type", havingValue = "db")
@Slf4j @Slf4j
@NoSqlDao @NoSqlDao
public class CassandraMsgQueue implements MsgQueue { public class CassandraMsgQueue implements MsgQueue {
@ -45,21 +49,21 @@ public class CassandraMsgQueue implements MsgQueue {
private QueuePartitioner queuePartitioner; private QueuePartitioner queuePartitioner;
@Override @Override
public ListenableFuture<Void> put(TbMsg msg, UUID nodeId, long clusterPartition) { public ListenableFuture<Void> put(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition) {
long msgTime = getMsgTime(msg); long msgTime = getMsgTime(msg);
long tsPartition = queuePartitioner.getPartition(msgTime); long tsPartition = queuePartitioner.getPartition(msgTime);
return msgRepository.save(msg, nodeId, clusterPartition, tsPartition, msgTime); return msgRepository.save(msg, nodeId, clusterPartition, tsPartition, msgTime);
} }
@Override @Override
public ListenableFuture<Void> ack(TbMsg msg, UUID nodeId, long clusterPartition) { public ListenableFuture<Void> ack(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition) {
long tsPartition = queuePartitioner.getPartition(getMsgTime(msg)); long tsPartition = queuePartitioner.getPartition(getMsgTime(msg));
MsgAck ack = new MsgAck(msg.getId(), nodeId, clusterPartition, tsPartition); MsgAck ack = new MsgAck(msg.getId(), nodeId, clusterPartition, tsPartition);
return ackRepository.ack(ack); return ackRepository.ack(ack);
} }
@Override @Override
public Iterable<TbMsg> findUnprocessed(UUID nodeId, long clusterPartition) { public Iterable<TbMsg> findUnprocessed(TenantId tenantId, UUID nodeId, long clusterPartition) {
List<TbMsg> unprocessedMsgs = Lists.newArrayList(); List<TbMsg> unprocessedMsgs = Lists.newArrayList();
for (Long tsPartition : queuePartitioner.findUnprocessedPartitions(nodeId, clusterPartition)) { for (Long tsPartition : queuePartitioner.findUnprocessedPartitions(nodeId, clusterPartition)) {
List<TbMsg> msgs = msgRepository.findMsgs(nodeId, clusterPartition, tsPartition); List<TbMsg> msgs = msgRepository.findMsgs(nodeId, clusterPartition, tsPartition);
@ -69,6 +73,11 @@ public class CassandraMsgQueue implements MsgQueue {
return unprocessedMsgs; return unprocessedMsgs;
} }
@Override
public ListenableFuture<Void> cleanUp(TenantId tenantId) {
return Futures.immediateFuture(null);
}
private long getMsgTime(TbMsg msg) { private long getMsgTime(TbMsg msg) {
return UUIDs.unixTimestamp(msg.getId()); return UUIDs.unixTimestamp(msg.getId());
} }

2
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/MsgAck.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/MsgAck.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra; package org.thingsboard.server.dao.queue.db.nosql;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;

4
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/QueuePartitioner.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/QueuePartitioner.java

@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra; package org.thingsboard.server.dao.queue.db.nosql;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.dao.service.queue.cassandra.repository.ProcessedPartitionRepository; import org.thingsboard.server.dao.queue.db.repository.ProcessedPartitionRepository;
import org.thingsboard.server.dao.timeseries.TsPartitionDate; import org.thingsboard.server.dao.timeseries.TsPartitionDate;
import org.thingsboard.server.dao.util.NoSqlDao; import org.thingsboard.server.dao.util.NoSqlDao;

2
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/UnprocessedMsgFilter.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/UnprocessedMsgFilter.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra; package org.thingsboard.server.dao.queue.db.nosql;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;

6
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/repository/impl/CassandraAckRepository.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraAckRepository.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository.impl; package org.thingsboard.server.dao.queue.db.nosql.repository;
import com.datastax.driver.core.*; import com.datastax.driver.core.*;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -22,8 +22,8 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.dao.nosql.CassandraAbstractDao; import org.thingsboard.server.dao.nosql.CassandraAbstractDao;
import org.thingsboard.server.dao.service.queue.cassandra.MsgAck; import org.thingsboard.server.dao.queue.db.nosql.MsgAck;
import org.thingsboard.server.dao.service.queue.cassandra.repository.AckRepository; import org.thingsboard.server.dao.queue.db.repository.AckRepository;
import org.thingsboard.server.dao.util.NoSqlDao; import org.thingsboard.server.dao.util.NoSqlDao;
import java.util.ArrayList; import java.util.ArrayList;

4
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/repository/impl/CassandraMsgRepository.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraMsgRepository.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository.impl; package org.thingsboard.server.dao.queue.db.nosql.repository;
import com.datastax.driver.core.*; import com.datastax.driver.core.*;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -23,7 +23,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.dao.nosql.CassandraAbstractDao; import org.thingsboard.server.dao.nosql.CassandraAbstractDao;
import org.thingsboard.server.dao.service.queue.cassandra.repository.MsgRepository; import org.thingsboard.server.dao.queue.db.repository.MsgRepository;
import org.thingsboard.server.dao.util.NoSqlDao; import org.thingsboard.server.dao.util.NoSqlDao;
import java.util.ArrayList; import java.util.ArrayList;

4
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/repository/impl/CassandraProcessedPartitionRepository.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraProcessedPartitionRepository.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository.impl; package org.thingsboard.server.dao.queue.db.nosql.repository;
import com.datastax.driver.core.*; import com.datastax.driver.core.*;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -22,7 +22,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.thingsboard.server.dao.nosql.CassandraAbstractDao; import org.thingsboard.server.dao.nosql.CassandraAbstractDao;
import org.thingsboard.server.dao.service.queue.cassandra.repository.ProcessedPartitionRepository; import org.thingsboard.server.dao.queue.db.repository.ProcessedPartitionRepository;
import org.thingsboard.server.dao.util.NoSqlDao; import org.thingsboard.server.dao.util.NoSqlDao;
import java.util.Optional; import java.util.Optional;

4
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/repository/AckRepository.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/repository/AckRepository.java

@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository; package org.thingsboard.server.dao.queue.db.repository;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.dao.service.queue.cassandra.MsgAck; import org.thingsboard.server.dao.queue.db.nosql.MsgAck;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;

2
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/repository/MsgRepository.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/repository/MsgRepository.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository; package org.thingsboard.server.dao.queue.db.repository;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;

2
dao/src/main/java/org/thingsboard/server/dao/service/queue/cassandra/repository/ProcessedPartitionRepository.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/repository/ProcessedPartitionRepository.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository; package org.thingsboard.server.dao.queue.db.repository;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;

2
dao/src/main/java/org/thingsboard/server/dao/queue/jpa/SqlMsgQueue.java → dao/src/main/java/org/thingsboard/server/dao/queue/db/sql/SqlMsgQueue.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.queue.jpa; package org.thingsboard.server.dao.queue.db.sql;
//@todo-vp: implement //@todo-vp: implement
public class SqlMsgQueue { public class SqlMsgQueue {

2
dao/src/main/java/org/thingsboard/server/dao/sql/queue/InMemoryMsgKey.java → dao/src/main/java/org/thingsboard/server/dao/queue/memory/InMemoryMsgKey.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.sql.queue; package org.thingsboard.server.dao.queue.memory;
import lombok.Data; import lombok.Data;

118
dao/src/main/java/org/thingsboard/server/dao/queue/memory/InMemoryMsgQueue.java

@ -0,0 +1,118 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.queue.memory;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.dao.queue.MsgQueue;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
/**
* Created by ashvayka on 27.04.18.
*/
@Component
@ConditionalOnProperty(prefix = "rule.queue", value = "type", havingValue = "memory", matchIfMissing = true)
@Slf4j
public class InMemoryMsgQueue implements MsgQueue {
private ListeningExecutorService queueExecutor;
private Map<TenantId, Map<InMemoryMsgKey, Map<UUID, TbMsg>>> data = new HashMap<>();
@PostConstruct
public void init() {
// Should be always single threaded due to absence of locks.
queueExecutor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
}
@PreDestroy
public void stop() {
if (queueExecutor != null) {
queueExecutor.shutdownNow();
}
}
@Override
public ListenableFuture<Void> put(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition) {
return queueExecutor.submit(() -> {
data.computeIfAbsent(tenantId, key -> new HashMap<>()).
computeIfAbsent(new InMemoryMsgKey(nodeId, clusterPartition), key -> new HashMap<>()).put(msg.getId(), msg);
return null;
});
}
@Override
public ListenableFuture<Void> ack(TenantId tenantId, TbMsg msg, UUID nodeId, long clusterPartition) {
return queueExecutor.submit(() -> {
Map<InMemoryMsgKey, Map<UUID, TbMsg>> tenantMap = data.get(tenantId);
if (tenantMap != null) {
InMemoryMsgKey key = new InMemoryMsgKey(nodeId, clusterPartition);
Map<UUID, TbMsg> map = tenantMap.get(key);
if (map != null) {
map.remove(msg.getId());
if (map.isEmpty()) {
tenantMap.remove(key);
}
}
if (tenantMap.isEmpty()) {
data.remove(tenantId);
}
}
return null;
});
}
@Override
public Iterable<TbMsg> findUnprocessed(TenantId tenantId, UUID nodeId, long clusterPartition) {
ListenableFuture<List<TbMsg>> list = queueExecutor.submit(() -> {
Map<InMemoryMsgKey, Map<UUID, TbMsg>> tenantMap = data.get(tenantId);
if (tenantMap != null) {
InMemoryMsgKey key = new InMemoryMsgKey(nodeId, clusterPartition);
Map<UUID, TbMsg> map = tenantMap.get(key);
if (map != null) {
return new ArrayList<>(map.values());
} else {
return Collections.emptyList();
}
} else {
return Collections.emptyList();
}
});
try {
return list.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@Override
public ListenableFuture<Void> cleanUp(TenantId tenantId) {
return queueExecutor.submit(() -> {
data.remove(tenantId);
return null;
});
}
}

114
dao/src/main/java/org/thingsboard/server/dao/sql/queue/InMemoryMsgQueue.java

@ -1,114 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.dao.sql.queue;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.dao.queue.MsgQueue;
import org.thingsboard.server.dao.util.SqlDao;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
/**
* Created by ashvayka on 27.04.18.
*/
@Component
//@ConditionalOnProperty(prefix = "rule.queue", value = "type", havingValue = "memory", matchIfMissing = true)
@Slf4j
@SqlDao
public class InMemoryMsgQueue implements MsgQueue {
@Value("${rule.queue.max_size}")
@Getter
private long maxSize;
private ListeningExecutorService queueExecutor;
private AtomicLong pendingMsgCount = new AtomicLong();
private Map<InMemoryMsgKey, Map<UUID, TbMsg>> data = new HashMap<>();
@PostConstruct
public void init() {
// Should be always single threaded due to absence of locks.
queueExecutor = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
}
@PreDestroy
public void stop() {
if (queueExecutor == null) {
queueExecutor.shutdownNow();
}
}
@Override
public ListenableFuture<Void> put(TbMsg msg, UUID nodeId, long clusterPartition) {
if (pendingMsgCount.incrementAndGet() < maxSize) {
return queueExecutor.submit(() -> {
data.computeIfAbsent(new InMemoryMsgKey(nodeId, clusterPartition), key -> new HashMap<>()).put(msg.getId(), msg);
return null;
});
} else {
pendingMsgCount.decrementAndGet();
return Futures.immediateFailedFuture(new RuntimeException("Message queue is full!"));
}
}
@Override
public ListenableFuture<Void> ack(TbMsg msg, UUID nodeId, long clusterPartition) {
return queueExecutor.submit(() -> {
InMemoryMsgKey key = new InMemoryMsgKey(nodeId, clusterPartition);
Map<UUID, TbMsg> map = data.get(key);
if (map != null) {
if (map.remove(msg.getId()) != null) {
pendingMsgCount.decrementAndGet();
}
if (map.isEmpty()) {
data.remove(key);
}
}
return null;
});
}
@Override
public Iterable<TbMsg> findUnprocessed(UUID nodeId, long clusterPartition) {
ListenableFuture<List<TbMsg>> list = queueExecutor.submit(() -> {
InMemoryMsgKey key = new InMemoryMsgKey(nodeId, clusterPartition);
Map<UUID, TbMsg> map = data.get(key);
if (map != null) {
return new ArrayList<>(map.values());
} else {
return Collections.emptyList();
}
});
try {
return list.get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}

5
dao/src/test/java/org/thingsboard/server/dao/service/queue/cassandra/QueuePartitionerTest.java → dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/QueuePartitionerTest.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra; package org.thingsboard.server.dao.queue.db.nosql;
import org.junit.Before; import org.junit.Before;
@ -21,7 +21,8 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner; import org.mockito.runners.MockitoJUnitRunner;
import org.thingsboard.server.dao.service.queue.cassandra.repository.ProcessedPartitionRepository; import org.thingsboard.server.dao.queue.db.nosql.QueuePartitioner;
import org.thingsboard.server.dao.queue.db.repository.ProcessedPartitionRepository;
import java.time.Clock; import java.time.Clock;
import java.time.Instant; import java.time.Instant;

4
dao/src/test/java/org/thingsboard/server/dao/service/queue/cassandra/UnprocessedMsgFilterTest.java → dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/UnprocessedMsgFilterTest.java

@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra; package org.thingsboard.server.dao.queue.db.nosql;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.junit.Test; import org.junit.Test;
import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.dao.queue.db.nosql.MsgAck;
import org.thingsboard.server.dao.queue.db.nosql.UnprocessedMsgFilter;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;

5
dao/src/test/java/org/thingsboard/server/dao/service/queue/cassandra/repository/impl/CassandraAckRepositoryTest.java → dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraAckRepositoryTest.java

@ -13,18 +13,17 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository.impl; package org.thingsboard.server.dao.queue.db.nosql.repository;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import org.thingsboard.server.dao.service.AbstractServiceTest; import org.thingsboard.server.dao.service.AbstractServiceTest;
import org.thingsboard.server.dao.service.DaoNoSqlTest; import org.thingsboard.server.dao.service.DaoNoSqlTest;
import org.thingsboard.server.dao.service.queue.cassandra.MsgAck; import org.thingsboard.server.dao.queue.db.nosql.MsgAck;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;

3
dao/src/test/java/org/thingsboard/server/dao/service/queue/cassandra/repository/impl/CassandraMsgRepositoryTest.java → dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraMsgRepositoryTest.java

@ -13,13 +13,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository.impl; package org.thingsboard.server.dao.queue.db.nosql.repository;
//import static org.junit.jupiter.api.Assertions.*; //import static org.junit.jupiter.api.Assertions.*;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;

3
dao/src/test/java/org/thingsboard/server/dao/service/queue/cassandra/repository/impl/CassandraProcessedPartitionRepositoryTest.java → dao/src/test/java/org/thingsboard/server/dao/queue/db/nosql/repository/CassandraProcessedPartitionRepositoryTest.java

@ -13,12 +13,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.thingsboard.server.dao.service.queue.cassandra.repository.impl; package org.thingsboard.server.dao.queue.db.nosql.repository;
import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.core.utils.UUIDs;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
Loading…
Cancel
Save