aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2019-02-23 12:12:31 -0800
committerAnton Tananaev <anton.tananaev@gmail.com>2019-02-23 12:12:31 -0800
commit7e239583698a169971f5bd817adbabdacba8dc56 (patch)
tree0914e1641733961352401b7d629542f23b8d6fb3
parentbd909426d24832e42a63503c338bbd8c37176caa (diff)
downloadtrackermap-server-7e239583698a169971f5bd817adbabdacba8dc56.tar.gz
trackermap-server-7e239583698a169971f5bd817adbabdacba8dc56.tar.bz2
trackermap-server-7e239583698a169971f5bd817adbabdacba8dc56.zip
Update filter handler
-rw-r--r--src/org/traccar/BasePipelineFactory.java19
-rw-r--r--src/org/traccar/MainModule.java11
-rw-r--r--src/org/traccar/config/Keys.java75
-rw-r--r--src/org/traccar/processing/FilterHandler.java (renamed from src/org/traccar/FilterHandler.java)82
-rw-r--r--test/org/traccar/FilterHandlerTest.java84
-rw-r--r--test/org/traccar/processing/FilterHandlerTest.java88
6 files changed, 199 insertions, 160 deletions
diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java
index 4bc41bd55..022eeeffa 100644
--- a/src/org/traccar/BasePipelineFactory.java
+++ b/src/org/traccar/BasePipelineFactory.java
@@ -31,6 +31,7 @@ import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.timeout.IdleStateHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.traccar.config.Keys;
import org.traccar.events.CommandResultEventHandler;
import org.traccar.events.DriverEventHandler;
import org.traccar.events.FuelDropEventHandler;
@@ -42,6 +43,7 @@ import org.traccar.events.OverspeedEventHandler;
import org.traccar.events.AlertEventHandler;
import org.traccar.processing.ComputedAttributesHandler;
import org.traccar.processing.CopyAttributesHandler;
+import org.traccar.processing.FilterHandler;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
@@ -54,7 +56,6 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> {
private final TrackerServer server;
private int timeout;
- private FilterHandler filterHandler;
private DistanceHandler distanceHandler;
private EngineHoursHandler engineHoursHandler;
private RemoteAddressHandler remoteAddressHandler;
@@ -199,10 +200,6 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> {
remoteAddressHandler = new RemoteAddressHandler();
}
- if (Context.getConfig().getBoolean("filter.enable")) {
- filterHandler = new FilterHandler();
- }
-
if (Context.getGeocoder() != null && !Context.getConfig().getBoolean("geocoder.ignorePositions")) {
geocoderHandler = new GeocoderHandler(
Context.getGeocoder(),
@@ -304,7 +301,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> {
addHandlers(
pipeline,
- filterHandler,
+ Main.getInjector().getInstance(FilterHandler.class),
geocoderHandler,
motionHandler,
engineHoursHandler,
@@ -332,12 +329,12 @@ public abstract class BasePipelineFactory extends ChannelInitializer<Channel> {
}
private void addDynamicHandlers(ChannelPipeline pipeline) {
- if (Context.getConfig().hasKey("extra.handlers")) {
- String[] handlers = Context.getConfig().getString("extra.handlers").split(",");
- for (String handler : handlers) {
+ String handlers = Context.getConfig().getString(Keys.EXTRA_HANDLERS);
+ if (handlers != null) {
+ for (String handler : handlers.split(",")) {
try {
- pipeline.addLast((ChannelHandler) Class.forName(handler).newInstance());
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException error) {
+ pipeline.addLast((ChannelHandler) Class.forName(handler).getDeclaredConstructor().newInstance());
+ } catch (ReflectiveOperationException error) {
LOGGER.warn("Dynamic handler error", error);
}
}
diff --git a/src/org/traccar/MainModule.java b/src/org/traccar/MainModule.java
index 26bdfcd60..60f774544 100644
--- a/src/org/traccar/MainModule.java
+++ b/src/org/traccar/MainModule.java
@@ -22,6 +22,7 @@ import com.google.inject.Singleton;
import org.traccar.config.Config;
import org.traccar.config.Keys;
import org.traccar.database.IdentityManager;
+import org.traccar.processing.FilterHandler;
import javax.ws.rs.client.Client;
@@ -49,6 +50,16 @@ public class MainModule extends AbstractModule {
@Singleton
@Provides
+ public static FilterHandler provideFilterHandler(Config config) {
+ if (config.getBoolean(Keys.FILTER_ENABLE)) {
+ return new FilterHandler(config);
+ } else {
+ return null;
+ }
+ }
+
+ @Singleton
+ @Provides
public static WebDataHandler provideWebDataHandler(
Config config, IdentityManager identityManager, ObjectMapper objectMapper, Client client) {
if (config.getBoolean(Keys.FORWARD_ENABLE)) {
diff --git a/src/org/traccar/config/Keys.java b/src/org/traccar/config/Keys.java
index 51adfbc13..5b26854ed 100644
--- a/src/org/traccar/config/Keys.java
+++ b/src/org/traccar/config/Keys.java
@@ -17,6 +17,11 @@ package org.traccar.config;
public final class Keys {
+ public static final ConfigKey EXTRA_HANDLERS = new ConfigKey(
+ "extra.handlers",
+ String.class,
+ "List of external handler classes to use in Netty pipeline.");
+
public static final ConfigKey FORWARD_ENABLE = new ConfigKey(
"forward.enable",
Boolean.class,
@@ -38,6 +43,76 @@ public final class Keys {
Boolean.class,
"Boolean value to enable forwarding in JSON format.");
+ public static final ConfigKey FILTER_ENABLE = new ConfigKey(
+ "filter.enable",
+ Boolean.class,
+ "Boolean flag to enable or disable position filtering.");
+
+ public static final ConfigKey FILTER_INVALID = new ConfigKey(
+ "filter.invalid",
+ Boolean.class,
+ "Filter invalid (valid field is set to false) positions.");
+
+ public static final ConfigKey FILTER_ZERO = new ConfigKey(
+ "filter.zero",
+ Boolean.class,
+ "Filter zero coordinates. Zero latitude and longitude are theoretically valid values, but it practice it "
+ + "usually indicates invalid GPS data.");
+
+ public static final ConfigKey FILTER_DUPLICATE = new ConfigKey(
+ "filter.duplicate",
+ Boolean.class,
+ "Filter duplicate records (duplicates are detected by time value).");
+
+ public static final ConfigKey FILTER_FUTURE = new ConfigKey(
+ "filter.future",
+ Long.class,
+ "Filter records with fix time in future. The values is specified in seconds. Records that have fix time "
+ + "more than specified number of seconds later than current server time would be filtered out.");
+
+ public static final ConfigKey FILTER_ACCURACY = new ConfigKey(
+ "filter.accuracy",
+ Integer.class,
+ "Filter positions with accuracy less than specified value in meters.");
+
+ public static final ConfigKey FILTER_APPROXIMATE = new ConfigKey(
+ "filter.approximate",
+ Boolean.class,
+ "Filter cell and wifi locations that are coming from geolocation provider.");
+
+ public static final ConfigKey FILTER_STATIC = new ConfigKey(
+ "filter.static",
+ Boolean.class,
+ "Filter positions with exactly zero speed values.");
+
+ public static final ConfigKey FILTER_DISTANCE = new ConfigKey(
+ "filter.distance",
+ Integer.class,
+ "Filter records by distance. The values is specified in meters. If the new position is less far than this "
+ + "value from the last one it gets filtered out.");
+
+ public static final ConfigKey FILTER_MAX_SPEED = new ConfigKey(
+ "filter.maxSpeed",
+ Integer.class,
+ "Filter records by Maximum Speed value in knots. Can be used to filter jumps to far locations even if "
+ + "they're marked as valid. Shouldn't be too low. Start testing with values at about 25000.");
+
+ public static final ConfigKey FILTER_MIN_PERIOD = new ConfigKey(
+ "filter.minPeriod",
+ Integer.class,
+ "Filter position if time from previous position is less than specified value in seconds.");
+
+ public static final ConfigKey FILTER_SKIP_LIMIT = new ConfigKey(
+ "filter.skipLimit",
+ Long.class,
+ "Time limit for the filtering in seconds. If the time difference between last position and a new one is "
+ + "more than this limit, the new position will not be filtered out.");
+
+ public static final ConfigKey FILTER_SKIP_ATTRIBUTES_ENABLE = new ConfigKey(
+ "filter.skipAttributes.enable",
+ Boolean.class,
+ "Enable attributes skipping. Attribute skipping can be enabled in the config or device attributes");
+
private Keys() {
}
diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/processing/FilterHandler.java
index 6f2bb0d2e..df62b1e6d 100644
--- a/src/org/traccar/FilterHandler.java
+++ b/src/org/traccar/processing/FilterHandler.java
@@ -13,12 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.traccar;
+package org.traccar.processing;
import io.netty.channel.ChannelHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.traccar.BaseDataHandler;
+import org.traccar.Context;
import org.traccar.config.Config;
+import org.traccar.config.Keys;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
@@ -40,70 +43,19 @@ public class FilterHandler extends BaseDataHandler {
private long skipLimit;
private boolean skipAttributes;
- public void setFilterInvalid(boolean filterInvalid) {
- this.filterInvalid = filterInvalid;
- }
-
- public void setFilterZero(boolean filterZero) {
- this.filterZero = filterZero;
- }
-
- public void setFilterDuplicate(boolean filterDuplicate) {
- this.filterDuplicate = filterDuplicate;
- }
-
- public void setFilterFuture(long filterFuture) {
- this.filterFuture = filterFuture;
- }
-
- public void setFilterAccuracy(int filterAccuracy) {
- this.filterAccuracy = filterAccuracy;
- }
-
- public void setFilterApproximate(boolean filterApproximate) {
- this.filterApproximate = filterApproximate;
- }
-
- public void setFilterStatic(boolean filterStatic) {
- this.filterStatic = filterStatic;
- }
-
- public void setFilterDistance(int filterDistance) {
- this.filterDistance = filterDistance;
- }
-
- public void setFilterMaxSpeed(int filterMaxSpeed) {
- this.filterMaxSpeed = filterMaxSpeed;
- }
-
- public void setFilterMinPeriod(int filterMinPeriod) {
- this.filterMinPeriod = filterMinPeriod;
- }
-
- public void setSkipLimit(long skipLimit) {
- this.skipLimit = skipLimit;
- }
-
- public void setSkipAttributes(boolean skipAttributes) {
- this.skipAttributes = skipAttributes;
- }
-
- public FilterHandler() {
- Config config = Context.getConfig();
- if (config != null) {
- filterInvalid = config.getBoolean("filter.invalid");
- filterZero = config.getBoolean("filter.zero");
- filterDuplicate = config.getBoolean("filter.duplicate");
- filterFuture = config.getLong("filter.future") * 1000;
- filterAccuracy = config.getInteger("filter.accuracy");
- filterApproximate = config.getBoolean("filter.approximate");
- filterStatic = config.getBoolean("filter.static");
- filterDistance = config.getInteger("filter.distance");
- filterMaxSpeed = config.getInteger("filter.maxSpeed");
- filterMinPeriod = config.getInteger("filter.minPeriod") * 1000;
- skipLimit = config.getLong("filter.skipLimit") * 1000;
- skipAttributes = config.getBoolean("filter.skipAttributes.enable");
- }
+ public FilterHandler(Config config) {
+ filterInvalid = config.getBoolean(Keys.FILTER_INVALID);
+ filterZero = config.getBoolean(Keys.FILTER_ZERO);
+ filterDuplicate = config.getBoolean(Keys.FILTER_DUPLICATE);
+ filterFuture = config.getLong(Keys.FILTER_FUTURE) * 1000;
+ filterAccuracy = config.getInteger(Keys.FILTER_ACCURACY);
+ filterApproximate = config.getBoolean(Keys.FILTER_APPROXIMATE);
+ filterStatic = config.getBoolean(Keys.FILTER_STATIC);
+ filterDistance = config.getInteger(Keys.FILTER_DISTANCE);
+ filterMaxSpeed = config.getInteger(Keys.FILTER_MAX_SPEED);
+ filterMinPeriod = config.getInteger(Keys.FILTER_MIN_PERIOD) * 1000;
+ skipLimit = config.getLong(Keys.FILTER_SKIP_LIMIT) * 1000;
+ skipAttributes = config.getBoolean(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE);
}
private boolean filterInvalid(Position position) {
diff --git a/test/org/traccar/FilterHandlerTest.java b/test/org/traccar/FilterHandlerTest.java
deleted file mode 100644
index 818583eb7..000000000
--- a/test/org/traccar/FilterHandlerTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.traccar;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.traccar.model.Position;
-
-import java.util.Date;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-public class FilterHandlerTest extends BaseTest {
-
- private FilterHandler filtingHandler;
- private FilterHandler passingHandler;
-
- @Before
- public void setUp() {
- passingHandler = new FilterHandler();
- filtingHandler = new FilterHandler();
- filtingHandler.setFilterInvalid(true);
- filtingHandler.setFilterZero(true);
- filtingHandler.setFilterDuplicate(true);
- filtingHandler.setFilterFuture(5 * 60);
- filtingHandler.setFilterApproximate(true);
- filtingHandler.setFilterStatic(true);
- filtingHandler.setFilterDistance(10);
- filtingHandler.setFilterMaxSpeed(500);
- filtingHandler.setSkipLimit(10);
- }
-
- @After
- public void tearDown() {
- filtingHandler = null;
- passingHandler = null;
- }
-
- private Position createPosition(
- long deviceId,
- Date time,
- boolean valid,
- double latitude,
- double longitude,
- double altitude,
- double speed,
- double course) {
-
- Position p = new Position();
- p.setDeviceId(deviceId);
- p.setTime(time);
- p.setValid(valid);
- p.setLatitude(latitude);
- p.setLongitude(longitude);
- p.setAltitude(altitude);
- p.setSpeed(speed);
- p.setCourse(course);
- return p;
- }
-
- @Test
- public void testFilterInvalid() throws Exception {
-
- Position position = createPosition(0, new Date(), true, 10, 10, 10, 10, 10);
-
- assertNotNull(filtingHandler.handlePosition(position));
- assertNotNull(passingHandler.handlePosition(position));
-
- position = createPosition(0, new Date(Long.MAX_VALUE), true, 10, 10, 10, 10, 10);
-
- assertNull(filtingHandler.handlePosition(position));
- assertNotNull(passingHandler.handlePosition(position));
-
- position = createPosition(0, new Date(), false, 10, 10, 10, 10, 10);
-
- assertNull(filtingHandler.handlePosition(position));
- assertNotNull(passingHandler.handlePosition(position));
-
- position.set(Position.KEY_ALARM, Position.ALARM_GENERAL);
- filtingHandler.setSkipAttributes(true);
- assertNotNull(filtingHandler.handlePosition(position));
- }
-
-}
diff --git a/test/org/traccar/processing/FilterHandlerTest.java b/test/org/traccar/processing/FilterHandlerTest.java
new file mode 100644
index 000000000..e0e9a9912
--- /dev/null
+++ b/test/org/traccar/processing/FilterHandlerTest.java
@@ -0,0 +1,88 @@
+package org.traccar.processing;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.traccar.BaseTest;
+import org.traccar.config.Config;
+import org.traccar.config.Keys;
+import org.traccar.model.Position;
+
+import java.util.Date;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class FilterHandlerTest extends BaseTest {
+
+ private FilterHandler passingHandler = new FilterHandler(new Config());
+ private FilterHandler filteringHandler;
+
+ @Before
+ public void before() {
+ Config config = new Config();
+ config.setString(Keys.FILTER_INVALID, String.valueOf(true));
+ config.setString(Keys.FILTER_ZERO, String.valueOf(true));
+ config.setString(Keys.FILTER_DUPLICATE, String.valueOf(true));
+ config.setString(Keys.FILTER_FUTURE, String.valueOf(5 * 60));
+ config.setString(Keys.FILTER_APPROXIMATE, String.valueOf(true));
+ config.setString(Keys.FILTER_STATIC, String.valueOf(true));
+ config.setString(Keys.FILTER_DISTANCE, String.valueOf(10));
+ config.setString(Keys.FILTER_MAX_SPEED, String.valueOf(500));
+ config.setString(Keys.FILTER_SKIP_LIMIT, String.valueOf(10));
+ config.setString(Keys.FILTER_SKIP_ATTRIBUTES_ENABLE, String.valueOf(true));
+ filteringHandler = new FilterHandler(config);
+ }
+
+ private Position createPosition(
+ long deviceId,
+ Date time,
+ boolean valid,
+ double latitude,
+ double longitude,
+ double altitude,
+ double speed,
+ double course) {
+
+ Position position = new Position();
+ position.setDeviceId(deviceId);
+ position.setTime(time);
+ position.setValid(valid);
+ position.setLatitude(latitude);
+ position.setLongitude(longitude);
+ position.setAltitude(altitude);
+ position.setSpeed(speed);
+ position.setCourse(course);
+ return position;
+ }
+
+ @Test
+ public void testFilter() {
+
+ Position position = createPosition(0, new Date(), true, 10, 10, 10, 10, 10);
+
+ assertNotNull(filteringHandler.handlePosition(position));
+ assertNotNull(passingHandler.handlePosition(position));
+
+ position = createPosition(0, new Date(Long.MAX_VALUE), true, 10, 10, 10, 10, 10);
+
+ assertNull(filteringHandler.handlePosition(position));
+ assertNotNull(passingHandler.handlePosition(position));
+
+ position = createPosition(0, new Date(), false, 10, 10, 10, 10, 10);
+
+ assertNull(filteringHandler.handlePosition(position));
+ assertNotNull(passingHandler.handlePosition(position));
+
+ }
+
+ @Test
+ public void testSkipAttributes() {
+
+ Position position = createPosition(0, new Date(), false, 10, 10, 10, 10, 10);
+ position.set(Position.KEY_ALARM, Position.ALARM_GENERAL);
+
+ assertNotNull(filteringHandler.handlePosition(position));
+
+ }
+
+}