From 481a902538b951a420d00c32063e0984e4e922d6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 16 Jun 2022 06:48:48 -0700 Subject: Inject data source --- src/main/java/org/traccar/Context.java | 6 +- src/main/java/org/traccar/Main.java | 3 +- src/main/java/org/traccar/MainModule.java | 12 ++- .../java/org/traccar/database/DataManager.java | 97 +------------------ .../java/org/traccar/storage/DatabaseModule.java | 103 +++++++++++++++++++++ src/main/java/org/traccar/web/WebServer.java | 22 +++-- 6 files changed, 130 insertions(+), 113 deletions(-) create mode 100644 src/main/java/org/traccar/storage/DatabaseModule.java (limited to 'src') diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index 5eaa1e15c..00ab05d57 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -28,6 +28,7 @@ import org.traccar.model.BaseModel; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.session.ConnectionManager; +import org.traccar.storage.Storage; public final class Context { @@ -82,7 +83,7 @@ public final class Context { } if (config.hasKey(Keys.DATABASE_URL)) { - dataManager = new DataManager(config); + dataManager = new DataManager(config, Main.getInjector().getInstance(Storage.class)); } if (dataManager != null) { @@ -93,7 +94,8 @@ public final class Context { identityManager = deviceManager; - permissionsManager = new PermissionsManager(dataManager, dataManager.getStorage()); + permissionsManager = new PermissionsManager( + dataManager, Main.getInjector().getInstance(Storage.class)); } diff --git a/src/main/java/org/traccar/Main.java b/src/main/java/org/traccar/Main.java index 412ac1f5e..72eeb5885 100644 --- a/src/main/java/org/traccar/Main.java +++ b/src/main/java/org/traccar/Main.java @@ -22,6 +22,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.traccar.broadcast.BroadcastService; import org.traccar.schedule.ScheduleManager; +import org.traccar.storage.DatabaseModule; import org.traccar.web.WebServer; import java.io.File; @@ -114,7 +115,7 @@ public final class Main { public static void run(String configFile) { try { - injector = Guice.createInjector(new MainModule(), new ServletModule()); + injector = Guice.createInjector(new MainModule(), new DatabaseModule(), new ServletModule()); Context.init(configFile); logSystemInfo(); LOGGER.info("Version: " + Main.class.getPackage().getImplementationVersion()); diff --git a/src/main/java/org/traccar/MainModule.java b/src/main/java/org/traccar/MainModule.java index dd7e375d3..4e95b2be0 100644 --- a/src/main/java/org/traccar/MainModule.java +++ b/src/main/java/org/traccar/MainModule.java @@ -30,12 +30,10 @@ import org.eclipse.jetty.util.URIUtil; import org.traccar.broadcast.BroadcastService; import org.traccar.config.Config; import org.traccar.config.Keys; -import org.traccar.database.LdapProvider; -import org.traccar.helper.SanitizerModule; -import org.traccar.notification.EventForwarder; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; import org.traccar.database.IdentityManager; +import org.traccar.database.LdapProvider; import org.traccar.database.StatisticsManager; import org.traccar.geocoder.AddressFormat; import org.traccar.geocoder.BanGeocoder; @@ -64,17 +62,21 @@ import org.traccar.geolocation.UnwiredGeolocationProvider; import org.traccar.handler.GeocoderHandler; import org.traccar.handler.GeolocationHandler; import org.traccar.handler.SpeedLimitHandler; +import org.traccar.helper.SanitizerModule; +import org.traccar.notification.EventForwarder; import org.traccar.session.cache.CacheManager; import org.traccar.sms.HttpSmsClient; import org.traccar.sms.SmsManager; import org.traccar.sms.SnsSmsClient; import org.traccar.speedlimit.OverpassSpeedLimitProvider; import org.traccar.speedlimit.SpeedLimitProvider; +import org.traccar.storage.DatabaseStorage; import org.traccar.storage.Storage; import org.traccar.web.WebServer; import javax.annotation.Nullable; import javax.inject.Singleton; +import javax.sql.DataSource; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.ext.ContextResolver; @@ -108,8 +110,8 @@ public class MainModule extends AbstractModule { } @Provides - public static Storage provideStorage() { - return Context.getDataManager().getStorage(); + public static Storage provideStorage(DataSource dataSource, ObjectMapper objectMapper) { + return new DatabaseStorage(dataSource, objectMapper); } @Provides diff --git a/src/main/java/org/traccar/database/DataManager.java b/src/main/java/org/traccar/database/DataManager.java index 6921634dd..9ffe1fe97 100644 --- a/src/main/java/org/traccar/database/DataManager.java +++ b/src/main/java/org/traccar/database/DataManager.java @@ -15,16 +15,6 @@ */ package org.traccar.database; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import liquibase.Contexts; -import liquibase.Liquibase; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.exception.LiquibaseException; -import liquibase.resource.FileSystemResourceAccessor; -import liquibase.resource.ResourceAccessor; import org.traccar.Main; import org.traccar.config.Config; import org.traccar.config.Keys; @@ -34,7 +24,6 @@ import org.traccar.model.Permission; import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.User; -import org.traccar.storage.DatabaseStorage; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; import org.traccar.storage.query.Columns; @@ -43,100 +32,18 @@ import org.traccar.storage.query.Limit; import org.traccar.storage.query.Order; import org.traccar.storage.query.Request; -import javax.sql.DataSource; -import java.io.File; -import java.lang.reflect.Method; -import java.net.URL; import java.util.Collection; import java.util.Date; public class DataManager { - private final Config config; - - private DataSource dataSource; - - public DataSource getDataSource() { - return dataSource; - } - private final Storage storage; - public Storage getStorage() { - return storage; - } - private final boolean forceLdap; - public DataManager(Config config) throws Exception { - this.config = config; - + public DataManager(Config config, Storage storage) throws Exception { + this.storage = storage; forceLdap = config.getBoolean(Keys.LDAP_FORCE); - - initDatabase(); - initDatabaseSchema(); - - storage = new DatabaseStorage(dataSource, Main.getInjector().getInstance(ObjectMapper.class)); - } - - private void initDatabase() throws Exception { - - String driverFile = config.getString(Keys.DATABASE_DRIVER_FILE); - if (driverFile != null) { - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - try { - Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class); - method.setAccessible(true); - method.invoke(classLoader, new File(driverFile).toURI().toURL()); - } catch (NoSuchMethodException e) { - Method method = classLoader.getClass() - .getDeclaredMethod("appendToClassPathForInstrumentation", String.class); - method.setAccessible(true); - method.invoke(classLoader, driverFile); - } - } - - String driver = config.getString(Keys.DATABASE_DRIVER); - if (driver != null) { - Class.forName(driver); - } - - HikariConfig hikariConfig = new HikariConfig(); - hikariConfig.setDriverClassName(driver); - hikariConfig.setJdbcUrl(config.getString(Keys.DATABASE_URL)); - hikariConfig.setUsername(config.getString(Keys.DATABASE_USER)); - hikariConfig.setPassword(config.getString(Keys.DATABASE_PASSWORD)); - hikariConfig.setConnectionInitSql(config.getString(Keys.DATABASE_CHECK_CONNECTION)); - hikariConfig.setIdleTimeout(600000); - - int maxPoolSize = config.getInteger(Keys.DATABASE_MAX_POOL_SIZE); - if (maxPoolSize != 0) { - hikariConfig.setMaximumPoolSize(maxPoolSize); - } - - dataSource = new HikariDataSource(hikariConfig); - } - - private void initDatabaseSchema() throws LiquibaseException { - - if (config.hasKey(Keys.DATABASE_CHANGELOG)) { - - ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(new File(".")); - - Database database = DatabaseFactory.getInstance().openDatabase( - config.getString(Keys.DATABASE_URL), - config.getString(Keys.DATABASE_USER), - config.getString(Keys.DATABASE_PASSWORD), - config.getString(Keys.DATABASE_DRIVER), - null, null, null, resourceAccessor); - - String changelog = config.getString(Keys.DATABASE_CHANGELOG); - - try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { - liquibase.clearCheckSums(); - liquibase.update(new Contexts()); - } - } } public User login(String email, String password) throws StorageException { diff --git a/src/main/java/org/traccar/storage/DatabaseModule.java b/src/main/java/org/traccar/storage/DatabaseModule.java new file mode 100644 index 000000000..71bf84b34 --- /dev/null +++ b/src/main/java/org/traccar/storage/DatabaseModule.java @@ -0,0 +1,103 @@ +/* + * Copyright 2022 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.storage; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import liquibase.Contexts; +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.exception.LiquibaseException; +import liquibase.resource.FileSystemResourceAccessor; +import liquibase.resource.ResourceAccessor; +import org.traccar.config.Config; +import org.traccar.config.Keys; + +import javax.inject.Singleton; +import javax.sql.DataSource; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URL; + +public class DatabaseModule extends AbstractModule { + + @Singleton + @Provides + public static DataSource provideDataSource( + Config config) throws ReflectiveOperationException, IOException, LiquibaseException { + + String driverFile = config.getString(Keys.DATABASE_DRIVER_FILE); + if (driverFile != null) { + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + try { + Method method = classLoader.getClass().getDeclaredMethod("addURL", URL.class); + method.setAccessible(true); + method.invoke(classLoader, new File(driverFile).toURI().toURL()); + } catch (NoSuchMethodException e) { + Method method = classLoader.getClass() + .getDeclaredMethod("appendToClassPathForInstrumentation", String.class); + method.setAccessible(true); + method.invoke(classLoader, driverFile); + } + } + + String driver = config.getString(Keys.DATABASE_DRIVER); + if (driver != null) { + Class.forName(driver); + } + + HikariConfig hikariConfig = new HikariConfig(); + hikariConfig.setDriverClassName(driver); + hikariConfig.setJdbcUrl(config.getString(Keys.DATABASE_URL)); + hikariConfig.setUsername(config.getString(Keys.DATABASE_USER)); + hikariConfig.setPassword(config.getString(Keys.DATABASE_PASSWORD)); + hikariConfig.setConnectionInitSql(config.getString(Keys.DATABASE_CHECK_CONNECTION)); + hikariConfig.setIdleTimeout(600000); + + int maxPoolSize = config.getInteger(Keys.DATABASE_MAX_POOL_SIZE); + if (maxPoolSize != 0) { + hikariConfig.setMaximumPoolSize(maxPoolSize); + } + + DataSource dataSource = new HikariDataSource(hikariConfig); + + if (config.hasKey(Keys.DATABASE_CHANGELOG)) { + + ResourceAccessor resourceAccessor = new FileSystemResourceAccessor(new File(".")); + + Database database = DatabaseFactory.getInstance().openDatabase( + config.getString(Keys.DATABASE_URL), + config.getString(Keys.DATABASE_USER), + config.getString(Keys.DATABASE_PASSWORD), + config.getString(Keys.DATABASE_DRIVER), + null, null, null, resourceAccessor); + + String changelog = config.getString(Keys.DATABASE_CHANGELOG); + + try (Liquibase liquibase = new Liquibase(changelog, resourceAccessor, database)) { + liquibase.clearCheckSums(); + liquibase.update(new Contexts()); + } + } + + return dataSource; + } + +} diff --git a/src/main/java/org/traccar/web/WebServer.java b/src/main/java/org/traccar/web/WebServer.java index 933e8c845..5d20966ad 100644 --- a/src/main/java/org/traccar/web/WebServer.java +++ b/src/main/java/org/traccar/web/WebServer.java @@ -47,7 +47,6 @@ import org.jvnet.hk2.guice.bridge.api.GuiceBridge; import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.traccar.Context; import org.traccar.LifecycleObject; import org.traccar.Main; import org.traccar.api.DateParameterConverterProvider; @@ -67,6 +66,7 @@ import javax.servlet.ServletException; import javax.servlet.SessionCookieConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.sql.DataSource; import java.io.File; import java.io.IOException; import java.io.Writer; @@ -80,11 +80,13 @@ public class WebServer implements LifecycleObject { private static final Logger LOGGER = LoggerFactory.getLogger(WebServer.class); private final Injector injector; + private final Config config; private final Server server; @Inject public WebServer(Injector injector, Config config) { this.injector = injector; + this.config = config; String address = config.getString(Keys.WEB_ADDRESS); int port = config.getInteger(Keys.WEB_PORT); if (address == null) { @@ -95,14 +97,14 @@ public class WebServer implements LifecycleObject { ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); - initApi(config, servletHandler); - initSessionConfig(config, servletHandler); + initApi(servletHandler); + initSessionConfig(servletHandler); if (config.getBoolean(Keys.WEB_CONSOLE)) { servletHandler.addServlet(new ServletHolder(new ConsoleServlet()), "/console/*"); } - initWebApp(config, servletHandler); + initWebApp(servletHandler); servletHandler.setErrorHandler(new ErrorHandler() { @Override @@ -119,7 +121,7 @@ public class WebServer implements LifecycleObject { }); HandlerList handlers = new HandlerList(); - initClientProxy(config, handlers); + initClientProxy(handlers); handlers.addHandler(servletHandler); handlers.addHandler(new GzipHandler()); server.setHandler(handlers); @@ -133,7 +135,7 @@ public class WebServer implements LifecycleObject { } } - private void initClientProxy(Config config, HandlerList handlers) { + private void initClientProxy(HandlerList handlers) { int port = config.getInteger(Keys.PROTOCOL_PORT.withPrefix("osmand")); if (port != 0) { ServletContextHandler servletHandler = new ServletContextHandler() { @@ -153,7 +155,7 @@ public class WebServer implements LifecycleObject { } } - private void initWebApp(Config config, ServletContextHandler servletHandler) { + private void initWebApp(ServletContextHandler servletHandler) { ServletHolder servletHolder = new ServletHolder(DefaultServlet.class); servletHolder.setInitParameter("resourceBase", new File(config.getString(Keys.WEB_PATH)).getAbsolutePath()); servletHolder.setInitParameter("dirAllowed", "false"); @@ -169,7 +171,7 @@ public class WebServer implements LifecycleObject { servletHandler.addServlet(servletHolder, "/*"); } - private void initApi(Config config, ServletContextHandler servletHandler) { + private void initApi(ServletContextHandler servletHandler) { servletHandler.addFilter(GuiceFilter.class, "/api/*", EnumSet.allOf(DispatcherType.class)); servletHandler.addServlet(new ServletHolder(injector.getInstance(AsyncSocketServlet.class)), "/api/socket"); @@ -211,10 +213,10 @@ public class WebServer implements LifecycleObject { servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/api/*"); } - private void initSessionConfig(Config config, ServletContextHandler servletHandler) { + private void initSessionConfig(ServletContextHandler servletHandler) { if (config.getBoolean(Keys.WEB_PERSIST_SESSION)) { DatabaseAdaptor databaseAdaptor = new DatabaseAdaptor(); - databaseAdaptor.setDatasource(Context.getDataManager().getDataSource()); + databaseAdaptor.setDatasource(injector.getInstance(DataSource.class)); JDBCSessionDataStoreFactory jdbcSessionDataStoreFactory = new JDBCSessionDataStoreFactory(); jdbcSessionDataStoreFactory.setDatabaseAdaptor(databaseAdaptor); SessionHandler sessionHandler = servletHandler.getSessionHandler(); -- cgit v1.2.3