/* * #%L * server * %% * Copyright (C) 2012 - 2015 valdasraps * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-3.0.html>. * #L% */ package lt.emasina.resthub.server; import com.google.inject.AbstractModule; import com.google.inject.assistedinject.FactoryModuleBuilder; import java.io.InputStream; import net.sf.jsqlparser.parser.CCJSqlParserManager; import lt.emasina.resthub.ConnectionFactory; import lt.emasina.resthub.TableFactory; import lt.emasina.resthub.server.app.BlacklistTable; import lt.emasina.resthub.server.app.BlacklistTables; import lt.emasina.resthub.server.app.Cache; import lt.emasina.resthub.server.app.Queries; import lt.emasina.resthub.server.app.Query; import lt.emasina.resthub.server.app.Count; import lt.emasina.resthub.server.app.Data; import lt.emasina.resthub.server.app.Info; import lt.emasina.resthub.server.app.Lob; import lt.emasina.resthub.server.app.Table; import lt.emasina.resthub.server.app.TableData; import lt.emasina.resthub.server.app.Tables; import lt.emasina.resthub.server.factory.CacheFactory; import lt.emasina.resthub.server.factory.MetadataFactory; import lt.emasina.resthub.server.factory.MetadataFactoryIf; import lt.emasina.resthub.server.factory.InjectorJobFactory; import lt.emasina.resthub.server.factory.ResourceFactory; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.impl.StdSchedulerFactory; import org.quartz.spi.JobFactory; import org.restlet.Restlet; import org.restlet.routing.Filter; import org.restlet.routing.Router; public class ServerApp extends BaseApp { private final AbstractModule[] applicationModules; public ServerApp(final ConnectionFactory connectionFactory, final TableFactory tableFactory) throws Exception { this(connectionFactory, tableFactory, new ServerAppConfig()); } public ServerApp(final ConnectionFactory connectionFactory, final TableFactory tableFactory, final ServerAppConfig cfg) throws Exception { setName("JDBC-Restlet Application"); setDescription("Application that provides RESTful API to JDBC queries"); setAuthor("Valdas Rapsevicius, valdas.rapsevicius@cern.ch"); final StdSchedulerFactory schedulerFactory = new StdSchedulerFactory(); // To skip /quartz.properties loading! try (InputStream in = SchedulerFactory.class.getResourceAsStream("/org/quartz/quartz.properties")) { schedulerFactory.initialize(in); } final Scheduler scheduler = schedulerFactory.getScheduler(); // Initialize tableFactory recursively tableFactory.init(connectionFactory); this.applicationModules = new AbstractModule[] { new AbstractModule() { @Override protected void configure() { bind(ConnectionFactory.class).toInstance(connectionFactory); bind(TableFactory.class).toInstance(tableFactory); bind(CCJSqlParserManager.class).toInstance(new CCJSqlParserManager()); install(new FactoryModuleBuilder().build(ResourceFactory.class)); bind(JobFactory.class).to(InjectorJobFactory.class); bind(MetadataFactoryIf.class).to(MetadataFactory.class); bind(Scheduler.class).toInstance(scheduler); bind(ServerAppConfig.class).toInstance(cfg); } } }; getInjector().getInstance(MetadataFactoryIf.class).refresh(); InjectorJobFactory.startUpdateJob(scheduler, getInjector().getInstance(InjectorJobFactory.class), cfg); getInjector().getInstance(CacheFactory.class); scheduler.start(); } @Override public synchronized void stop() throws Exception { super.stop(); getInjector().getInstance(Scheduler.class).shutdown(); getInjector().getInstance(CacheFactory.class).close(); getInjector().getInstance(TableFactory.class).closeAll(); } @Override protected AbstractModule[] getApplicationModules() { return applicationModules; } @Override public Restlet createInboundRoot() { Router router = new Router(getContext()); // GET router.attach("/", Tables.class); router.attach("/tables", Tables.class); router.attach("/tables/{tableNs}", Tables.class); router.attach("/table/{tableNs}/{tableName}", Table.class); // GET router.attach("/info", Info.class); // GET, DELETE router.attach("/blacklist", BlacklistTables.class); router.attach("/blacklist/{tableNs}", BlacklistTables.class); router.attach("/blacklist/{tableNs}/{tableName}", BlacklistTable.class); // GET, DELETE router.attach("/table/{tableNs}/{tableName}/cache", Cache.class); // GET router.attach("/queries", Queries.class); // POST router.attach("/query", Query.class); // GET, DELETE router.attach("/query/{queryId}", Query.class); // GET router.attach("/query/{queryId}/count", Count.class); // GET router.attach("/query/{queryId}/data", Data.class); router.attach("/query/{queryId}/page/{perPage}/{page}/data", Data.class); router.attach("/query/{queryId}/{row}/{col}/lob", Lob.class); router.attach("/query/{queryId}/page/{perPage}/{page}/{row}/{col}/lob", Lob.class); // GET router.attach("/table/{tableNs}/{tableName}/data", TableData.class); router.attach("/table/{tableNs}/{tableName}/page/{perPage}/{page}/data", TableData.class); // GET, DELETE router.attach("/query/{queryId}/cache", Cache.class); Filter filter = new RequestFilter(getContext()); filter.setNext(router); return filter; } }