From 98993ee219b6c0cb31f2f3b1608d378b2e028535 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Feb 2019 10:45:26 -0800 Subject: Refactor geolocation --- src/org/traccar/BasePipelineFactory.java | 10 +-- src/org/traccar/BaseProtocolDecoder.java | 3 +- src/org/traccar/Context.java | 75 +++------------------ src/org/traccar/GeocoderHandler.java | 3 +- src/org/traccar/GeolocationHandler.java | 78 --------------------- src/org/traccar/Main.java | 8 ++- src/org/traccar/MainEventHandler.java | 3 +- src/org/traccar/MainModule.java | 51 ++++++++++++++ src/org/traccar/api/MediaFilter.java | 4 +- src/org/traccar/api/SecurityRequestFilter.java | 6 +- src/org/traccar/config/Keys.java | 35 ++++++++++ src/org/traccar/database/MailManager.java | 3 +- src/org/traccar/database/StatisticsManager.java | 26 +++++-- src/org/traccar/handler/GeolocationHandler.java | 86 ++++++++++++++++++++++++ src/org/traccar/model/Server.java | 5 +- src/org/traccar/notificators/NotificatorSms.java | 6 +- 16 files changed, 232 insertions(+), 170 deletions(-) delete mode 100644 src/org/traccar/GeolocationHandler.java create mode 100644 src/org/traccar/handler/GeolocationHandler.java (limited to 'src/org') diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index d5a90390e..b993e0741 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -38,6 +38,7 @@ import org.traccar.handler.ComputedAttributesHandler; import org.traccar.handler.CopyAttributesHandler; import org.traccar.handler.DistanceHandler; import org.traccar.handler.FilterHandler; +import org.traccar.handler.GeolocationHandler; import org.traccar.handler.NetworkMessageHandler; import org.traccar.handler.OpenChannelHandler; import org.traccar.handler.RemoteAddressHandler; @@ -55,7 +56,6 @@ public abstract class BasePipelineFactory extends ChannelInitializer { private EngineHoursHandler engineHoursHandler; private MotionHandler motionHandler; private GeocoderHandler geocoderHandler; - private GeolocationHandler geolocationHandler; private HemisphereHandler hemisphereHandler; private CopyAttributesHandler copyAttributesHandler; private ComputedAttributesHandler computedAttributesHandler; @@ -84,12 +84,6 @@ public abstract class BasePipelineFactory extends ChannelInitializer { Context.getConfig().getBoolean("geocoder.processInvalidPositions")); } - if (Context.getGeolocationProvider() != null) { - geolocationHandler = new GeolocationHandler( - Context.getGeolocationProvider(), - Context.getConfig().getBoolean("geolocation.processInvalidPositions")); - } - motionHandler = new MotionHandler(Context.getTripsConfig().getSpeedThreshold()); if (Context.getConfig().getBoolean("processing.engineHours.enable")) { @@ -171,7 +165,7 @@ public abstract class BasePipelineFactory extends ChannelInitializer { addHandlers( pipeline, - geolocationHandler, + Main.getInjector().getInstance(GeolocationHandler.class), hemisphereHandler, Main.getInjector().getInstance(DistanceHandler.class), Main.getInjector().getInstance(RemoteAddressHandler.class)); diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index e1efbd3eb..aa5be612e 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -45,11 +45,12 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { private final Config config = Context.getConfig(); private final IdentityManager identityManager = Context.getIdentityManager(); private final ConnectionManager connectionManager = Context.getConnectionManager(); - private final StatisticsManager statisticsManager = Context.getStatisticsManager(); + private final StatisticsManager statisticsManager; private final Protocol protocol; public BaseProtocolDecoder(Protocol protocol) { this.protocol = protocol; + statisticsManager = Main.getInjector() != null ? Main.getInjector().getInstance(StatisticsManager.class) : null; } public String getProtocolName() { diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index d9fed22ec..e507406e8 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,25 +17,22 @@ package org.traccar; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Properties; - import com.fasterxml.jackson.datatype.jsr353.JSR353Module; import org.apache.velocity.app.VelocityEngine; import org.eclipse.jetty.util.URIUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.config.Config; -import org.traccar.database.CalendarManager; -import org.traccar.database.CommandsManager; import org.traccar.database.AttributesManager; import org.traccar.database.BaseObjectManager; +import org.traccar.database.CalendarManager; +import org.traccar.database.CommandsManager; import org.traccar.database.ConnectionManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.DriversManager; +import org.traccar.database.GeofenceManager; +import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.LdapProvider; import org.traccar.database.MailManager; @@ -43,27 +40,23 @@ import org.traccar.database.MaintenancesManager; import org.traccar.database.MediaManager; import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; -import org.traccar.database.GeofenceManager; -import org.traccar.database.GroupsManager; -import org.traccar.database.StatisticsManager; import org.traccar.database.UsersManager; import org.traccar.events.MotionEventHandler; import org.traccar.events.OverspeedEventHandler; import org.traccar.geocoder.AddressFormat; +import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.BingMapsGeocoder; import org.traccar.geocoder.FactualGeocoder; import org.traccar.geocoder.GeocodeFarmGeocoder; import org.traccar.geocoder.GeocodeXyzGeocoder; +import org.traccar.geocoder.Geocoder; import org.traccar.geocoder.GisgraphyGeocoder; -import org.traccar.geocoder.BanGeocoder; import org.traccar.geocoder.GoogleGeocoder; import org.traccar.geocoder.HereGeocoder; import org.traccar.geocoder.MapQuestGeocoder; +import org.traccar.geocoder.MapmyIndiaGeocoder; import org.traccar.geocoder.NominatimGeocoder; import org.traccar.geocoder.OpenCageGeocoder; -import org.traccar.geocoder.MapmyIndiaGeocoder; -import org.traccar.geocoder.Geocoder; -import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.helper.Log; import org.traccar.helper.SanitizerModule; import org.traccar.model.Attribute; @@ -77,10 +70,6 @@ import org.traccar.model.Group; import org.traccar.model.Maintenance; import org.traccar.model.Notification; import org.traccar.model.User; -import org.traccar.geolocation.GoogleGeolocationProvider; -import org.traccar.geolocation.GeolocationProvider; -import org.traccar.geolocation.MozillaGeolocationProvider; -import org.traccar.geolocation.OpenCellIdGeolocationProvider; import org.traccar.notification.EventForwarder; import org.traccar.notification.JsonTypeEventForwarder; import org.traccar.notification.NotificatorManager; @@ -92,6 +81,9 @@ import org.traccar.web.WebServer; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.ext.ContextResolver; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Properties; public final class Context { @@ -100,10 +92,6 @@ public final class Context { private Context() { } - public static String getAppVersion() { - return Context.class.getPackage().getImplementationVersion(); - } - private static Config config; public static Config getConfig() { @@ -182,12 +170,6 @@ public final class Context { return geocoder; } - private static GeolocationProvider geolocationProvider; - - public static GeolocationProvider getGeolocationProvider() { - return geolocationProvider; - } - private static WebServer webServer; public static WebServer getWebServer() { @@ -266,12 +248,6 @@ public final class Context { return maintenancesManager; } - private static StatisticsManager statisticsManager; - - public static StatisticsManager getStatisticsManager() { - return statisticsManager; - } - private static SmsManager smsManager; public static SmsManager getSmsManager() { @@ -385,7 +361,6 @@ public final class Context { client = ClientBuilder.newClient().register(new ObjectMapperContextResolver()); - if (config.hasKey("database.url")) { dataManager = new DataManager(config); } @@ -410,10 +385,6 @@ public final class Context { geocoder = initGeocoder(); } - if (config.getBoolean("geolocation.enable")) { - initGeolocationModule(); - } - if (config.getBoolean("web.enable")) { webServer = new WebServer(config); } @@ -449,30 +420,6 @@ public final class Context { commandsManager = new CommandsManager(dataManager, config.getBoolean("commands.queueing")); - statisticsManager = new StatisticsManager(); - - } - - private static void initGeolocationModule() { - - String type = config.getString("geolocation.type", "mozilla"); - String url = config.getString("geolocation.url"); - String key = config.getString("geolocation.key"); - - switch (type) { - case "google": - geolocationProvider = new GoogleGeolocationProvider(key); - break; - case "opencellid": - geolocationProvider = new OpenCellIdGeolocationProvider(key); - break; - case "unwired": - geolocationProvider = new UnwiredGeolocationProvider(url, key); - break; - default: - geolocationProvider = new MozillaGeolocationProvider(key); - break; - } } private static void initEventsModule() { diff --git a/src/org/traccar/GeocoderHandler.java b/src/org/traccar/GeocoderHandler.java index 72f164948..4154e287c 100644 --- a/src/org/traccar/GeocoderHandler.java +++ b/src/org/traccar/GeocoderHandler.java @@ -20,6 +20,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.database.StatisticsManager; import org.traccar.geocoder.Geocoder; import org.traccar.model.Position; @@ -54,7 +55,7 @@ public class GeocoderHandler extends ChannelInboundHandlerAdapter { } } - Context.getStatisticsManager().registerGeocoderRequest(); + Main.getInjector().getInstance(StatisticsManager.class).registerGeocoderRequest(); geocoder.getAddress(position.getLatitude(), position.getLongitude(), new Geocoder.ReverseGeocoderCallback() { diff --git a/src/org/traccar/GeolocationHandler.java b/src/org/traccar/GeolocationHandler.java deleted file mode 100644 index 97b5fda6a..000000000 --- a/src/org/traccar/GeolocationHandler.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) - * - * 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.traccar; - -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.geolocation.GeolocationProvider; -import org.traccar.model.Position; - -@ChannelHandler.Sharable -public class GeolocationHandler extends ChannelInboundHandlerAdapter { - - private static final Logger LOGGER = LoggerFactory.getLogger(GeolocationHandler.class); - - private final GeolocationProvider geolocationProvider; - private final boolean processInvalidPositions; - - public GeolocationHandler(GeolocationProvider geolocationProvider, boolean processInvalidPositions) { - this.geolocationProvider = geolocationProvider; - this.processInvalidPositions = processInvalidPositions; - } - - @Override - public void channelRead(final ChannelHandlerContext ctx, Object message) throws Exception { - if (message instanceof Position) { - final Position position = (Position) message; - if ((position.getOutdated() || processInvalidPositions && !position.getValid()) - && position.getNetwork() != null) { - Context.getStatisticsManager().registerGeolocationRequest(); - - geolocationProvider.getLocation(position.getNetwork(), - new GeolocationProvider.LocationProviderCallback() { - @Override - public void onSuccess(double latitude, double longitude, double accuracy) { - position.set(Position.KEY_APPROXIMATE, true); - position.setValid(true); - position.setFixTime(position.getDeviceTime()); - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setAccuracy(accuracy); - position.setAltitude(0); - position.setSpeed(0); - position.setCourse(0); - position.set(Position.KEY_RSSI, 0); - ctx.fireChannelRead(position); - } - - @Override - public void onFailure(Throwable e) { - LOGGER.warn("Geolocation network error", e); - ctx.fireChannelRead(position); - } - }); - } else { - ctx.fireChannelRead(position); - } - } else { - ctx.fireChannelRead(message); - } - } - -} diff --git a/src/org/traccar/Main.java b/src/org/traccar/Main.java index c85d93431..ff97dfd94 100644 --- a/src/org/traccar/Main.java +++ b/src/org/traccar/Main.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,10 @@ public final class Main { return injector; } + public static String getAppVersion() { + return Context.class.getPackage().getImplementationVersion(); + } + private Main() { } @@ -110,7 +114,7 @@ public final class Main { Context.init(configFile); injector = Guice.createInjector(new MainModule()); logSystemInfo(); - LOGGER.info("Version: " + Context.getAppVersion()); + LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); LOGGER.info("Starting server..."); Context.getServerManager().start(); diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index 75dafcc29..1137bfc24 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -23,6 +23,7 @@ import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.timeout.IdleStateEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.traccar.database.StatisticsManager; import org.traccar.helper.DateUtil; import org.traccar.model.Position; @@ -108,7 +109,7 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { } LOGGER.info(builder.toString()); - Context.getStatisticsManager().registerMessageStored(position.getDeviceId()); + Main.getInjector().getInstance(StatisticsManager.class).registerMessageStored(position.getDeviceId()); } } diff --git a/src/org/traccar/MainModule.java b/src/org/traccar/MainModule.java index d9ff93b21..3b9bbe4b6 100644 --- a/src/org/traccar/MainModule.java +++ b/src/org/traccar/MainModule.java @@ -21,11 +21,20 @@ import com.google.inject.Provides; import com.google.inject.Singleton; import org.traccar.config.Config; import org.traccar.config.Keys; +import org.traccar.database.DataManager; import org.traccar.database.IdentityManager; +import org.traccar.database.StatisticsManager; +import org.traccar.geolocation.GeolocationProvider; +import org.traccar.geolocation.GoogleGeolocationProvider; +import org.traccar.geolocation.MozillaGeolocationProvider; +import org.traccar.geolocation.OpenCellIdGeolocationProvider; +import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.DistanceHandler; import org.traccar.handler.FilterHandler; +import org.traccar.handler.GeolocationHandler; import org.traccar.handler.RemoteAddressHandler; +import javax.annotation.Nullable; import javax.ws.rs.client.Client; public class MainModule extends AbstractModule { @@ -40,6 +49,11 @@ public class MainModule extends AbstractModule { return Context.getConfig(); } + @Provides + public static DataManager provideDataManager() { + return Context.getDataManager(); + } + @Provides public static IdentityManager provideIdentityManager() { return Context.getIdentityManager(); @@ -50,6 +64,33 @@ public class MainModule extends AbstractModule { return Context.getClient(); } + @Singleton + @Provides + public static StatisticsManager provideStatisticsManager(Config config, DataManager dataManager, Client client) { + return new StatisticsManager(config, dataManager, client); + } + + @Singleton + @Provides + public static GeolocationProvider provideGeolocationProvider(Config config) { + if (config.getBoolean(Keys.GEOLOCATION_ENABLE)) { + String type = config.getString(Keys.GEOLOCATION_TYPE, "mozilla"); + String url = config.getString(Keys.GEOLOCATION_URL); + String key = config.getString(Keys.GEOLOCATION_KEY); + switch (type) { + case "google": + return new GoogleGeolocationProvider(key); + case "opencellid": + return new OpenCellIdGeolocationProvider(key); + case "unwired": + return new UnwiredGeolocationProvider(url, key); + default: + return new MozillaGeolocationProvider(key); + } + } + return null; + } + @Singleton @Provides public static DistanceHandler provideDistanceHandler(Config config, IdentityManager identityManager) { @@ -84,6 +125,16 @@ public class MainModule extends AbstractModule { return null; } + @Singleton + @Provides + public static GeolocationHandler provideGeolocationHandler( + Config config, @Nullable GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { + if (geolocationProvider != null) { + return new GeolocationHandler(config, geolocationProvider, statisticsManager); + } + return null; + } + @Override protected void configure() { binder().requireExplicitBindings(); diff --git a/src/org/traccar/api/MediaFilter.java b/src/org/traccar/api/MediaFilter.java index 25e242b01..53539770f 100644 --- a/src/org/traccar/api/MediaFilter.java +++ b/src/org/traccar/api/MediaFilter.java @@ -30,7 +30,9 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.traccar.Context; +import org.traccar.Main; import org.traccar.api.resource.SessionResource; +import org.traccar.database.StatisticsManager; import org.traccar.helper.Log; import org.traccar.model.Device; @@ -51,7 +53,7 @@ public class MediaFilter implements Filter { userId = (Long) session.getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { Context.getPermissionsManager().checkUserEnabled(userId); - Context.getStatisticsManager().registerRequest(userId); + Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); } } if (userId == null) { diff --git a/src/org/traccar/api/SecurityRequestFilter.java b/src/org/traccar/api/SecurityRequestFilter.java index 195c1f72f..33b6b37df 100644 --- a/src/org/traccar/api/SecurityRequestFilter.java +++ b/src/org/traccar/api/SecurityRequestFilter.java @@ -18,7 +18,9 @@ package org.traccar.api; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.api.resource.SessionResource; +import org.traccar.database.StatisticsManager; import org.traccar.helper.DataConverter; import org.traccar.model.User; @@ -77,7 +79,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { String[] auth = decodeBasicAuth(authHeader); User user = Context.getPermissionsManager().login(auth[0], auth[1]); if (user != null) { - Context.getStatisticsManager().registerRequest(user.getId()); + Main.getInjector().getInstance(StatisticsManager.class).registerRequest(user.getId()); securityContext = new UserSecurityContext(new UserPrincipal(user.getId())); } } catch (SQLException e) { @@ -89,7 +91,7 @@ public class SecurityRequestFilter implements ContainerRequestFilter { Long userId = (Long) request.getSession().getAttribute(SessionResource.USER_ID_KEY); if (userId != null) { Context.getPermissionsManager().checkUserEnabled(userId); - Context.getStatisticsManager().registerRequest(userId); + Main.getInjector().getInstance(StatisticsManager.class).registerRequest(userId); securityContext = new UserSecurityContext(new UserPrincipal(userId)); } diff --git a/src/org/traccar/config/Keys.java b/src/org/traccar/config/Keys.java index 655a61c1d..068512de8 100644 --- a/src/org/traccar/config/Keys.java +++ b/src/org/traccar/config/Keys.java @@ -30,6 +30,12 @@ public final class Keys { Integer.class, "Server wide connection timeout value in seconds. See protocol timeout for more information."); + public static final ConfigKey SERVER_STATISTICS = new ConfigKey( + "server.statistics", + Boolean.class, + "Address for uploading aggregated anonymous usage statistics. Uploaded information is the same you can see " + + "on the statistics screen in the web app. It does not include any sensitive (e.g. locations)."); + public static final ConfigKey EXTRA_HANDLERS = new ConfigKey( "extra.handlers", String.class, @@ -148,6 +154,35 @@ public final class Keys { Boolean.class, "Enable to save device IP addresses information. Disabled by default."); + public static final ConfigKey GEOLOCATION_ENABLE = new ConfigKey( + "geolocation.enable", + Boolean.class, + "Boolean flag to enable LBS location resolution. Some devices send cell towers information and WiFi point " + + "when GPS location is not available. Traccar can determine coordinates based on that information " + + "using third party services. Default value is false."); + + public static final ConfigKey GEOLOCATION_TYPE = new ConfigKey( + "geolocation.type", + String.class, + "Provider to use for LBS location. Available options: google, mozilla and opencellid. By default " + + "opencellid is used. You have to supply a key that you get from corresponding provider. For more " + + "information see LBS geolocation documentation."); + + public static final ConfigKey GEOLOCATION_URL = new ConfigKey( + "geolocation.url", + String.class, + "Geolocation provider URL address."); + + public static final ConfigKey GEOLOCATION_KEY = new ConfigKey( + "geolocation.key", + String.class, + "Provider API key. OpenCellID service requires API key."); + + public static final ConfigKey GEOLOCATION_PROCESS_INVALID_POSITIONS = new ConfigKey( + "geolocation.processInvalidPositions", + Boolean.class, + "Boolean flag to apply geolocation to invalid positions."); + private Keys() { } diff --git a/src/org/traccar/database/MailManager.java b/src/org/traccar/database/MailManager.java index e64aa638a..8a2f002cd 100644 --- a/src/org/traccar/database/MailManager.java +++ b/src/org/traccar/database/MailManager.java @@ -19,6 +19,7 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.Context; +import org.traccar.Main; import org.traccar.model.User; import org.traccar.notification.PropertiesProvider; @@ -134,7 +135,7 @@ public final class MailManager { } try (Transport transport = session.getTransport()) { - Context.getStatisticsManager().registerMail(); + Main.getInjector().getInstance(StatisticsManager.class).registerMail(); transport.connect( properties.getProperty("mail.smtp.host"), properties.getProperty("mail.smtp.username"), diff --git a/src/org/traccar/database/StatisticsManager.java b/src/org/traccar/database/StatisticsManager.java index 4e656bfd8..e59f8e767 100644 --- a/src/org/traccar/database/StatisticsManager.java +++ b/src/org/traccar/database/StatisticsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,13 @@ package org.traccar.database; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; +import org.traccar.config.Config; +import org.traccar.config.Keys; import org.traccar.helper.DateUtil; import org.traccar.model.Statistics; +import javax.inject.Inject; +import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Form; import java.sql.SQLException; @@ -36,6 +39,10 @@ public class StatisticsManager { private static final int SPLIT_MODE = Calendar.DAY_OF_MONTH; + private final Config config; + private final DataManager dataManager; + private final Client client; + private AtomicInteger lastUpdate = new AtomicInteger(Calendar.getInstance().get(SPLIT_MODE)); private Set users = new HashSet<>(); @@ -49,6 +56,13 @@ public class StatisticsManager { private int geocoderRequests; private int geolocationRequests; + @Inject + public StatisticsManager(Config config, DataManager dataManager, Client client) { + this.config = config; + this.dataManager = dataManager; + this.client = client; + } + private void checkSplit() { int currentUpdate = Calendar.getInstance().get(SPLIT_MODE); if (lastUpdate.getAndSet(currentUpdate) != currentUpdate) { @@ -65,17 +79,17 @@ public class StatisticsManager { statistics.setGeolocationRequests(geolocationRequests); try { - Context.getDataManager().addObject(statistics); + dataManager.addObject(statistics); } catch (SQLException e) { LOGGER.warn("Error saving statistics", e); } - String url = Context.getConfig().getString("server.statistics"); + String url = config.getString(Keys.SERVER_STATISTICS); if (url != null) { String time = DateUtil.formatDate(statistics.getCaptureTime()); Form form = new Form(); - form.param("version", Context.getAppVersion()); + form.param("version", getClass().getPackage().getImplementationVersion()); form.param("captureTime", time); form.param("activeUsers", String.valueOf(statistics.getActiveUsers())); form.param("activeDevices", String.valueOf(statistics.getActiveDevices())); @@ -87,7 +101,7 @@ public class StatisticsManager { form.param("geocoderRequests", String.valueOf(statistics.getGeocoderRequests())); form.param("geolocationRequests", String.valueOf(statistics.getGeolocationRequests())); - Context.getClient().target(url).request().async().post(Entity.form(form)); + client.target(url).request().async().post(Entity.form(form)); } users.clear(); diff --git a/src/org/traccar/handler/GeolocationHandler.java b/src/org/traccar/handler/GeolocationHandler.java new file mode 100644 index 000000000..c7b39e491 --- /dev/null +++ b/src/org/traccar/handler/GeolocationHandler.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * + * 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.traccar.handler; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +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.geolocation.GeolocationProvider; +import org.traccar.model.Position; + +@ChannelHandler.Sharable +public class GeolocationHandler extends ChannelInboundHandlerAdapter { + + private static final Logger LOGGER = LoggerFactory.getLogger(GeolocationHandler.class); + + private final GeolocationProvider geolocationProvider; + private final StatisticsManager statisticsManager; + private final boolean processInvalidPositions; + + public GeolocationHandler( + Config config, GeolocationProvider geolocationProvider, StatisticsManager statisticsManager) { + this.geolocationProvider = geolocationProvider; + this.statisticsManager = statisticsManager; + this.processInvalidPositions = config.getBoolean(Keys.GEOLOCATION_PROCESS_INVALID_POSITIONS); + } + + @Override + public void channelRead(final ChannelHandlerContext ctx, Object message) { + if (message instanceof Position) { + final Position position = (Position) message; + if ((position.getOutdated() || processInvalidPositions && !position.getValid()) + && position.getNetwork() != null) { + if (statisticsManager != null) { + statisticsManager.registerGeolocationRequest(); + } + + geolocationProvider.getLocation(position.getNetwork(), + new GeolocationProvider.LocationProviderCallback() { + @Override + public void onSuccess(double latitude, double longitude, double accuracy) { + position.set(Position.KEY_APPROXIMATE, true); + position.setValid(true); + position.setFixTime(position.getDeviceTime()); + position.setLatitude(latitude); + position.setLongitude(longitude); + position.setAccuracy(accuracy); + position.setAltitude(0); + position.setSpeed(0); + position.setCourse(0); + position.set(Position.KEY_RSSI, 0); + ctx.fireChannelRead(position); + } + + @Override + public void onFailure(Throwable e) { + LOGGER.warn("Geolocation network error", e); + ctx.fireChannelRead(position); + } + }); + } else { + ctx.fireChannelRead(position); + } + } else { + ctx.fireChannelRead(message); + } + } + +} diff --git a/src/org/traccar/model/Server.java b/src/org/traccar/model/Server.java index 66aa7ee75..ad37e7078 100644 --- a/src/org/traccar/model/Server.java +++ b/src/org/traccar/model/Server.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,14 +15,13 @@ */ package org.traccar.model; -import org.traccar.Context; import org.traccar.database.QueryIgnore; public class Server extends ExtendedModel { @QueryIgnore public String getVersion() { - return Context.getAppVersion(); + return getClass().getPackage().getImplementationVersion(); } public void setVersion(String version) { diff --git a/src/org/traccar/notificators/NotificatorSms.java b/src/org/traccar/notificators/NotificatorSms.java index d4052c626..d5c791eae 100644 --- a/src/org/traccar/notificators/NotificatorSms.java +++ b/src/org/traccar/notificators/NotificatorSms.java @@ -17,6 +17,8 @@ package org.traccar.notificators; import org.traccar.Context; +import org.traccar.Main; +import org.traccar.database.StatisticsManager; import org.traccar.model.Event; import org.traccar.model.Position; import org.traccar.model.User; @@ -41,7 +43,7 @@ public final class NotificatorSms extends Notificator { public void sendAsync(long userId, Event event, Position position) { final User user = Context.getPermissionsManager().getUser(userId); if (user.getPhone() != null) { - Context.getStatisticsManager().registerSms(); + Main.getInjector().getInstance(StatisticsManager.class).registerSms(); smsManager.sendMessageAsync(user.getPhone(), NotificationFormatter.formatShortMessage(userId, event, position), false); } @@ -51,7 +53,7 @@ public final class NotificatorSms extends Notificator { public void sendSync(long userId, Event event, Position position) throws MessageException, InterruptedException { final User user = Context.getPermissionsManager().getUser(userId); if (user.getPhone() != null) { - Context.getStatisticsManager().registerSms(); + Main.getInjector().getInstance(StatisticsManager.class).registerSms(); smsManager.sendMessageSync(user.getPhone(), NotificationFormatter.formatShortMessage(userId, event, position), false); } -- cgit v1.2.3