aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/traccar/config/Keys.java7
-rw-r--r--src/main/java/org/traccar/database/StatisticsManager.java7
-rw-r--r--src/main/java/org/traccar/handler/FilterHandler.java15
-rw-r--r--src/test/java/org/traccar/handler/FilterHandlerTest.java4
4 files changed, 30 insertions, 3 deletions
diff --git a/src/main/java/org/traccar/config/Keys.java b/src/main/java/org/traccar/config/Keys.java
index 1ff1d1b51..04bf10fe7 100644
--- a/src/main/java/org/traccar/config/Keys.java
+++ b/src/main/java/org/traccar/config/Keys.java
@@ -1328,6 +1328,13 @@ public final class Keys {
List.of(KeyType.CONFIG));
/**
+ * Filter position if the daily limit is exceeded for the device.
+ */
+ public static final ConfigKey<Integer> FILTER_DAILY_LIMIT = new IntegerConfigKey(
+ "filter.dailyLimit",
+ List.of(KeyType.CONFIG));
+
+ /**
* If false, the server expects all locations to come sequentially (for each device). Filter checks for duplicates,
* distance, speed, or time period only against the location that was last received by server.
* If true, the server expects locations to come at random order (since tracking device might go offline).
diff --git a/src/main/java/org/traccar/database/StatisticsManager.java b/src/main/java/org/traccar/database/StatisticsManager.java
index c8a36bf78..e417c8901 100644
--- a/src/main/java/org/traccar/database/StatisticsManager.java
+++ b/src/main/java/org/traccar/database/StatisticsManager.java
@@ -58,6 +58,7 @@ public class StatisticsManager {
private final Set<Long> users = new HashSet<>();
private final Map<Long, String> deviceProtocols = new HashMap<>();
+ private final Map<Long, Integer> deviceMessages = new HashMap<>();
private int requests;
private int messagesReceived;
@@ -101,6 +102,7 @@ public class StatisticsManager {
users.clear();
deviceProtocols.clear();
+ deviceMessages.clear();
requests = 0;
messagesReceived = 0;
messagesStored = 0;
@@ -163,9 +165,14 @@ public class StatisticsManager {
messagesStored += 1;
if (deviceId != 0) {
deviceProtocols.put(deviceId, protocol);
+ deviceMessages.merge(deviceId, 1, Integer::sum);
}
}
+ public synchronized int messageStoredCount(long deviceId) {
+ return deviceMessages.getOrDefault(deviceId, 0);
+ }
+
public synchronized void registerMail() {
checkSplit();
mailSent += 1;
diff --git a/src/main/java/org/traccar/handler/FilterHandler.java b/src/main/java/org/traccar/handler/FilterHandler.java
index 9ff94deb0..37c3beddf 100644
--- a/src/main/java/org/traccar/handler/FilterHandler.java
+++ b/src/main/java/org/traccar/handler/FilterHandler.java
@@ -22,6 +22,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.traccar.config.Config;
import org.traccar.config.Keys;
+import org.traccar.database.StatisticsManager;
import org.traccar.helper.UnitsConverter;
import org.traccar.helper.model.AttributeUtil;
import org.traccar.model.Device;
@@ -57,15 +58,18 @@ public class FilterHandler extends ChannelInboundHandlerAdapter {
private final int filterDistance;
private final int filterMaxSpeed;
private final long filterMinPeriod;
+ private final int filterDailyLimit;
private final boolean filterRelative;
private final long skipLimit;
private final boolean skipAttributes;
private final CacheManager cacheManager;
private final Storage storage;
+ private final StatisticsManager statisticsManager;
@Inject
- public FilterHandler(Config config, CacheManager cacheManager, Storage storage) {
+ public FilterHandler(
+ Config config, CacheManager cacheManager, Storage storage, StatisticsManager statisticsManager) {
enabled = config.getBoolean(Keys.FILTER_ENABLE);
filterInvalid = config.getBoolean(Keys.FILTER_INVALID);
filterZero = config.getBoolean(Keys.FILTER_ZERO);
@@ -79,11 +83,13 @@ public class FilterHandler extends ChannelInboundHandlerAdapter {
filterDistance = config.getInteger(Keys.FILTER_DISTANCE);
filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED);
filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000L;
+ filterDailyLimit = config.getInteger(Keys.FILTER_DAILY_LIMIT);
filterRelative = config.getBoolean(Keys.FILTER_RELATIVE);
skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000;
skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE);
this.cacheManager = cacheManager;
this.storage = storage;
+ this.statisticsManager = statisticsManager;
}
private Position getPrecedingPosition(long deviceId, Date date) throws StorageException {
@@ -165,6 +171,13 @@ public class FilterHandler extends ChannelInboundHandlerAdapter {
return false;
}
+ private boolean filterDailyLimit(Position position) {
+ if (filterDailyLimit != 0) {
+ return statisticsManager.messageStoredCount(position.getDeviceId()) >= filterDailyLimit;
+ }
+ return false;
+ }
+
private boolean skipLimit(Position position, Position last) {
if (skipLimit != 0 && last != null) {
return (position.getServerTime().getTime() - last.getServerTime().getTime()) > skipLimit;
diff --git a/src/test/java/org/traccar/handler/FilterHandlerTest.java b/src/test/java/org/traccar/handler/FilterHandlerTest.java
index 26281e351..14037f723 100644
--- a/src/test/java/org/traccar/handler/FilterHandlerTest.java
+++ b/src/test/java/org/traccar/handler/FilterHandlerTest.java
@@ -29,7 +29,7 @@ public class FilterHandlerTest extends BaseTest {
when(config.getBoolean(Keys.FILTER_ENABLE)).thenReturn(true);
var cacheManager = mock(CacheManager.class);
when(cacheManager.getConfig()).thenReturn(config);
- passingHandler = new FilterHandler(config, cacheManager, null);
+ passingHandler = new FilterHandler(config, cacheManager, null, null);
}
@BeforeEach
@@ -50,7 +50,7 @@ public class FilterHandlerTest extends BaseTest {
var cacheManager = mock(CacheManager.class);
when(cacheManager.getConfig()).thenReturn(config);
when(cacheManager.getObject(any(), anyLong())).thenReturn(mock(Device.class));
- filteringHandler = new FilterHandler(config, cacheManager, null);
+ filteringHandler = new FilterHandler(config, cacheManager, null, null);
}
private Position createPosition(Date time, boolean valid, double speed) {