// This file is part of OpenTSDB.
// Copyright (C) 2010-2014 The OpenTSDB Authors.
//
// 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 2.1 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 Lesser
// General Public License for more details. You should have received a copy
// of the GNU Lesser General Public License along with this program. If not,
// see <http://www.gnu.org/licenses/>.
package net.opentsdb.tsd;
import java.io.IOException;
import com.stumbleupon.async.Deferred;
import net.opentsdb.core.TSDB;
import net.opentsdb.stats.StatsCollector;
/**
* A plugin that runs along side TSD's built-in HTTP endpoints (like the
* <code>/api</code> endpoints). There can be multiple implementations of
* such plugins per TSD. These plugins run on the same Netty server as
* built-in HTTP endpoints and thus are available on the same port as those
* endpoints. However, these plugins are mounted beneath a special base
* path called <code>/plugin</code>.
*
* <p>Notes on multi-threaded behavior:
* <ul>
* <li>Plugins are created and initialized <strong>once</strong> per instance
* of the TSD. Therefore, these plugins are effectively singletons.
* <li>Plugins will be executed from multiple threads so the {@link #execute}
* and {@link collectStats} methods <strong>must be thread safe</strong>
* with respect to the plugin's internal state and external resources.
* </ul>
* @since 2.2
*/
public abstract class HttpRpcPlugin {
/**
* Called by TSDB to initialize the plugin. This is called <strong>once</strong>
* (and from a single thread) at the time the plugin in loaded.
*
* <p><b>Note:</b> Implementations should throw exceptions if they can't start
* up properly. The TSD will then shutdown so the operator can fix the
* problem. Please use IllegalArgumentException for configuration issues.
*
* @param tsdb The parent TSDB object
* @throws IllegalArgumentException if required configuration parameters are
* missing
* @throws Exception
*/
public abstract void initialize(TSDB tsdb);
/**
* Called to gracefully shutdown the plugin. This is called <strong>once</strong>
* (and from a single thread) at the time the owning TSD is shutting down.
*
* @return A deferred object that indicates the completion of the request.
* The {@link Object} has not special meaning and can be {@code null}
* (think of it as {@code Deferred<Void>}).
*/
public abstract Deferred<Object> shutdown();
/**
* Should return the version of this plugin in the format:
* MAJOR.MINOR.MAINT, e.g. "2.0.1". The MAJOR version should match the major
* version of OpenTSDB the plugin is meant to work with.
* @return A version string used to log the loaded version
*/
public abstract String version();
/**
* Called by the TSD when a request for statistics collection has come in. The
* implementation may provide one or more statistics. If no statistics are
* available for the implementation, simply stub the method.
*
* <p><strong>Note:</strong> Must be thread-safe.
*
* @param collector The collector used for emitting statistics
*/
public abstract void collectStats(StatsCollector collector);
/**
* The (web) path this plugin should be available at. This value
* <strong>should</strong> start with a <code>/</code>. However, it
* <strong>must not</strong> contain the system's plugin base path or the
* plugin will fail to load.
*
* <p>Here are some examples where
* <code>path --(is available at)--> server path</code>
* <ul>
* <li><code>/myAwesomePlugin --> /plugin/myAwesomePlugin</code>
* <li><code>/myOtherPlugin/operation --> /plugin/myOtherPlugin/operation</code>
* </ul>
*
* @return a slash separated path
*/
public abstract String getPath();
/**
* Executes the plugin for the given query received on the path derived from
* {@link #getPath()}. This method will be called by multiple threads
* simultaneously and <strong>must be</strong> thread-safe.
*
* @param tsdb the owning TSDB instance.
* @param query the parsed query
* @throws IOException
*/
public abstract void execute(TSDB tsdb, HttpRpcPluginQuery query) throws IOException;
}