/** * Copyright (C) 2014-2016 LinkedIn Corp. (pinot-core@linkedin.com) * * 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 com.linkedin.pinot.server.starter; import com.linkedin.pinot.common.data.DataManager; import com.linkedin.pinot.common.metrics.MetricsHelper; import com.linkedin.pinot.common.metrics.ServerMetrics; import com.linkedin.pinot.common.query.QueryExecutor; import com.linkedin.pinot.core.data.manager.offline.TableDataManagerProvider; import com.linkedin.pinot.core.operator.transform.TransformUtils; import com.linkedin.pinot.core.operator.transform.function.TransformFunctionFactory; import com.linkedin.pinot.core.query.scheduler.QueryScheduler; import com.linkedin.pinot.core.query.scheduler.QuerySchedulerFactory; import com.linkedin.pinot.server.conf.NettyServerConfig; import com.linkedin.pinot.server.conf.ServerConf; import com.linkedin.pinot.server.request.ScheduledRequestHandler; import com.linkedin.pinot.transport.netty.NettyServer; import com.linkedin.pinot.transport.netty.NettyServer.RequestHandlerFactory; import com.linkedin.pinot.transport.netty.NettyTCPServer; import com.yammer.metrics.core.MetricsRegistry; import java.io.File; import java.lang.reflect.InvocationTargetException; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Initialize a ServerBuilder with serverConf file. * * */ public class ServerBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(ServerBuilder.class); public static final String PINOT_PROPERTIES = "pinot.properties"; private final ServerConf _serverConf; private ServerMetrics _serverMetrics; private MetricsRegistry metricsRegistry; public ServerConf getConfiguration() { return _serverConf; } /** * Construct from config file path * @param configFilePath Path to the config file * @param metricsRegistry * @throws Exception */ public ServerBuilder(File configFilePath, MetricsRegistry metricsRegistry) throws Exception { this.metricsRegistry = metricsRegistry; if (!configFilePath.exists()) { LOGGER.error("configuration file: " + configFilePath.getAbsolutePath() + " does not exist."); throw new ConfigurationException("configuration file: " + configFilePath.getAbsolutePath() + " does not exist."); } // build _serverConf PropertiesConfiguration serverConf = new PropertiesConfiguration(); serverConf.setDelimiterParsingDisabled(false); serverConf.load(configFilePath); _serverConf = new ServerConf(serverConf); initMetrics(); } /** * Construct from config directory and a config file which resides under it * @param confDir Directory under which config file is present * @param file Config File * @param metricsRegistry * @throws Exception */ public ServerBuilder(String confDir, String file, MetricsRegistry metricsRegistry) throws Exception { this(new File(confDir, file), metricsRegistry); } /** * Construct from config directory and default config file * @param confDir Directory under which pinot.properties file is present * @param metricsRegistry * @throws Exception */ public ServerBuilder(String confDir, MetricsRegistry metricsRegistry) throws Exception { this(new File(confDir, PINOT_PROPERTIES), metricsRegistry); } /** * Initialize with Configuration file * @param config object * @param metricsRegistry */ public ServerBuilder(Configuration config, MetricsRegistry metricsRegistry) { this.metricsRegistry = metricsRegistry; _serverConf = new ServerConf(config); initMetrics(); } /** * Initialize with ServerConf object * @param serverConf object * @param metricsRegistry */ public ServerBuilder(ServerConf serverConf, MetricsRegistry metricsRegistry) { _serverConf = serverConf; this.metricsRegistry = metricsRegistry; initMetrics(); } public DataManager buildInstanceDataManager() throws InstantiationException, IllegalAccessException, ClassNotFoundException { String className = _serverConf.getInstanceDataManagerClassName(); LOGGER.info("Trying to Load Instance DataManager by Class : " + className); DataManager instanceDataManager = (DataManager) Class.forName(className).newInstance(); instanceDataManager.init(_serverConf.getInstanceDataManagerConfig()); return instanceDataManager; } public QueryExecutor buildQueryExecutor(DataManager instanceDataManager) throws InstantiationException, IllegalAccessException, ClassNotFoundException, ConfigurationException { String className = _serverConf.getQueryExecutorClassName(); LOGGER.info("Trying to Load Query Executor by Class : " + className); QueryExecutor queryExecutor = (QueryExecutor) Class.forName(className).newInstance(); queryExecutor.init(_serverConf.getQueryExecutorConfig(), instanceDataManager, _serverMetrics); return queryExecutor; } public QueryScheduler buildQueryScheduler(QueryExecutor queryExecutor) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Configuration schedulerConfig = _serverConf.getSchedulerConfig(); return QuerySchedulerFactory.create(schedulerConfig, queryExecutor); } public RequestHandlerFactory buildRequestHandlerFactory(final QueryScheduler queryScheduler) { RequestHandlerFactory requestHandlerFactory = new RequestHandlerFactory() { @Override public NettyServer.RequestHandler createNewRequestHandler() { return new ScheduledRequestHandler(queryScheduler, _serverMetrics); } }; return requestHandlerFactory; } /** * This method initializes the transform factory containing built-in functions * as well as functions specified in the server configuration. * * @param serverConf Server configuration */ public static void init(ServerConf serverConf) { TransformFunctionFactory.init( ArrayUtils.addAll(TransformUtils.getBuiltInTransform(), serverConf.getTransformFunctions())); } public NettyServer buildNettyServer(NettyServerConfig nettyServerConfig, RequestHandlerFactory requestHandlerFactory) { LOGGER.info("Trying to build NettyTCPServer with port : " + nettyServerConfig.getPort()); NettyServer nettyServer = new NettyTCPServer(nettyServerConfig.getPort(), requestHandlerFactory, null); return nettyServer; } private void initMetrics() { MetricsHelper.initializeMetrics(_serverConf.getMetricsConfig()); MetricsHelper.registerMetricsRegistry(metricsRegistry); _serverMetrics = new ServerMetrics(metricsRegistry, !_serverConf.emitTableLevelMetrics()); _serverMetrics.initializeGlobalMeters(); TableDataManagerProvider.setServerMetrics(_serverMetrics); } public ServerMetrics getServerMetrics() { return _serverMetrics; } }