fix: clear mqtt pending commands on request
This commit is contained in:
@@ -132,6 +132,15 @@ public class MqttCommandAckService implements IDeviceCommandAckHandler {
|
||||
pendingIds().add(command.getCommandId());
|
||||
}
|
||||
|
||||
public int clearPendingCommands() {
|
||||
Set<String> commandIds = pendingIds().readAll();
|
||||
for (String commandId : commandIds) {
|
||||
RedisUtils.deleteObject(pendingKey(commandId));
|
||||
}
|
||||
pendingIds().clear();
|
||||
return commandIds.size();
|
||||
}
|
||||
|
||||
public void removePending(String commandId) {
|
||||
if (StringUtils.isBlank(commandId)) {
|
||||
return;
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.test.util.ReflectionTestUtils;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -97,6 +98,48 @@ class MqttCommandAckServiceTest {
|
||||
assertThat(MqttCommandAckService.ackMatchesPendingCommand("D01", null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void clearPendingCommandsDeletesPendingObjectsAndClearsIds() {
|
||||
MqttProperties properties = new MqttProperties();
|
||||
AppDeviceMapper appDeviceMapper = mock(AppDeviceMapper.class);
|
||||
RedissonClient redissonClient = mock(RedissonClient.class);
|
||||
RSet<String> pendingIds = mock(RSet.class);
|
||||
when(redissonClient.<String>getSet("mqtt:command:pending:ids")).thenReturn(pendingIds);
|
||||
when(pendingIds.readAll()).thenReturn(Set.of("cmd-1", "cmd-2"));
|
||||
|
||||
MqttCommandAckService service = new MqttCommandAckService(properties, appDeviceMapper);
|
||||
try (MockedStatic<RedisUtils> redis = mockStatic(RedisUtils.class)) {
|
||||
redis.when(RedisUtils::getClient).thenReturn(redissonClient);
|
||||
|
||||
int cleared = service.clearPendingCommands();
|
||||
|
||||
assertThat(cleared).isEqualTo(2);
|
||||
redis.verify(() -> RedisUtils.deleteObject("mqtt:command:pending:cmd-1"));
|
||||
redis.verify(() -> RedisUtils.deleteObject("mqtt:command:pending:cmd-2"));
|
||||
verify(pendingIds).clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void clearPendingCommandsReturnsZeroForEmptySet() {
|
||||
MqttProperties properties = new MqttProperties();
|
||||
AppDeviceMapper appDeviceMapper = mock(AppDeviceMapper.class);
|
||||
RedissonClient redissonClient = mock(RedissonClient.class);
|
||||
RSet<String> pendingIds = mock(RSet.class);
|
||||
when(redissonClient.<String>getSet("mqtt:command:pending:ids")).thenReturn(pendingIds);
|
||||
when(pendingIds.readAll()).thenReturn(Set.of());
|
||||
|
||||
MqttCommandAckService service = new MqttCommandAckService(properties, appDeviceMapper);
|
||||
try (MockedStatic<RedisUtils> redis = mockStatic(RedisUtils.class)) {
|
||||
redis.when(RedisUtils::getClient).thenReturn(redissonClient);
|
||||
|
||||
int cleared = service.clearPendingCommands();
|
||||
|
||||
assertThat(cleared).isZero();
|
||||
verify(pendingIds).clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void handleAckWaitsBrieflyForCommandLock() throws Exception {
|
||||
MqttProperties properties = new MqttProperties();
|
||||
|
||||
Reference in New Issue
Block a user