/**
* Copyright 2014 Flipkart Internet Pvt. Ltd.
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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 com.flipkart.foxtrot.server;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
import com.fasterxml.jackson.databind.jsontype.impl.StdSubtypeResolver;
import com.flipkart.foxtrot.core.cache.CacheManager;
import com.flipkart.foxtrot.core.cache.impl.DistributedCacheFactory;
import com.flipkart.foxtrot.core.common.DataDeletionManager;
import com.flipkart.foxtrot.core.common.DataDeletionManagerConfig;
import com.flipkart.foxtrot.core.datastore.DataStore;
import com.flipkart.foxtrot.core.datastore.impl.hbase.HBaseDataStore;
import com.flipkart.foxtrot.core.datastore.impl.hbase.HbaseTableConnection;
import com.flipkart.foxtrot.core.querystore.DocumentTranslator;
import com.flipkart.foxtrot.core.querystore.QueryExecutor;
import com.flipkart.foxtrot.core.querystore.QueryStore;
import com.flipkart.foxtrot.core.querystore.actions.spi.AnalyticsLoader;
import com.flipkart.foxtrot.core.querystore.impl.ElasticsearchConnection;
import com.flipkart.foxtrot.core.querystore.impl.ElasticsearchQueryStore;
import com.flipkart.foxtrot.core.querystore.impl.ElasticsearchUtils;
import com.flipkart.foxtrot.core.querystore.impl.HazelcastConnection;
import com.flipkart.foxtrot.core.table.TableMetadataManager;
import com.flipkart.foxtrot.core.table.impl.DistributedTableMetadataManager;
import com.flipkart.foxtrot.core.table.impl.FoxtrotTableManager;
import com.flipkart.foxtrot.server.cluster.ClusterManager;
import com.flipkart.foxtrot.server.config.FoxtrotServerConfiguration;
import com.flipkart.foxtrot.server.console.ElasticsearchConsolePersistence;
import com.flipkart.foxtrot.server.healthcheck.ElasticSearchHealthCheck;
import com.flipkart.foxtrot.server.providers.FlatResponseCsvProvider;
import com.flipkart.foxtrot.server.providers.FlatResponseErrorTextProvider;
import com.flipkart.foxtrot.server.providers.FlatResponseTextProvider;
import com.flipkart.foxtrot.server.providers.exception.FoxtrotExceptionMapper;
import com.flipkart.foxtrot.server.resources.*;
import com.flipkart.foxtrot.sql.FqlEngine;
import com.yammer.dropwizard.Service;
import com.yammer.dropwizard.assets.AssetsBundle;
import com.yammer.dropwizard.config.Bootstrap;
import com.yammer.dropwizard.config.Environment;
import com.yammer.metrics.core.HealthCheck;
import net.sourceforge.cobertura.CoverageIgnore;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
/**
* User: Santanu Sinha (santanu.sinha@flipkart.com)
* Date: 15/03/14
* Time: 9:38 PM
*/
@CoverageIgnore
public class FoxtrotServer extends Service<FoxtrotServerConfiguration> {
@Override
public void initialize(Bootstrap<FoxtrotServerConfiguration> bootstrap) {
bootstrap.setName("foxtrot");
bootstrap.addBundle(new AssetsBundle("/console/", "/"));
bootstrap.addCommand(new InitializerCommand());
}
@Override
public void run(FoxtrotServerConfiguration configuration, Environment environment) throws Exception {
configuration.getHttpConfiguration().setRootPath("/foxtrot/*");
configureObjectMapper(environment);
ObjectMapper objectMapper = environment.getObjectMapperFactory().build();
ExecutorService executorService = environment.managedExecutorService("query-executor-%s", 20, 40, 30, TimeUnit.SECONDS);
HbaseTableConnection HBaseTableConnection = new HbaseTableConnection(configuration.getHbase());
ElasticsearchConnection elasticsearchConnection = new ElasticsearchConnection(configuration.getElasticsearch());
HazelcastConnection hazelcastConnection = new HazelcastConnection(configuration.getCluster());
ElasticsearchUtils.setTableNamePrefix(configuration.getElasticsearch());
TableMetadataManager tableMetadataManager = new DistributedTableMetadataManager(hazelcastConnection, elasticsearchConnection);
DataStore dataStore = new HBaseDataStore(HBaseTableConnection,
objectMapper, new DocumentTranslator(configuration.getHbase()));
QueryStore queryStore = new ElasticsearchQueryStore(tableMetadataManager, elasticsearchConnection, dataStore, objectMapper);
FoxtrotTableManager tableManager = new FoxtrotTableManager(tableMetadataManager, queryStore, dataStore);
CacheManager cacheManager = new CacheManager(new DistributedCacheFactory(hazelcastConnection, objectMapper));
AnalyticsLoader analyticsLoader = new AnalyticsLoader(tableMetadataManager, dataStore, queryStore, elasticsearchConnection, cacheManager, objectMapper);
QueryExecutor executor = new QueryExecutor(analyticsLoader, executorService);
DataDeletionManagerConfig dataDeletionManagerConfig = configuration.getTableDataManagerConfig();
DataDeletionManager dataDeletionManager = new DataDeletionManager(dataDeletionManagerConfig, queryStore);
List<HealthCheck> healthChecks = new ArrayList<>();
healthChecks.add(new ElasticSearchHealthCheck("ES Health Check", elasticsearchConnection));
ClusterManager clusterManager = new ClusterManager(hazelcastConnection, healthChecks, configuration.getHttpConfiguration());
environment.manage(HBaseTableConnection);
environment.manage(elasticsearchConnection);
environment.manage(hazelcastConnection);
environment.manage(tableMetadataManager);
environment.manage(analyticsLoader);
environment.manage(dataDeletionManager);
environment.manage(clusterManager);
environment.addResource(new DocumentResource(queryStore));
environment.addResource(new AsyncResource(cacheManager));
environment.addResource(new AnalyticsResource(executor));
environment.addResource(new TableManagerResource(tableManager));
environment.addResource(new TableFieldMappingResource(queryStore));
environment.addResource(new ConsoleResource(
new ElasticsearchConsolePersistence(elasticsearchConnection, objectMapper)));
FqlEngine fqlEngine = new FqlEngine(tableMetadataManager, queryStore, executor, objectMapper);
environment.addResource(new FqlResource(fqlEngine));
environment.addResource(new ClusterInfoResource(clusterManager));
environment.addResource(new UtilResource(configuration));
environment.addResource(new ClusterHealthResource(queryStore));
healthChecks.forEach(environment::addHealthCheck);
environment.addProvider(new FoxtrotExceptionMapper());
environment.addProvider(new FlatResponseTextProvider());
environment.addProvider(new FlatResponseCsvProvider());
environment.addProvider(new FlatResponseErrorTextProvider());
environment.addFilter(CrossOriginFilter.class, "/*");
}
private void configureObjectMapper(Environment environment) {
environment.getObjectMapperFactory().setSerializationInclusion(JsonInclude.Include.NON_NULL);
environment.getObjectMapperFactory().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
SubtypeResolver subtypeResolver = new StdSubtypeResolver();
environment.getObjectMapperFactory().setSubtypeResolver(subtypeResolver);
}
}