:linkattrs:
= Gerrit Code Review - Plugin Development

The Gerrit server functionality can be extended by installing plugins.
This page describes how plugins for Gerrit can be developed and hosted
on gerrit-review.googlesource.com.

For PolyGerrit-specific plugin development, consult with
link:pg-plugin-dev.html[PolyGerrit Plugin Development] guide.

Depending on how tightly the extension code is coupled with the Gerrit
server code, there is a distinction between `plugins` and `extensions`.

[[plugin]]
A `plugin` in Gerrit is tightly coupled code that runs in the same
JVM as Gerrit. It has full access to all server internals. Plugins
are tightly coupled to a specific major.minor server version and
may require source code changes to compile against a different
server version.

Plugins may require a specific major.minor.patch server version
and may need rebuild and revalidation across different
patch levels. A different patch level may only add new
API interfaces and never change or extend existing ones.

[[extension]]
An `extension` in Gerrit runs inside of the same JVM as Gerrit
in the same way as a plugin, but has limited visibility to the
server's internals. The limited visibility reduces the extension's
dependencies, enabling it to be compatible across a wider range
of server versions.

Most of this documentation refers to either type as a plugin.

[[getting-started]]
== Getting started

To get started with the development of a plugin, take a look at
the samples in the
link:https://gerrit.googlesource.com/plugins/examples[examples plugin project,role=external,window=_blank].

This is a project that demonstrates the various features of the
plugin API. It can be taken as an example to develop an own plugin.

When starting from this example one should take care to adapt the
`Gerrit-ApiVersion` in the `BUILD` to the version of Gerrit for which
the plugin is developed.

[[API]]
== API

There are two different API formats offered against which plugins can
be developed:

gerrit-extension-api.jar::
  A stable but thin interface. Suitable for extensions that need
  to be notified of events, but do not require tight coupling to
  the internals of Gerrit. Extensions built against this API can
  expect to be binary compatible across a wide range of server
  versions.

gerrit-plugin-api.jar::
  The complete internals of the Gerrit server, permitting a
  plugin to tightly couple itself and provide additional
  functionality that is not possible as an extension. Plugins
  built against this API are expected to break at the source
  code level between every major.minor Gerrit release. A plugin
  that compiles against 2.5 will probably need source code level
  changes to work with 2.6, 2.7, and so on.

== Manifest

Plugins may provide optional description information with standard
manifest fields:

----
Implementation-Title: Example plugin showing examples
Implementation-Version: 1.0
Implementation-Vendor: Example, Inc.
----

=== ApiType

Plugins using the tightly coupled `gerrit-plugin-api.jar` must
declare this API dependency in the manifest to gain access to server
internals. If no `Gerrit-ApiType` is specified the stable `extension`
API will be assumed. This may cause ClassNotFoundExceptions when
loading a plugin that needs the plugin API.

----
Gerrit-ApiType: plugin
----

=== Explicit Registration

Plugins that use explicit Guice registration must name the Guice
modules in the manifest. Up to three modules can be named in the
manifest. `Gerrit-Module` supplies bindings to the core server;
`Gerrit-SshModule` supplies SSH commands to the SSH server (if
enabled); `Gerrit-HttpModule` supplies servlets and filters to the HTTP
server (if enabled). If no modules are named automatic registration
will be performed by scanning all classes in the plugin JAR for
`@Listen` and `@Export("")` annotations.

----
Gerrit-Module:     tld.example.project.CoreModuleClassName
Gerrit-SshModule:  tld.example.project.SshModuleClassName
Gerrit-HttpModule: tld.example.project.HttpModuleClassName
----

=== Batch runtime

Gerrit can be run as a server, serving HTTP or SSH requests, or as an
offline program. Plugins can contribute Guice modules to this batch
runtime by binding `Gerrit-BatchModule` to one of their classes.
The Guice injector is bound to less classes, and some Gerrit features
will be absent - on purpose.

This feature was originally introduced to support plugins during an
offline reindexing task.

----
Gerrit-BatchModule: tld.example.project.CoreModuleClassName
----

In this runtime, only the module designated by `Gerrit-BatchModule` is
enabled, not `Gerrit-SysModule`.

[[plugin_name]]
=== Plugin Name

A plugin can optionally provide its own plugin name.

----
Gerrit-PluginName: replication
----

This is useful for plugins that contribute plugin-owned capabilities that
are stored in the `project.config` file. Another use case is to be able to put
project specific plugin configuration section in `project.config`. In this
case it is advantageous to reserve the plugin name to access the configuration
section in the `project.config` file.

If `Gerrit-PluginName` is omitted, then the plugin's name is determined from
the plugin file name.

If a plugin provides its own name, then that plugin cannot be deployed
multiple times under different file names on one Gerrit site.

For Maven driven plugins, the following line must be included in the pom.xml
file:

[source,xml]
----
<manifestEntries>
  <Gerrit-PluginName>name</Gerrit-PluginName>
</manifestEntries>
----

For Bazel driven plugins, the following line must be included in the BUILD
configuration file:

[source,python]
----
manifest_entries = [
   'Gerrit-PluginName: name',
]
----

A plugin can get its own name injected at runtime:

[source,java]
----
public class MyClass {

  private final String pluginName;

  @Inject
  public MyClass(@PluginName String pluginName) {
    this.pluginName = pluginName;
  }

  [...]
}
----

A plugin can get its canonical web URL injected at runtime:

[source,java]
----
public class MyClass {

  private final String url;

  @Inject
  public MyClass(@PluginCanonicalWebUrl String url) {
    this.url = url;
  }

  [...]
}
----

The URL is composed of the server's canonical web URL and the plugin's
name, i.e. `http://review.example.com:8080/plugin-name`.

The canonical web URL may be injected into any .jar plugin regardless of
whether or not the plugin provides an HTTP servlet.

[[reload_method]]
=== Reload Method

If a plugin holds an exclusive resource that must be released before
loading the plugin again (for example listening on a network port or
acquiring a file lock) the manifest must declare `Gerrit-ReloadMode`
to be `restart`. Otherwise the preferred method of `reload` will
be used, as it enables the server to hot-patch an updated plugin
with no down time.

----
Gerrit-ReloadMode: restart
----

In either mode ('restart' or 'reload') any plugin or extension can
be updated without restarting the Gerrit server. The difference is
how Gerrit handles the upgrade:

restart::
  The old plugin is completely stopped. All registrations of SSH
  commands and HTTP servlets are removed. All registrations of any
  extension points are removed. All registered LifecycleListeners
  have their `stop()` method invoked in reverse order. The new
  plugin is started, and registrations are made from the new
  plugin. There is a brief window where neither the old nor the
  new plugin is connected to the server. This means SSH commands
  and HTTP servlets will return not found errors, and the plugin
  will not be notified of events that occurred during the restart.

reload::
  The new plugin is started. Its LifecycleListeners are permitted
  to perform their `start()` methods. All SSH and HTTP registrations
  are atomically swapped out from the old plugin to the new plugin,
  ensuring the server never returns a not found error. All extension
  point listeners are atomically swapped out from the old plugin to
  the new plugin, ensuring no events are missed (however some events
  may still route to the old plugin if the swap wasn't complete yet).
  The old plugin is stopped.

To reload/restart a plugin the link:cmd-plugin-reload.html[plugin reload]
command can be used.

[[init_step]]
=== Init step

Plugins can contribute their own "init step" during the Gerrit init
wizard. This is useful for guiding the Gerrit administrator through
the settings needed by the plugin to work properly.

For instance plugins to integrate Jira issues to Gerrit changes may
contribute their own "init step" to allow configuring the Jira URL,
credentials and possibly verify connectivity to validate them.

----
Gerrit-InitStep: tld.example.project.MyInitStep
----

MyInitStep needs to follow the standard Gerrit InitStep syntax
and behavior: writing to the console using the injected ConsoleUI
and accessing / changing configuration settings using Section.Factory.

In addition to the standard Gerrit init injections, plugins receive
the @PluginName String injection containing their own plugin name.

During their initialization plugins may get access to the
`project.config` file of the `All-Projects` project and they are able
to store configuration parameters in it. For this a plugin `InitStep`
can get `com.google.gerrit.pgm.init.api.AllProjectsConfig` injected:

[source,java]
----
public class MyInitStep implements InitStep {
  private final String pluginName;
  private final ConsoleUI ui;
  private final AllProjectsConfig allProjectsConfig;

  @Inject
  public MyInitStep(@PluginName String pluginName, ConsoleUI ui,
      AllProjectsConfig allProjectsConfig) {
    this.pluginName = pluginName;
    this.ui = ui;
    this.allProjectsConfig = allProjectsConfig;
  }

  @Override
  public void run() throws Exception {
  }

  @Override
  public void postRun() throws Exception {
    ui.message("\n");
    ui.header(pluginName + " Integration");
    boolean enabled = ui.yesno(true, "By default enabled for all projects");
    Config cfg = allProjectsConfig.load().getConfig();
    if (enabled) {
      cfg.setBoolean("plugin", pluginName, "enabled", enabled);
    } else {
      cfg.unset("plugin", pluginName, "enabled");
    }
    allProjectsConfig.save(pluginName, "Initialize " + pluginName + " Integration");
  }
}
----

Bear in mind that the Plugin's InitStep class will be loaded but
the standard Gerrit runtime environment is not available and the plugin's
own Guice modules were not initialized.
This means the InitStep for a plugin is not executed in the same way that
the plugin executes within the server, and may mean a plugin author cannot
trivially reuse runtime code during init.

For instance a plugin that wants to verify connectivity may need to statically
call the constructor of their connection class, passing in values obtained
from the Section.Factory rather than from an injected Config object.

Plugins' InitSteps are executed during the "Gerrit Plugin init" phase, after
the extraction of the plugins embedded in the distribution .war file into
`$GERRIT_SITE/plugins` and before the site initialization or upgrade.

A plugin's InitStep cannot refer to any Gerrit runtime objects injected at
startup.

[source,java]
----
public class MyInitStep implements InitStep {
  private final ConsoleUI ui;
  private final Section.Factory sections;
  private final String pluginName;

  @Inject
  public GitBlitInitStep(final ConsoleUI ui, Section.Factory sections, @PluginName String pluginName) {
    this.ui = ui;
    this.sections = sections;
    this.pluginName = pluginName;
  }

  @Override
  public void run() throws Exception {
    ui.header("\nMy plugin");

    Section mySection = getSection("myplugin", null);
    mySection.string("Link name", "linkname", "MyLink");
  }

  @Override
  public void postRun() throws Exception {
  }
}
----

[[classpath]]
== Classpath

Each plugin is loaded into its own ClassLoader, isolating plugins
from each other. A plugin or extension inherits the Java runtime
and the Gerrit API chosen by `Gerrit-ApiType` (extension or plugin)
from the hosting server.

Plugins are loaded from a single JAR file. If a plugin needs
additional libraries, it must include those dependencies within
its own JAR. Plugins built using Maven may be able to use the
link:http://maven.apache.org/plugins/maven-shade-plugin/[shade plugin,role=external,window=_blank]
to package additional dependencies. Relocating (or renaming) classes
should not be necessary due to the ClassLoader isolation.

[[events]]
== Listening to Events

Certain operations in Gerrit trigger events. Plugins may receive
notifications of these events by implementing the corresponding
listeners.

* `com.google.gerrit.common.EventListener`:
+
Allows to listen to events without user visibility restrictions. These
are the same link:cmd-stream-events.html#events[events] that are also streamed by
the link:cmd-stream-events.html[gerrit stream-events] command.

* `com.google.gerrit.common.UserScopedEventListener`:
+
Allows to listen to events visible to the specified user. These are the
same link:cmd-stream-events.html#events[events] that are also streamed
by the link:cmd-stream-events.html[gerrit stream-events] command.

* `com.google.gerrit.extensions.events.AccountActivationListener`:
+
User account got activated or deactivated

* `com.google.gerrit.extensions.events.LifecycleListener`:
+
Plugin start and stop

* `com.google.gerrit.extensions.events.NewProjectCreatedListener`:
+
Project creation

* `com.google.gerrit.extensions.events.ProjectDeletedListener`:
+
Project deletion

* `com.google.gerrit.extensions.events.HeadUpdatedListener`:
+
Update of HEAD on a project

* `com.google.gerrit.extensions.events.UsageDataPublishedListener`:
+
Publication of usage data

* `com.google.gerrit.extensions.events.GarbageCollectorListener`:
+
Garbage collection ran on a project

* `com.google.gerrit.server.extensions.events.ChangeIndexedListener`:
+
Update of the change secondary index

* `com.google.gerrit.server.extensions.events.AccountIndexedListener`:
+
Update of the account secondary index

* `com.google.gerrit.server.extensions.events.GroupIndexedListener`:
+
Update of the group secondary index

* `com.google.gerrit.server.extensions.events.ProjectIndexedListener`:
+
Update of the project secondary index

* `com.google.gerrit.httpd.WebLoginListener`:
+
User login or logout interactively on the Web user interface.

The event listener is under the Gerrit http package to automatically
inherit the javax.servlet.http dependencies and allowing to influence
the login or logout flow with additional redirections.

[[stream-events]]
== Sending Events to the Events Stream

Plugins may send events to the events stream where consumers of
Gerrit's `stream-events` ssh command will receive them.

To send an event, the plugin must invoke one of the `postEvent`
methods in the `EventDispatcher` interface, passing an instance of
its own custom event class derived from
`com.google.gerrit.server.events.Event`.

[source,java]
----
import com.google.gerrit.common.EventDispatcher;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.inject.Inject;

class MyPlugin {
  private final DynamicItem<EventDispatcher> eventDispatcher;

  @Inject
  myPlugin(DynamicItem<EventDispatcher> eventDispatcher) {
    this.eventDispatcher = eventDispatcher;
  }

  private void postEvent(MyPluginEvent event) {
    try {
      eventDispatcher.get().postEvent(event);
    } catch (StorageException e) {
      // error handling
    }
  }
}
----

Plugins which define new Events should register them via the
`com.google.gerrit.server.events.EventTypes.register()` method.
This will make the EventType known to the system. Deserializing
events with the
`com.google.gerrit.server.events.EventDeserializer` class requires
that the event be registered in EventTypes.

== Modifying the Stream Event Flow

It is possible to modify the stream event flow from plugins by registering
an `com.google.gerrit.server.events.EventDispatcher`. A plugin may register
a Dispatcher class to replace the internal Dispatcher. EventDispatcher is
a DynamicItem, so Gerrit may only have one copy.

[[validation]]
== Validation Listeners

Certain operations in Gerrit can be validated by plugins by
implementing the corresponding link:config-validation.html[listeners].

[[change-message-modifier]]
== Change Message Modifier

`com.google.gerrit.server.git.ChangeMessageModifier`:
plugins implementing this can modify commit message of the change being
submitted by Rebase Always and Cherry Pick submit strategies as well as
change being queried with COMMIT_FOOTERS option.

[[merge-super-set-computation]]
== Merge Super Set Computation

The algorithm to compute the merge super set to detect changes that
should be submitted together can be customized by implementing
`com.google.gerrit.server.git.MergeSuperSetComputation`.
MergeSuperSetComputation is a DynamicItem, so Gerrit may only have one
implementation.

[[receive-pack]]
== Receive Pack Initializers

Plugins may provide ReceivePackInitializer instances, which will be
invoked by Gerrit just before a ReceivePack instance will be used.
Usually, plugins will make use of the setXXX methods on the ReceivePack
to set additional properties on it.

The interactions with the core Gerrit ReceivePack initialization and
between ReceivePackInitializers can be complex. Please read the
ReceivePack Javadoc and Gerrit AsyncReceiveCommits implementation
carefully.

[[post-receive-hook]]
== Post Receive-Pack Hooks

Plugins may register PostReceiveHook instances in order to get
notified when JGit successfully receives a pack. This may be useful
for those plugins which would like to monitor changes in Git
repositories.

[[upload-pack]]
== Upload Pack Initializers

Plugins may provide UploadPackInitializer instances, which will be
invoked by Gerrit just before a UploadPack instance will be used.
Usually, plugins will make use of the setXXX methods on the UploadPack
to set additional properties on it.

The interactions with the core Gerrit UploadPack initialization and
between UploadPackInitializers can be complex. Please read the
UploadPack Javadoc and Gerrit Upload/UploadFactory implementations
carefully.

[[pre-upload-hook]]
== Pre Upload-Pack Hooks

Plugins may register PreUploadHook instances in order to get
notified when JGit is about to upload a pack. This may be useful
for those plugins which would like to monitor usage in Git
repositories.

[[post-upload-hook]]
== Post Upload-Pack Hooks

Plugins may register PostUploadHook instances in order to get notified after
JGit is done uploading a pack.

[[ssh]]
== SSH Commands

Plugins may provide commands that can be accessed through the SSH
interface (extensions do not have this option).

Command implementations must extend the base class SshCommand:

[source,java]
----
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.sshd.CommandMetaData;

@CommandMetaData(name="print", description="Print hello command")
class PrintHello extends SshCommand {
  @Override
  protected void run() {
    stdout.print("Hello\n");
  }
}
----

If no Guice modules are declared in the manifest, SSH commands may
use auto-registration by providing an `@Export` annotation:

[source,java]
----
import com.google.gerrit.extensions.annotations.Export;
import com.google.gerrit.sshd.SshCommand;

@Export("print")
class PrintHello extends SshCommand {
  @Override
  protected void run() {
    stdout.print("Hello\n");
  }
}
----

If explicit registration is being used, a Guice module must be
supplied to register the SSH command and declared in the manifest
with the `Gerrit-SshModule` attribute:

[source,java]
----
import com.google.gerrit.sshd.PluginCommandModule;

class MyCommands extends PluginCommandModule {
  @Override
  protected void configureCommands() {
    command(PrintHello.class);
  }
}
----

For a plugin installed as name `helloworld`, the command implemented
by PrintHello class will be available to users as:

----
$ ssh -p 29418 review.example.com helloworld print
----

[[multiple-commands]]
=== Multiple Commands bound to one implementation

Multiple SSH commands can be bound to the same implementation class. For
example a Gerrit Shell plugin can bind different shell commands to the same
implementation class:

[source,java]
----
public class SshShellModule extends PluginCommandModule {
  @Override
  protected void configureCommands() {
    command("ls").to(ShellCommand.class);
    command("ps").to(ShellCommand.class);
    [...]
  }
}
----

With the possible implementation:

[source,java]
----
public class ShellCommand extends SshCommand {
  @Override
  protected void run() throws UnloggedFailure {
    String cmd = getName().substring(getPluginName().length() + 1);
    ProcessBuilder proc = new ProcessBuilder(cmd);
    Process cmd = proc.start();
    [...]
  }
}
----

And the call:

----
$ ssh -p 29418 review.example.com shell ls
$ ssh -p 29418 review.example.com shell ps
----

[[root-level-commands]]
=== Root Level Commands

Single command plugins are also supported. In this scenario plugin binds
SSH command to its own name. `SshModule` must inherit from
`SingleCommandPluginModule` class:

[source,java]
----
public class SshModule extends SingleCommandPluginModule {
 @Override
 protected void configure(LinkedBindingBuilder<Command> b) {
    b.to(ShellCommand.class);
  }
}
----

If the plugin above is deployed under sh.jar file in `$site/plugins`
directory, generic commands can be called without specifying the
actual SSH command. Note in the example below, that the called commands
`ls` and `ps` was not explicitly bound:

----
$ ssh -p 29418 review.example.com sh ls
$ ssh -p 29418 review.example.com sh ps
----

[[search_operators]]
== Search Operators

Plugins can define new search operators to extend change searching by
implementing the `ChangeQueryBuilder.ChangeOperatorFactory` interface
and registering it to an operator name in the plugin module's
`configure()` method.  The search operator name is defined during
registration via the DynamicMap annotation mechanism.  The plugin
name will get appended to the annotated name, with an underscore
in between, leading to the final operator name.  An example
registration looks like this:

[source,java]
----
bind(ChangeOperatorFactory.class)
  .annotatedWith(Exports.named("sample"))
  .to(SampleOperator.class);
----

If this is registered in the `myplugin` plugin, then the resulting
operator will be named `sample_myplugin`.

The search operator itself is implemented by ensuring that the
`create()` method of the class implementing the
`ChangeQueryBuilder.ChangeOperatorFactory` interface returns a
`Predicate<ChangeData>`.  Here is a sample operator factory
definition which creates a `MyPredicate`:

[source,java]
----
public class SampleOperator
    implements ChangeQueryBuilder.ChangeOperatorFactory {
  public static class MyPredicate extends PostFilterPredicate<ChangeData> {
    ...
  }

  @Override
  public Predicate<ChangeData> create(ChangeQueryBuilder builder, String value)
      throws QueryParseException {
    return new MyPredicate(value);
  }
}
----

[[search_operands]]
== Search Operands

Plugins can define new search operands to extend change searching.
Plugin methods implementing search operands (returning a
`Predicate<ChangeData>`), must be defined on a class implementing
one of the `ChangeQueryBuilder.ChangeOperandsFactory` interfaces
(.e.g., ChangeQueryBuilder.ChangeHasOperandFactory).  The specific
`ChangeOperandFactory` class must also be bound to the `DynamicSet` from
a module's `configure()` method in the plugin.

The new operand, when used in a search would appear as:
  `operatorName:operandName_pluginName`

A sample `ChangeHasOperandFactory` class implementing, and registering, a
new `has:sample_pluginName` operand is shown below:

[source, java]
----
public class SampleHasOperand implements ChangeHasOperandFactory {
  public static class Module extends AbstractModule {
    @Override
    protected void configure() {
      bind(ChangeHasOperandFactory.class)
          .annotatedWith(Exports.named("sample")
          .to(SampleHasOperand.class);
    }
  }

  @Override
  public Predicate<ChangeData> create(ChangeQueryBuilder builder)
      throws QueryParseException {
    return new HasSamplePredicate();
  }
}
----

[[command_options]]
== Command Options

Plugins can provide additional options for each of the gerrit ssh and the
REST API commands by implementing the DynamicBean interface and registering
it to a command class name in the plugin module's `configure()` method. The
plugin's name will be prepended to the name of each @Option annotation found
on the DynamicBean object provided by the plugin. The example below shows a
plugin that adds an option to log a value from the gerrit 'ban-commits'
ssh command.

[source, java]
----
public class SshModule extends AbstractModule {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  @Override
  protected void configure() {
    bind(DynamicOptions.DynamicBean.class)
        .annotatedWith(Exports.named(
        com.google.gerrit.sshd.commands.BanCommitCommand.class))
        .to(BanOptions.class);
  }

  public static class BanOptions implements DynamicOptions.DynamicBean {
    @Option(name = "--log", aliases = { "-l" }, usage = "Say Hello in the Log")
    private void parse(String arg) {
      logger.atSevere().log("Say Hello in the Log %s", arg);
    }
  }
}
----

=== Calling Command Options ===

Within an OptionHandler, during the processing of an option, plugins can
provide and call extra parameters on the current command during parsing
simulating as if they had been passed from the command line originally.

To call additional parameters from within an option handler, instantiate
the com.google.gerrit.util.cli.CmdLineParser.Parameters class with the
existing parameters, and then call callParameters() with the additional
parameters to be parsed. OptionHandlers may optionally pass this class to
other methods which may then both parse/consume more parameters and call
additional parameters.

When calling command options not provided by your plugin, there is always
a risk that the options may not exist, perhaps because the options being
called are to be provided by another plugin, and said plugin is not
currently installed. To protect againt this situation, it is possible to
define an option as being dependent on other options using the
@RequiresOptions() annotation. If the required options are not all not
currently present, then the dependent option will not be available or
visible in the help.

The example below shows a plugin that adds a "--special" option (perhaps
for use with the Query command) that calls (and requires) the
"--format json" option.

[source, java]
----
public class JsonOutputOptionHandler<T> extends OptionHandler<T> {
  protected com.google.gerrit.util.cli.CmdLineParser.MyParser myParser;

  public JsonOutputOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super T> setter) {
    super(parser, option, setter);
    myParser = (com.google.gerrit.util.cli.CmdLineParser.MyParser) owner;
  }

  @Override
  public int parseArguments(org.kohsuke.args4j.spi.Parameters params) throws CmdLineException {
    new Parameters(params, myParser).callParameters("--format", "json");
    setter.addValue(true);
    return 0; // we didn't consume any additional args
  }

  @Override
  public String getDefaultMetaVariable() {
   ...
  }
}

@RequiresOptions("--format")
@Option(
  name = "--special",
  usage = "ouptut results using json",
  handler = JsonOutputOptionHandler.class
)
boolean json;
----

[[query_attributes]]
== Change Attributes

Plugins can provide additional attributes to be returned from the Get Change and
Query Change APIs by implementing implementing the `ChangeAttributeFactory`
interface and adding it to the `DynamicSet` in the plugin module's `configure()`
method. The new attribute(s) will be output under a `plugin` attribute in the
change output. This can be further controlled by registering a class containing
@Option declarations as a `DynamicBean`, annotated with the with HTTP/SSH
commands on which the options should be available.

The example below shows a plugin that adds two attributes (`exampleName` and
`changeValue`), to the change query output, when the query command is provided
the `--myplugin-name--all` option.

[source, java]
----
public class Module extends AbstractModule {
  @Override
  protected void configure() {
    // Register attribute factory.
    DynamicSet.bind(binder(), ChangeAttributeFactory.class)
        .to(AttributeFactory.class);

    // Register options for GET /changes/X/change and /changes/X/detail.
    bind(DynamicBean.class)
        .annotatedWith(Exports.named(GetChange.class))
        .to(MyChangeOptions.class);

    // Register options for GET /changes/?q=...
    bind(DynamicBean.class)
        .annotatedWith(Exports.named(QueryChanges.class))
        .to(MyChangeOptions.class);

    // Register options for ssh gerrit query.
    bind(DynamicBean.class)
        .annotatedWith(Exports.named(Query.class))
        .to(MyChangeOptions.class);
  }
}

public class MyChangeOptions implements DynamicBean {
  @Option(name = "--all", usage = "Include plugin output")
  public boolean all = false;
}

public class AttributeFactory implements ChangeAttributeFactory {
  protected MyChangeOptions options;

  public class PluginAttribute extends PluginDefinedInfo {
    public String exampleName;
    public String changeValue;

    public PluginAttribute(ChangeData c) {
      this.exampleName = "Attribute Example";
      this.changeValue = Integer.toString(c.getId().get());
    }
  }

  @Override
  public PluginDefinedInfo create(ChangeData c, BeanProvider bp, String plugin) {
    if (options == null) {
      options = (MyChangeOptions) bp.getDynamicBean(plugin);
    }
    if (options.all) {
      return new PluginAttribute(c);
    }
    return null;
  }
}
----

Example:
----
$ ssh -p 29418 localhost gerrit query --myplugin-name--all "change:1" --format json
{
   "url" : "http://localhost:8080/1",
   "plugins" : [
      {
         "name" : "myplugin-name",
         "exampleName" : "Attribute Example",
         "changeValue" : "1"
      }
   ],
    ...
}

$ curl http://localhost:8080/changes/1?myplugin-name--all
{
  "_number": 1,
  ...
  "plugins": [
    {
      "name": "myplugin-name",
      "example_name": "Attribute Example",
      "change_value": "1"
    }
  ],
  ...
}
----

Implementors of the `ChangeAttributeFactory` interface should check whether
they need to contribute to the link:#change-etag-computation[change ETag
computation] to prevent callers using ETags from potentially seeing outdated
plugin attributes.

[[simple-configuration]]
== Simple Configuration in `gerrit.config`

In Gerrit, global configuration is stored in the `gerrit.config` file.
If a plugin needs global configuration, this configuration should be
stored in a `plugin` subsection in the `gerrit.config` file.

This approach of storing the plugin configuration is only suitable for
plugins that have a simple configuration that only consists of
key-value pairs. With this approach it is not possible to have
subsections in the plugin configuration. Plugins that require a complex
configuration need to store their configuration in their
link:#configuration[own configuration file] where they can make use of
subsections. On the other hand storing the plugin configuration in a
'plugin' subsection in the `gerrit.config` file has the advantage that
administrators have all configuration parameters in one file, instead
of having one configuration file per plugin.

To avoid conflicts with other plugins, it is recommended that plugins
only use the `plugin` subsection with their own name. For example the
`helloworld` plugin should store its configuration in the
`plugin.helloworld` subsection:

----
[plugin "helloworld"]
  language = Latin
----

Via the `com.google.gerrit.server.config.PluginConfigFactory` class a
plugin can easily access its configuration and there is no need for a
plugin to parse the `gerrit.config` file on its own:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

String language = cfg.getFromGerritConfig("helloworld")
                     .getString("language", "English");
----

[[configuration]]
== Configuration in own config file

Plugins can store their configuration in an own configuration file.
This makes sense if the plugin configuration is rather complex and
requires the usage of subsections. Plugins that have a simple
key-value pair configuration can store their configuration in a
link:#simple-configuration[`plugin` subsection of the `gerrit.config`
file].

The plugin configuration file must be named after the plugin and must
be located in the `etc` folder of the review site. For example a
configuration file for a `default-reviewer` plugin could look like
this:

.$site_path/etc/default-reviewer.config
----
[branch "refs/heads/master"]
  reviewer = Project Owners
  reviewer = john.doe@example.com
[match "file:^.*\.txt"]
  reviewer = My Info Developers
----

Plugins that have sensitive configuration settings can store those settings in
an own secure configuration file. The plugin's secure configuration file must be
named after the plugin and must be located in the `etc` folder of the review
site. For example a secure configuration file for a `default-reviewer` plugin
could look like this:

.$site_path/etc/default-reviewer.secure.config
----
[auth]
  password = secret
----

Via the `com.google.gerrit.server.config.PluginConfigFactory` class a
plugin can easily access its configuration:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

String[] reviewers = cfg.getGlobalPluginConfig("default-reviewer")
                        .getStringList("branch", "refs/heads/master", "reviewer");
String password = cfg.getGlobalPluginConfig("default-reviewer")
                     .getString("auth", null, "password");
----


[[simple-project-specific-configuration]]
== Simple Project Specific Configuration in `project.config`

In Gerrit, project specific configuration is stored in the project's
`project.config` file on the `refs/meta/config` branch.  If a plugin
needs configuration on project level (e.g. to enable its functionality
only for certain projects), this configuration should be stored in a
`plugin` subsection in the project's `project.config` file.

This approach of storing the plugin configuration is only suitable for
plugins that have a simple configuration that only consists of
key-value pairs. With this approach it is not possible to have
subsections in the plugin configuration. Plugins that require a complex
configuration need to store their configuration in their
link:#project-specific-configuration[own configuration file] where they
can make use of subsections. On the other hand storing the plugin
configuration in a 'plugin' subsection in the `project.config` file has
the advantage that project owners have all configuration parameters in
one file, instead of having one configuration file per plugin.

To avoid conflicts with other plugins, it is recommended that plugins
only use the `plugin` subsection with their own name. For example the
`helloworld` plugin should store its configuration in the
`plugin.helloworld` subsection:

----
[plugin "helloworld"]
  enabled = true
----

Via the `com.google.gerrit.server.config.PluginConfigFactory` class a
plugin can easily access its project specific configuration and there
is no need for a plugin to parse the `project.config` file on its own:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

boolean enabled = cfg.getFromProjectConfig(project, "helloworld")
                     .getBoolean("enabled", false);
----

It is also possible to get missing configuration parameters inherited
from the parent projects:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

boolean enabled = cfg.getFromProjectConfigWithInheritance(project, "helloworld")
                     .getBoolean("enabled", false);
----

Project owners can edit the project configuration by fetching the
`refs/meta/config` branch, editing the `project.config` file and
pushing the commit back.

Plugin configuration values that are stored in the `project.config`
file can be exposed in the ProjectInfoScreen to allow project owners
to see and edit them from the UI.

For this an instance of `ProjectConfigEntry` needs to be bound for each
parameter. The export name must be a valid Git variable name. The
variable name is case-insensitive, allows only alphanumeric characters
and '-', and must start with an alphabetic character.

The example below shows how the parameters `plugin.helloworld.enabled`
and `plugin.helloworld.language` are bound to be editable from the
Web UI. For the parameter `plugin.helloworld.enabled` "Enable Greeting"
is provided as display name and the default value is set to `true`.
For the parameter `plugin.helloworld.language` "Preferred Language"
is provided as display name and "en" is set as default value.

[source,java]
----
class Module extends AbstractModule {
  @Override
  protected void configure() {
    bind(ProjectConfigEntry.class)
        .annotatedWith(Exports.named("enabled"))
        .toInstance(new ProjectConfigEntry("Enable Greeting", true));
    bind(ProjectConfigEntry.class)
        .annotatedWith(Exports.named("language"))
        .toInstance(new ProjectConfigEntry("Preferred Language", "en"));
  }
}
----

By overwriting the `onUpdate` method of `ProjectConfigEntry` plugins
can be notified when this configuration parameter is updated on a
project.

[[configuring-groups]]
=== Referencing groups in `project.config`

Plugins can refer to groups so that when they are renamed, the project
config will also be updated in this section. The proper format to use is
the same as for any other group reference in the `project.config`, as shown below.

----
group group_name
----

The file `groups` must also contains the mapping of the group name and its UUID,
refer to link:config-project-config.html#file-groups[file groups]

[[project-specific-configuration]]
== Project Specific Configuration in own config file

Plugins can store their project specific configuration in an own
configuration file in the projects `refs/meta/config` branch.
This makes sense if the plugins project specific configuration is
rather complex and requires the usage of subsections. Plugins that
have a simple key-value pair configuration can store their project
specific configuration in a link:#simple-project-specific-configuration[
`plugin` subsection of the `project.config` file].

The plugin configuration file in the `refs/meta/config` branch must be
named after the plugin. For example a configuration file for a
`default-reviewer` plugin could look like this:

.default-reviewer.config
----
[branch "refs/heads/master"]
  reviewer = Project Owners
  reviewer = john.doe@example.com
[match "file:^.*\.txt"]
  reviewer = My Info Developers
----

Via the `com.google.gerrit.server.config.PluginConfigFactory` class a
plugin can easily access its project specific configuration:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

String[] reviewers = cfg.getProjectPluginConfig(project, "default-reviewer")
                        .getStringList("branch", "refs/heads/master", "reviewer");
----

It is also possible to get missing configuration parameters inherited
from the parent projects:

[source,java]
----
@Inject
private com.google.gerrit.server.config.PluginConfigFactory cfg;

[...]

String[] reviewers = cfg.getProjectPluginConfigWithInheritance(project, "default-reviewer")
                        .getStringList("branch", "refs/heads/master", "reviewer");
----

Project owners can edit the project configuration by fetching the
`refs/meta/config` branch, editing the `<plugin-name>.config` file and
pushing the commit back.

== React on changes in project configuration

If a plugin wants to react on changes in the project configuration, it
can implement a `GitReferenceUpdatedListener` and filter on events for
the `refs/meta/config` branch:

[source,java]
----
public class MyListener implements GitReferenceUpdatedListener {

  private final MetaDataUpdate.Server metaDataUpdateFactory;

  @Inject
  MyListener(MetaDataUpdate.Server metaDataUpdateFactory) {
    this.metaDataUpdateFactory = metaDataUpdateFactory;
  }

  @Override
  public void onGitReferenceUpdated(Event event) {
    if (event.getRefName().equals(RefNames.REFS_CONFIG)) {
      Project.NameKey p = new Project.NameKey(event.getProjectName());
      try {
        ProjectConfig oldCfg = parseConfig(p, event.getOldObjectId());
        ProjectConfig newCfg = parseConfig(p, event.getNewObjectId());

        if (oldCfg != null && newCfg != null
            && !oldCfg.getProject().getSubmitType().equals(newCfg.getProject().getSubmitType())) {
          // submit type has changed
          ...
        }
      } catch (IOException | ConfigInvalidException e) {
        ...
      }
    }
  }

  private ProjectConfig parseConfig(Project.NameKey p, String idStr)
      throws IOException, ConfigInvalidException, RepositoryNotFoundException {
    ObjectId id = ObjectId.fromString(idStr);
    if (ObjectId.zeroId().equals(id)) {
      return null;
    }
    return ProjectConfig.read(metaDataUpdateFactory.create(p), id);
  }
}
----

== Trace Event origin

When plugins are installed in a multi-master setups it can be useful to know
the Gerrit `instanceId` of the server that has generated an Event.

E.g. A plugin that sends an instance message for every comment on a change may
want to react only if the event is generated on the local Gerrit master, for
avoiding duplicating the notifications.

If link:config-gerrit.html[instanceId] is set, each Event will contain its
origin in the `instanceId` field.

Here and example of ref-updated JSON event payload with `instanceId`:

[source,json]
----
{
  "submitter": {
    "name": "Administrator",
    "email": "admin@example.com",
    "username": "admin"
  },
  "refUpdate": {
    "oldRev": "a69fc95c7aad5ad41c618d31548b8af835d2959a",
    "newRev": "31da6556d638a74e5370b62f83e8007f94abb7c6",
    "refName": "refs/changes/01/1/meta",
    "project": "test"
  },
  "type": "ref-updated",
  "eventCreatedOn": 1588849085,
  "instanceId": "instance1"
}
----

[[capabilities]]
== Plugin Owned Capabilities

Plugins may provide their own capabilities and restrict usage of SSH
commands or `UiAction` to the users who are granted those capabilities.

Plugins define the capabilities by overriding the `CapabilityDefinition`
abstract class:

[source,java]
----
public class PrintHelloCapability extends CapabilityDefinition {
  @Override
  public String getDescription() {
    return "Print Hello";
  }
}
----

If no Guice modules are declared in the manifest, capability may
use auto-registration by providing an `@Export` annotation:

[source,java]
----
@Export("printHello")
public class PrintHelloCapability extends CapabilityDefinition {
  [...]
}
----

Otherwise the capability must be bound in a plugin module:

[source,java]
----
public class HelloWorldModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(CapabilityDefinition.class)
      .annotatedWith(Exports.named("printHello"))
      .to(PrintHelloCapability.class);
  }
}
----

With a plugin-owned capability defined in this way, it is possible to restrict
usage of an SSH command or `UiAction` to members of the group that were granted
this capability in the usual way, using the `RequiresCapability` annotation:

[source,java]
----
@RequiresCapability("printHello")
@CommandMetaData(name="print", description="Print greeting in different languages")
public final class PrintHelloWorldCommand extends SshCommand {
  [...]
}
----

Or with `UiAction`:

[source,java]
----
@RequiresCapability("printHello")
public class SayHelloAction extends UiAction<RevisionResource>
  implements RestModifyView<RevisionResource, SayHelloAction.Input> {
  [...]
}
----

Capability scope was introduced to differentiate between plugin-owned
capabilities and core capabilities. Per default the scope of the
`@RequiresCapability` annotation is `CapabilityScope.CONTEXT`, that means:

* when `@RequiresCapability` is used within a plugin the scope of the
capability is assumed to be that plugin.

* If `@RequiresCapability` is used within the core Gerrit Code Review server
(and thus is outside of a plugin) the scope is the core server and will use
the `GlobalCapability` known to Gerrit Code Review server.

If a plugin needs to use a core capability name (e.g. "administrateServer")
this can be specified by setting `scope = CapabilityScope.CORE`:

[source,java]
----
@RequiresCapability(value = "administrateServer", scope =
    CapabilityScope.CORE)
  [...]
----

[[ui_extension]]
== UI Extension

[[panels]]
=== Panels

UI plugins can contribute panels to Gerrit screens.

Gerrit screens define extension points where plugins can add GWT
panels with custom controls:

* Change Screen:
** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER`:
+
Panel will be shown in the header bar to the right of the change
status.

** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_BUTTONS`:
+
Panel will be shown in the header bar on the right side of the buttons.

** `GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS`:
+
Panel will be shown in the header bar on the right side of the pop down
buttons.

** `GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_COMMIT_INFO_BLOCK`:
+
Panel will be shown below the commit info block.

** `GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK`:
+
Panel will be shown below the change info block.

** `GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_RELATED_INFO_BLOCK`:
+
Panel will be shown below the related info block.

** `GerritUiExtensionPoint.CHANGE_SCREEN_HISTORY_RIGHT_OF_BUTTONS`:
+
Panel will be shown in the history bar on the right side of the buttons.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.CHANGE_INFO`:
+
The link:rest-api-changes.html#change-info[ChangeInfo] entity for the
current change.
+
The link:rest-api-changes.html#revision-info[RevisionInfo] entity for
the current patch set.

* Project Info Screen:
** `GerritUiExtensionPoint.PROJECT_INFO_SCREEN_TOP`:
+
Panel will be shown at the top of the screen.

** `GerritUiExtensionPoint.PROJECT_INFO_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.PROJECT_NAME`:
+
The name of the project.

* User Password Screen:
** `GerritUiExtensionPoint.PASSWORD_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
+
The link:rest-api-accounts.html#account-info[AccountInfo] entity for
the current user.

* User Preferences Screen:
** `GerritUiExtensionPoint.PREFERENCES_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
+
The link:rest-api-accounts.html#account-info[AccountInfo] entity for
the current user.

* User Profile Screen:
** `GerritUiExtensionPoint.PROFILE_SCREEN_BOTTOM`:
+
Panel will be shown at the bottom of the screen below the grid with the
profile data.

** The following parameters are provided:
*** `GerritUiExtensionPoint.Key.ACCOUNT_INFO`:
+
The link:rest-api-accounts.html#account-info[AccountInfo] entity for
the current user.

Example panel:
[source,java]
----
public class MyPlugin extends PluginEntryPoint {
  @Override
  public void onPluginLoad() {
    Plugin.get().panel(GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
        "my_panel_name",
        new Panel.EntryPoint() {
          @Override
          public void onLoad(Panel panel) {
            panel.setWidget(new InlineLabel("My Panel for change "
                + panel.getInt(GerritUiExtensionPoint.Key.CHANGE_ID, -1));
          }
        });
  }
}
----

Change Screen panel ordering may be specified in the
project config. Values may be either "plugin name" or
"plugin name"."panel name".
Panels not specified in the config will be added
to the end in load order. Panels specified in the config that
are not found will be ignored.

Example config:
----
[extension-panels "CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK"]
  panel = helloworld.change_id
  panel = myotherplugin
  panel = myplugin.my_panel_name
----



[[actions]]
=== Actions

Plugins can contribute UI actions on core Gerrit pages. This is useful
for workflow customization or exposing plugin functionality through the
UI in addition to SSH commands and the REST API.

For instance a plugin to integrate Jira with Gerrit changes may
contribute a "File bug" button to allow filing a bug from the change
page or plugins to integrate continuous integration systems may
contribute a "Schedule" button to allow a CI build to be scheduled
manually from the patch set panel.

Two different places on core Gerrit pages are supported:

* Change screen
* Project info screen

Plugins contribute UI actions by implementing the `UiAction` interface:

[source,java]
----
@RequiresCapability("printHello")
class HelloWorldAction implements UiAction<RevisionResource>,
    RestModifyView<RevisionResource, HelloWorldAction.Input> {
  static class Input {
    boolean french;
    String message;
  }

  private Provider<CurrentUser> user;

  @Inject
  HelloWorldAction(Provider<CurrentUser> user) {
    this.user = user;
  }

  @Override
  public String apply(RevisionResource rev, Input input) {
    final String greeting = input.french
        ? "Bonjour"
        : "Hello";
    return String.format("%s %s from change %s, patch set %d!",
        greeting,
        Strings.isNullOrEmpty(input.message)
            ? Objects.firstNonNull(user.get().getUserName(), "world")
            : input.message,
        rev.getChange().getId().toString(),
        rev.getPatchSet().getPatchSetId());
  }

  @Override
  public Description getDescription(
      RevisionResource resource) {
    return new Description()
        .setLabel("Say hello")
        .setTitle("Say hello in different languages");
  }
}
----

Sometimes plugins may want to be able to change the state of a patch set or
change in the `UiAction.apply()` method and reflect these changes on the core
UI. For example a buildbot plugin which exposes a 'Schedule' button on the
patch set panel may want to disable that button after the build was scheduled
and update the tooltip of that button. But because of Gerrit's caching
strategy the following must be taken into consideration.

The browser is allowed to cache the `UiAction` information until something on
the change is modified. More accurately the change row needs to be modified in
the database to have a more recent `lastUpdatedOn` or a new `rowVersion`, or
the +refs/meta/config+ of the project or any parents needs to change to a new
SHA-1. The ETag SHA-1 computation code can be found in the
`ChangeResource.getETag()` method.

The easiest way to accomplish this is to update `lastUpdatedOn` of the change:

[source,java]
----
@Override
public Object apply(RevisionResource rcrs, Input in) {
  // schedule a build
  [...]
  // update change
  try (BatchUpdate bu = batchUpdateFactory.create(
      project.getNameKey(), user, TimeUtil.nowTs())) {
    bu.addOp(change.getId(), new BatchUpdate.Op() {
      @Override
      public boolean updateChange(ChangeContext ctx) {
        return true;
      }
    });
    bu.execute();
  }
  [...]
}
----

`UiAction` must be bound in a plugin module:

[source,java]
----
public class Module extends AbstractModule {
  @Override
  protected void configure() {
    install(new RestApiModule() {
      @Override
      protected void configure() {
        post(REVISION_KIND, "say-hello")
            .to(HelloWorldAction.class);
      }
    });
  }
}
----

The module above must be declared in the `pom.xml` for Maven driven
plugins:

[source,xml]
----
<manifestEntries>
  <Gerrit-Module>com.googlesource.gerrit.plugins.cookbook.Module</Gerrit-Module>
</manifestEntries>
----

or in the `BUILD` configuration file for Bazel driven plugins:

[source,python]
----
manifest_entries = [
  'Gerrit-Module: com.googlesource.gerrit.plugins.cookbook.Module',
]
----

In some use cases more user input must be gathered, for that `UiAction` can be
combined with the JavaScript API. This would display a small popup near the
activation button to gather additional input from the user. The JS file is
typically put in the `static` folder within the plugin's directory:

[source,javascript]
----
Gerrit.install(function(self) {
  function onSayHello(c) {
    var f = c.textfield();
    var t = c.checkbox();
    var b = c.button('Say hello', {onclick: function(){
      c.call(
        {message: f.value, french: t.checked},
        function(r) {
          c.hide();
          window.alert(r);
          c.refresh();
        });
    }});
    c.popup(c.div(
      c.prependLabel('Greeting message', f),
      c.br(),
      c.label(t, 'french'),
      c.br(),
      b));
    f.focus();
  }
  self.onAction('revision', 'say-hello', onSayHello);
});
----

The JS module must be exposed as a `WebUiPlugin` and bound as
an HTTP Module:

[source,java]
----
public class HttpModule extends ServletModule {
  @Override
  protected void configureServlets() {
    DynamicSet.bind(binder(), WebUiPlugin.class)
        .toInstance(new JavaScriptPlugin("hello.js"));
  }
}
----

The HTTP module above must be declared in the `pom.xml` for Maven
driven plugins:

[source,xml]
----
<manifestEntries>
  <Gerrit-HttpModule>com.googlesource.gerrit.plugins.cookbook.HttpModule</Gerrit-HttpModule>
</manifestEntries>
----

or in the `BUILD` configuration file for Bazel driven plugins

[source,python]
----
manifest_entries = [
  'Gerrit-HttpModule: com.googlesource.gerrit.plugins.cookbook.HttpModule',
]
----

If `UiAction` is annotated with the `@RequiresCapability` annotation, then the
capability check is done during the `UiAction` gathering, so the plugin author
doesn't have to set `UiAction.Description.setVisible()` explicitly in this
case.

The following prerequisites must be met, to satisfy the capability check:

* user is authenticated
* user is a member of a group which has the `Administrate Server` capability, or
* user is a member of a group which has the required capability

The `apply` method is called when the button is clicked. If `UiAction` is
combined with JavaScript API (its own JavaScript function is provided),
then a popup dialog is normally opened to gather additional user input.
A new button is placed on the popup dialog to actually send the request.

Every `UiAction` exposes a REST API endpoint. The endpoint from the example above
can be accessed from any REST client, i. e.:

----
$ curl -X POST -H "Content-Type: application/json" \
    -d '{message: "François", french: true}' \
    --user joe:secret \
    http://host:port/a/changes/1/revisions/1/cookbook~say-hello
"Bonjour François from change 1, patch set 1!"
----

A special case is to bind an endpoint without a view name.  This is
particularly useful for `DELETE` requests:

[source,java]
----
public class Module extends AbstractModule {
  @Override
  protected void configure() {
    install(new RestApiModule() {
      @Override
      protected void configure() {
        delete(PROJECT_KIND)
            .to(DeleteProject.class);
      }
    });
  }
}
----

For a `UiAction` bound this way, a JS API function can be provided.

Currently only one restriction exists: per plugin only one `UiAction`
can be bound per resource without view name. To define a JS function
for the `UiAction`, "/" must be used as the name:

[source,javascript]
----
Gerrit.install(function(self) {
  function onDeleteProject(c) {
    [...]
  }
  self.onAction('project', '/', onDeleteProject);
});
----


[[action-visitor]]
=== Action Visitors

In addition to providing new actions, plugins can have fine-grained control
over the link:rest-api-changes.html#action-info[ActionInfo] map, modifying or
removing existing actions, including those contributed by core.

Visitors are provided the link:rest-api-changes.html#action-info[ActionInfo],
which is mutable, along with copies of the
link:rest-api-changes.html#change-info[ChangeInfo] and
link:rest-api-changes.html#revision-info[RevisionInfo]. They can modify the
action, or return `false` to exclude it from the resulting map.

These operations only affect the action buttons that are displayed in the UI;
the underlying REST API endpoints are not affected. Multiple plugins may
implement the visitor interface, but the order in which they are run is
undefined.

For example, to exclude "Cherry-Pick" only from certain projects, and rename
"Abandon":

[source,java]
----
public class MyActionVisitor implements ActionVisitor {
  @Override
  public boolean visit(String name, ActionInfo actionInfo,
      ChangeInfo changeInfo) {
    if (name.equals("abandon")) {
      actionInfo.label = "Drop";
    }
    return true;
  }

  @Override
  public boolean visit(String name, ActionInfo actionInfo,
      ChangeInfo changeInfo, RevisionInfo revisionInfo) {
    if (project.startsWith("some-team/") && name.equals("cherrypick")) {
      return false;
    }
    return true;
  }
}
----


[[top-menu-extensions]]
== Top Menu Extensions

Plugins can contribute items to Gerrit's top menu.

A single top menu extension can have multiple elements and will be put as
the last element in Gerrit's top menu.

Plugins define the top menu entries by implementing `TopMenu` interface:

[source,java]
----
public class MyTopMenuExtension implements TopMenu {
  @Override
  public List<MenuEntry> getEntries() {
    return Lists.newArrayList(
               new MenuEntry("Top Menu Entry", Lists.newArrayList(
                      new MenuItem("Gerrit", "http://gerrit.googlecode.com/"))));
  }
}
----

Plugins can also add additional menu items to Gerrit's top menu entries
by defining a `MenuEntry` that has the same name as a Gerrit top menu
entry:

[source,java]
----
public class MyTopMenuExtension implements TopMenu {
  @Override
  public List<MenuEntry> getEntries() {
    return Lists.newArrayList(
               new MenuEntry(GerritTopMenu.PROJECTS, Lists.newArrayList(
                      new MenuItem("Browse Repositories", "https://gerrit.googlesource.com/"))));
  }
}
----

`MenuItems` that are bound for the `MenuEntry` with the name
`GerritTopMenu.PROJECTS` can contain a `${projectName}` placeholder
which is automatically replaced by the actual project name.

E.g. plugins may register an link:#http[HTTP Servlet] to handle project
specific requests and add an menu item for this:

[source,java]
----
new MenuItem("My Screen", "/plugins/myplugin/project/${projectName}");
----

This also enables plugins to provide menu items for project aware
screens:

[source,java]
----
new MenuItem("My Screen", "/x/my-screen/for/${projectName}");
----

If no Guice modules are declared in the manifest, the top menu extension may use
auto-registration by providing an `@Listen` annotation:

[source,java]
----
@Listen
public class MyTopMenuExtension implements TopMenu {
  [...]
}
----

Otherwise the top menu extension must be bound in the plugin module used
for the Gerrit system injector (Gerrit-Module entry in MANIFEST.MF):

[source,java]
----
package com.googlesource.gerrit.plugins.helloworld;

public class HelloWorldModule extends AbstractModule {
  @Override
  protected void configure() {
    DynamicSet.bind(binder(), TopMenu.class).to(MyTopMenuExtension.class);
  }
}
----

[source,manifest]
----
Gerrit-ApiType: plugin
Gerrit-Module: com.googlesource.gerrit.plugins.helloworld.HelloWorldModule
----

It is also possible to show some menu entries only if the user has a
certain capability:

[source,java]
----
public class MyTopMenuExtension implements TopMenu {
  private final String pluginName;
  private final Provider<CurrentUser> userProvider;
  private final List<MenuEntry> menuEntries;

  @Inject
  public MyTopMenuExtension(@PluginName String pluginName,
      Provider<CurrentUser> userProvider) {
    this.pluginName = pluginName;
    this.userProvider = userProvider;
    menuEntries = new ArrayList<TopMenu.MenuEntry>();

    // add menu entry that is only visible to users with a certain capability
    if (canSeeMenuEntry()) {
      menuEntries.add(new MenuEntry("Top Menu Entry", Collections
          .singletonList(new MenuItem("Gerrit", "http://gerrit.googlecode.com/"))));
    }

    // add menu entry that is visible to all users (even anonymous users)
    menuEntries.add(new MenuEntry("Top Menu Entry", Collections
          .singletonList(new MenuItem("Documentation", "/plugins/myplugin/"))));
  }

  private boolean canSeeMenuEntry() {
    if (userProvider.get().isIdentifiedUser()) {
      CapabilityControl ctl = userProvider.get().getCapabilities();
      return ctl.canPerform(pluginName + "-" + MyCapability.ID)
          || ctl.canAdministrateServer();
    } else {
      return false;
    }
  }

  @Override
  public List<MenuEntry> getEntries() {
    return menuEntries;
  }
}
----


[[settings-screen]]
== Plugin Settings Screen

If a plugin implements a screen for administrating its settings that is
available under "#/x/<plugin-name>/settings" it is automatically linked
from the plugin list screen.

[[http]]
== HTTP Servlets

Plugins or extensions may register additional HTTP servlets, and
wrap them with HTTP filters.

Servlets may use auto-registration to declare the URL they handle:

[source,java]
----
import com.google.gerrit.extensions.annotations.Export;
import com.google.inject.Singleton;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Export("/print")
@Singleton
class HelloServlet extends HttpServlet {
  protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    res.setContentType("text/plain");
    res.setCharacterEncoding("UTF-8");
    res.getWriter().write("Hello");
  }
}
----

The auto registration only works for standard servlet mappings like
`/foo` or `+/foo/*+`. Regex style bindings must use a Guice ServletModule
to register the HTTP servlets and declare it explicitly in the manifest
with the `Gerrit-HttpModule` attribute:

[source,java]
----
import com.google.inject.servlet.ServletModule;

class MyWebUrls extends ServletModule {
  protected void configureServlets() {
    serve("/print").with(HelloServlet.class);
  }
}
----

For a plugin installed as name `helloworld`, the servlet implemented
by HelloServlet class will be available to users as:

----
$ curl http://review.example.com/plugins/helloworld/print
----

[[data-directory]]
== Data Directory

Plugins can request a data directory with a `@PluginData` Path (or File,
deprecated) dependency. A data directory will be created automatically
by the server in `$site_path/data/$plugin_name` and passed to the
plugin.

Plugins can use this to store any data they want.

[source,java]
----
@Inject
MyType(@PluginData java.nio.file.Path myDir) {
  this.in = Files.newInputStream(myDir.resolve("my.config"));
}
----

[[secure-store]]
== SecureStore

SecureStore allows to change the way Gerrit stores sensitive data like
passwords.

In order to replace the default SecureStore (no-op) implementation,
a class that extends `com.google.gerrit.server.securestore.SecureStore`
needs to be provided (with dependencies) in a separate jar file. Then
link:pgm-SwitchSecureStore.html[SwitchSecureStore] must be run to
switch implementations.

The SecureStore implementation is instantiated using a Guice injector
which binds the `File` annotated with the `@SitePath` annotation.
This means that a SecureStore implementation class can get access to
the `site_path` like in the following example:

[source,java]
----
@Inject
MySecureStore(@SitePath java.io.File sitePath) {
  // your code
}
----

No Guice bindings or modules are required. Gerrit will automatically
discover and bind the implementation.

[[gerrit-replica]]
== Gerrit Replica

Gerrit can be run as a read-only replica. Some plugins may need to know
whether Gerrit is run as a primary- or a replica instance. For that purpose
Gerrit exposes the `@GerritIsReplica` annotation. A boolean annotated with
this annotation will indicate whether Gerrit is run as a replica.

[[accountcreation]]
== Account Creation

Plugins can hook into the
link:rest-api-accounts.html#create-account[account creation] REST API and
inject additional external identifiers for an account that represents a user
in some external user store. For that, an implementation of the extension
point `com.google.gerrit.server.account.AccountExternalIdCreator`
must be registered.

[source,java]
----
class MyExternalIdCreator implements AccountExternalIdCreator {
  @Override
  public List<AccountExternalId> create(Account.Id id, String username,
      String email) {
    // your code
  }
}

bind(AccountExternalIdCreator.class)
  .annotatedWith(UniqueAnnotations.create())
  .to(MyExternalIdCreator.class);
----

[[download-commands]]
== Download Commands

Gerrit offers commands for downloading changes and cloning projects
using different download schemes (e.g. for downloading via different
network protocols). Plugins can contribute download schemes, download
commands and clone commands by implementing
`com.google.gerrit.extensions.config.DownloadScheme`,
`com.google.gerrit.extensions.config.DownloadCommand` and
`com.google.gerrit.extensions.config.CloneCommand`.

The download schemes, download commands and clone commands which are
used most often are provided by the Gerrit core plugin
`download-commands`.

[[included-in]]
== Included In

For merged changes the link:user-review-ui.html#included-in[Included In]
drop-down panel shows the branches and tags in which the change is
included.

Plugins can add additional systems in which the change can be included
by implementing `com.google.gerrit.extensions.config.ExternalIncludedIn`,
e.g. a plugin can provide a list of servers on which the change was
deployed.

[[change-report-formatting]]
== Change Report Formatting

When a change is pushed for review from the command line, Gerrit reports
the change(s) received with their URL and subject.

By implementing the
`com.google.gerrit.server.git.ChangeReportFormatter` interface, a plugin
may change the formatting of the report.

[[url-formatting]]
== URL Formatting

URLs to various parts of Gerrit are usually formed by adding suffixes to
the canonical web URL.

By implementing the
`com.google.gerrit.server.config.UrlFormatter` interface, a plugin may
change the format of the URL.

[[links-to-external-tools]]
== Links To External Tools

Gerrit has extension points that enables development of a
light-weight plugin that links commits to external
tools (GitBlit, CGit, company specific resources etc).

PatchSetWebLinks will appear to the right of the commit-SHA1 in the UI.

[source, java]
----
import com.google.gerrit.extensions.annotations.Listen;
import com.google.gerrit.extensions.webui.PatchSetWebLink;;
import com.google.gerrit.extensions.webui.WebLinkTarget;

@Listen
public class MyWeblinkPlugin implements PatchSetWebLink {
  private String name = "MyLink";
  private String placeHolderUrlProjectCommit = "http://my.tool.com/project=%s/commit=%s";
  private String imageUrl = "http://placehold.it/16x16.gif";

  @Override
  public WebLinkInfo getPatchSetWebLink(String projectName, String commit) {
    return new WebLinkInfo(name,
        imageUrl,
        String.format(placeHolderUrlProjectCommit, project, commit),
        WebLinkTarget.BLANK);
  }
}
----

ParentWebLinks will appear to the right of the SHA1 of the parent
revisions in the UI. The implementation should in most use cases direct
to the same external service as PatchSetWebLink; it is provided as a
separate interface because not all users want to have links for the
parent revisions.

FileWebLinks will appear in the side-by-side diff screen on the right
side of the patch selection on each side.

DiffWebLinks will appear in the side-by-side and unified diff screen in
the header next to the navigation icons.

ProjectWebLinks will appear in the project list in the
`Repository Browser` column.

BranchWebLinks will appear in the branch list in the last column.

FileHistoryWebLinks will appear on the access rights screen.

TagWebLinks will appear in the tag list in the last column.

If a `get*WebLink` implementation returns `null`, the link will be omitted. This
allows the plugin to selectively "enable" itself on a per-project/branch/file
basis.

[[lfs-extension]]
== LFS Storage Plugins

Gerrit provides an extension point that enables development of
link:https://github.com/github/git-lfs/blob/master/docs/api/v1/http-v1-batch.md[
LFS (Large File Storage),role=external,window=_blank] storage plugins. Gerrit core exposes the default LFS
protocol endpoint `<project-name>/info/lfs/objects/batch` and forwards the requests
to the configured link:config-gerrit.html#lfs[lfs.plugin] plugin which implements
the LFS protocol. By exposing the default LFS endpoint, the git-lfs client can be
used without any configuration.

[source, java]
----
/** Provide an LFS protocol implementation */
import org.eclipse.jgit.lfs.server.LargeFileRepository;
import org.eclipse.jgit.lfs.server.LfsProtocolServlet;

@Singleton
public class LfsApiServlet extends LfsProtocolServlet {
  private static final long serialVersionUID = 1L;

  private final S3LargeFileRepository repository;

  @Inject
  LfsApiServlet(S3LargeFileRepository repository) {
    this.repository = repository;
  }

  @Override
  protected LargeFileRepository getLargeFileRepository() {
    return repository;
  }
}

/** Register the LfsApiServlet to listen on the default LFS protocol endpoint */
import static com.google.gerrit.httpd.plugins.LfsPluginServlet.URL_REGEX;

import com.google.inject.servlet.ServletModule;

public class HttpModule extends ServletModule {
  @Override
  protected void configureServlets() {
    serveRegex(URL_REGEX).with(LfsApiServlet.class);
  }
}

/** Provide an implementation of the LargeFileRepository */
import org.eclipse.jgit.lfs.server.s3.S3Repository;

public class S3LargeFileRepository extends S3Repository {
  ...
}
----

[[metrics]]
== Metrics

=== Metrics Reporting

To send Gerrit's metrics data to an external reporting backend, a plugin can
get a `MetricRegistry` injected and register an instance of a class that
implements the `Reporter` interface from link:http://metrics.dropwizard.io/[
DropWizard Metrics,role=external,window=_blank].

Metric reporting plugin implementations are provided for
link:https://gerrit.googlesource.com/plugins/metrics-reporter-jmx/[JMX,role=external,window=_blank],
link:https://gerrit.googlesource.com/plugins/metrics-reporter-elasticsearch/[Elastic Search,role=external,window=_blank],
and link:https://gerrit.googlesource.com/plugins/metrics-reporter-graphite/[Graphite,role=external,window=_blank].

There is also a working example of reporting metrics to the console in the
link:https://gerrit.googlesource.com/plugins/cookbook-plugin/+/master/src/main/java/com/googlesource/gerrit/plugins/cookbook/ConsoleMetricReporter.java[
cookbook plugin,role=external,window=_blank].

=== Providing own metrics

Plugins may provide metrics to be dispatched to external reporting services by
getting a `MetricMaker` injected and creating instances of specific types of
metric:

* Counter
+
Metric whose value increments during the life of the process.

* Timer
+
Metric recording time spent on an operation.

* Histogram
+
Metric recording statistical distribution (rate) of values.

Note that metrics cannot be recorded from plugin init steps that
are run during site initialization.

By default, plugin metrics are recorded under
`plugins/${plugin-name}/${metric-name}`. This can be changed by
setting `plugins.${plugin-name}.metricsPrefix` in the `gerrit.config`
file. For example:

----
[plugin "my-plugin"]
  metricsPrefix = my-metrics
----

will cause the metrics to be recorded under `my-metrics/${metric-name}`.

See the replication metrics in the
link:https://gerrit.googlesource.com/plugins/replication/+/master/src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationMetrics.java[
replication plugin,role=external,window=_blank] for an example of usage.

[[account-patch-review-store]]
== AccountPatchReviewStore

The AccountPatchReviewStore is used to store reviewed flags on changes.
A reviewed flag is a tuple of (patch set ID, file, account ID) and
records whether the user has reviewed a file in a patch set. Each user
can easily have thousands of reviewed flags and the number of reviewed
flags is growing without bound. The store must be able handle this data
volume efficiently.

Gerrit implements this extension point, but plugins may bind another
implementation, e.g. one that supports cluster setup with multiple
primary Gerrit nodes handling write operations.

[source,java]
----
DynamicItem.bind(binder(), AccountPatchReviewStore.class)
    .to(MultiMasterAccountPatchReviewStore.class);

...

public class MultiMasterAccountPatchReviewStore
    implements AccountPatchReviewStore {
  ...
}
----


[[documentation]]
== Documentation

If a plugin does not register a filter or servlet to handle URLs
`+/Documentation/*+` or `+/static/*+`, the core Gerrit server will
automatically export these resources over HTTP from the plugin JAR.

Static resources under the `static/` directory in the JAR will be
available as `/plugins/helloworld/static/resource`. This prefix is
configurable by setting the `Gerrit-HttpStaticPrefix` attribute.

Documentation files under the `Documentation/` directory in the JAR
will be available as `/plugins/helloworld/Documentation/resource`. This
prefix is configurable by setting the `Gerrit-HttpDocumentationPrefix`
attribute.

Documentation may be written in the Markdown flavor
link:https://github.com/vsch/flexmark-java[flexmark-java,role=external,window=_blank]
if the file name ends with `.md`. Gerrit will automatically convert
Markdown to HTML if accessed with extension `.html`.

[[macros]]
Within the Markdown documentation files macros can be used that allow
to write documentation with reasonably accurate examples that adjust
automatically based on the installation.

The following macros are supported:

[width="40%",options="header"]
|===================================================
|Macro       | Replacement
|@PLUGIN@    | name of the plugin
|@URL@       | Gerrit Web URL
|@SSH_HOST@  | SSH Host
|@SSH_PORT@  | SSH Port
|===================================================

The macros will be replaced when the documentation files are rendered
from Markdown to HTML.

Macros that start with `\` such as `\@KEEP@` will render as `@KEEP@`
even if there is an expansion for `KEEP` in the future.

[[auto-index]]
=== Automatic Index

If a plugin does not handle its `/` URL itself, Gerrit will
redirect clients to the plugin's `/Documentation/index.html`.
Requests for `/Documentation/` (bare directory) will also redirect
to `/Documentation/index.html`.

If neither resource `Documentation/index.html` or
`Documentation/index.md` exists in the plugin JAR, Gerrit will
automatically generate an index page for the plugin's documentation
tree by scanning every `*.md` and `*.html` file in the Documentation/
directory.

For any discovered Markdown (`*.md`) file, Gerrit will parse the
header of the file and extract the first level one title. This
title text will be used as display text for a link to the HTML
version of the page.

For any discovered HTML (`*.html`) file, Gerrit will use the name
of the file, minus the `*.html` extension, as the link text. Any
hyphens in the file name will be replaced with spaces.

If a discovered file is named `about.md` or `about.html`, its
content will be inserted in an 'About' section at the top of the
auto-generated index page.  If both `about.md` and `about.html`
exist, only the first discovered file will be used.

If a discovered file name beings with `cmd-` it will be clustered
into a 'Commands' section of the generated index page.

If a discovered file name beings with `servlet-` it will be clustered
into a 'Servlets' section of the generated index page.

If a discovered file name beings with `rest-api-` it will be clustered
into a 'REST APIs' section of the generated index page.

All other files are clustered under a 'Documentation' section.

Some optional information from the manifest is extracted and
displayed as part of the index page, if present in the manifest:

[width="40%",options="header"]
|===================================================
|Field       | Source Attribute
|Name        | Implementation-Title
|Vendor      | Implementation-Vendor
|Version     | Implementation-Version
|URL         | Implementation-URL
|API Version | Gerrit-ApiVersion
|===================================================

[[deployment]]
== Deployment

Compiled plugins and extensions can be deployed to a running Gerrit
server using the link:cmd-plugin-install.html[plugin install] command.

Web UI plugins distributed as a single `.js` file (or `.html` file for
Polygerrit) can be deployed without the overhead of JAR packaging. For
more information refer to link:cmd-plugin-install.html[plugin install]
command.

Plugins can also be copied directly into the server's directory at
`$site_path/plugins/$name.(jar|js|html)`. For Web UI plugins, the name
of the file, minus the `.js` or `.html` extension, will be used as the
plugin name. For JAR plugins, the value of the `Gerrit-PluginName`
manifest attribute will be used, if provided, otherwise the name of
the file, minus the `.jar` extension, will be used.

For Web UI plugins, the plugin version is derived from the filename.
If the filename contains one or more hyphens, the version is taken
from the portion following the last hyphen. For example if the plugin
filename is `my-plugin-1.0.js` the version will be `1.0`. For JAR
plugins, the version is taken from the `Version` attribute in the
manifest.

Unless disabled, servers periodically scan the `$site_path/plugins`
directory for updated plugins. The time can be adjusted by
link:config-gerrit.html#plugins.checkFrequency[plugins.checkFrequency].

For disabling plugins the link:cmd-plugin-remove.html[plugin remove]
command can be used.

Disabled plugins can be re-enabled using the
link:cmd-plugin-enable.html[plugin enable] command.

[[reviewer-suggestion]]
== Reviewer Suggestion Plugins

Gerrit provides an extension point that enables Plugins to rank
the list of reviewer suggestion a user receives upon clicking "Add Reviewer" on
the change screen.

Gerrit supports both a default suggestion that appears when the user has not yet
typed anything and a filtered suggestion that is shown as the user starts
typing.

Plugins receive a candidate list and can return a `Set` of suggested reviewers
containing the `Account.Id` and a score for each reviewer. The candidate list is
non-binding and plugins can choose to return reviewers not initially contained in
the candidate list.

Server administrators can configure the overall weight of each plugin by setting
the `addreviewer.pluginName-exportName.weight` value in `gerrit.config`.

[source, java]
----
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.annotations.ExtensionPoint;

import java.util.Set;

public class MyPlugin implements ReviewerSuggestion {
  public Set<SuggestedReviewer> suggestReviewers(Project.NameKey project,
      @Nullable Change.Id changeId, @Nullable String query,
      Set<Account.Id> candidates) {
    Set<SuggestedReviewer> suggestions = new HashSet<>();
    // Implement your ranking logic here
    return suggestions;
  }
}
----


[[mail-filter]]
== Mail Filter Plugins

Gerrit provides an extension point that enables Plugins to discard incoming
messages and prevent further processing by Gerrit.

This can be used to implement spam checks, signature validations or organization
specific checks like IP filters.

[source, java]
----
import com.google.gerrit.extensions.annotations.ExtensionPoint;
import com.google.gerrit.mail.MailMessage;

public class MyPlugin implements MailFilter {
  public boolean shouldProcessMessage(MailMessage message) {
    // Implement your filter logic here
    return true;
  }
}
----

[[ssh-command-creation-interception]]
== SSH Command Creation Interception

Gerrit provides an extension point that allows a plugin to intercept
creation of SSH commands and override the functionality with its own
implementation.

[source, java]
----
import com.google.gerrit.sshd.SshCreateCommandInterceptor;

class MyCommandInterceptor implements SshCreateCommandInterceptor {
  @Override
  public String intercept(String in) {
    return pluginName + " mycommand";
  }
}
----

[[ssh-command-execution-interception]]
== SSH Command Execution Interception
Gerrit provides an extension point that enables plugins to check and
prevent an SSH command from being run.

[source, java]
----
import com.google.gerrit.sshd.SshExecuteCommandInterceptor;

@Singleton
public class SshExecuteCommandInterceptorImpl implements SshExecuteCommandInterceptor {
  private final Provider<SshSession> sessionProvider;

  @Inject
  SshExecuteCommandInterceptorImpl(Provider<SshSession> sessionProvider) {
    this.sessionProvider = sessionProvider;
  }

  @Override
  public boolean accept(String command, List<String> arguments) {
    if (command.startsWith("gerrit") && !"10.1.2.3".equals(sessionProvider.get().getRemoteAddressAsString())) {
      return false;
    }
    return true;
  }
}
----

And then declare it in your SSH module:
[source, java]
----
DynamicSet.bind(binder(), SshExecuteCommandInterceptor.class)
  .to(SshExecuteCommandInterceptorImpl.class);
----

[[pre-submit-evaluator]]
== Pre-submit Validation Plugins

Gerrit provides an extension point that enables plugins to prevent a change
from being submitted.

[IMPORTANT]
This extension point **must NOT** be used for long or slow operations, like
calling external programs or content, running unit tests...
Slow operations will hurt the whole Gerrit instance.

This can be used to implement custom rules that changes have to match to become
submittable. A more concrete example: the Prolog rules engine can be
implemented using this.

Gerrit calls the plugins once per change and caches the results. Although it is
possible to predict when this interface will be triggered, this should not be
considered as a feature. Plugins should only rely on the internal state of the
ChangeData, not on external values like date and time, remote content or
randomness.

Plugins are expected to support rules inheritance themselves, providing ways
to configure it and handling the logic behind it.
Please note that no inheritance is sometimes better than badly handled
inheritance: mis-communication and strange behaviors caused by inheritance
may and will confuse the users. Each plugins is responsible for handling the
project hierarchy and taking wise actions. Gerrit does not enforce it.

Once Gerrit has gathered every plugins' SubmitRecords, it stores them.

Plugins accept or reject a given change using `SubmitRecord.Status`.
If a change is ready to be submitted, `OK`. If it is not ready and requires
modifications, `NOT_READY`. Other statuses are available for particular cases.
A change can be submitted if all the plugins accept the change.

Plugins may also decide not to vote on a given change by returning an
`Optional.empty()` (ie: the plugin is not enabled for this repository).

If a plugin decides not to vote, it's name will not be displayed in the UI and
it will not be recoded in the database.

.Gerrit's Pre-submit handling with three plugins
[width="50%",cols="^m,^m,^m,^m",frame="topbot",options="header"]
|=======================================================
|  Plugin A  |  Plugin B  |  Plugin C  | Final decision
|     OK     |     OK     |     OK     | OK
|     OK     |     OK     |     /      | OK
|     OK     |     OK     | RULE_ERROR | NOT_READY
|     OK     | NOT_READY  |     OK     | NOT_READY
|  NOT_READY |     OK     |     OK     | NOT_READY
|=======================================================


This makes composing plugins really easy.

- If a plugin places a veto on a change, it can't be submitted.
- If a plugin isn't enabled for a project (or isn't needed for this change),
  it returns an empty collection.
- If all the plugins answer `OK`, the change can be submitted.


A more rare case, but worth documenting: if there are no installed plugins,
the labels will be compared to the rules defined in the project's config,
and the permission system will be used to allow or deny a submit request.

Some rules are defined internally to provide a common base ground (and sanity):
changes that are marked as WIP or that are closed (abandoned, merged) can't be merged.


[source, java]
----
import java.util.Optional;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.common.data.SubmitRecord.Status;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.rules.SubmitRule;

public class MyPluginRules implements SubmitRule {
  public Optional<SubmitRecord> evaluate(ChangeData changeData) {
    // Implement your submitability logic here

    // Assuming we want to prevent this change from being submitted:
    SubmitRecord record = new SubmitRecord();
    record.status = Status.NOT_READY;
    return Optional.of(record);
  }
}
----

Don't forget to register your class!

[source, java]
----
import com.google.gerrit.extensions.annotations.Exports;
import com.google.inject.AbstractModule;

public class MyPluginModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(SubmitRule.class).annotatedWith(Exports.named("myPlugin")).to(MyPluginRules.class);
  }
}
----

Plugin authors should also consider binding their SubmitRule using a `Gerrit-BatchModule`.
See link:dev-plugins.html[Batch runtime] for more informations.


The SubmitRule extension point allows you to write complex rules, but writing
small self-contained rules should be preferred: doing so allows end users to
compose several rules to form more complex submit checks.

The `SubmitRequirement` class allows rules to communicate what the user needs
to change in order to be compliant. These requirements should be kept once they
are met, but marked as `OK`. If the requirements were not displayed, reviewers
would need to use their precious time to manually check that they were met.

Implementors of the `SubmitRule` interface should check whether they need to
contribute to the link:#change-etag-computation[change ETag computation] to
prevent callers using ETags from potentially seeing outdated submittability
information.

[[change-etag-computation]]
== Change ETag Computation

By implementing the `com.google.gerrit.server.change.ChangeETagComputation`
interface plugins can contribute a value to the change ETag computation.

Plugins can affect the result of the get change / get change details REST
endpoints by:

* providing link:#query_attributes[plugin defined attributes] in
  link:rest-api-changes.html#change-info[ChangeInfo]
* implementing a link:#pre-submit-evaluator[pre-submit evaluator] which affects
  the computation of `submittable` field in
  link:rest-api-changes.html#change-info[ChangeInfo]

If the plugin defined part of link:rest-api-changes.html#change-info[
ChangeInfo] depends on plugin specific data, callers that use change ETags to
avoid unneeded recomputations of ChangeInfos may see outdated plugin attributes
and/or outdated submittable information, because a ChangeInfo is only reloaded
if the change ETag changes.

By implementating the `com.google.gerrit.server.change.ChangeETagComputation`
interface plugins can contribute to the ETag computation and thus ensure that
the change ETag changes when the plugin data was changed. This way it can be
ensured that callers do not see outdated ChangeInfos.

IMPORTANT: Change ETags are computed very frequently and the computation must
be cheap. Take good care to not perform any expensive computations when
implementing this.

[source, java]
----
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.hash.Hasher;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.change.ChangeETagComputation;

public class MyPluginChangeETagComputation implements ChangeETagComputation {
  public String getETag(Project.NameKey projectName, Change.Id changeId) {
    Hasher hasher = Hashing.murmur3_128().newHasher();

    // Add hashes for all plugin-specific data that affects change infos.
    hasher.putString(sha1OfPluginSpecificChangeRef, UTF_8);

    return hasher.hash().toString();
  }
}
----

[[exception-hook]]
== ExceptionHook

An `ExceptionHook` allows implementors to control how certain
exceptions should be handled.

This interface is intended to be implemented for multi-master setups to
control the behavior for handling exceptions that are thrown by a lower
layer that handles the consensus and synchronization between different
server nodes. E.g. if an operation fails because consensus for a Git
update could not be achieved (e.g. due to slow responding server nodes)
this interface can be used to retry the request instead of failing it
immediately.

It also allows implementors to group exceptions that have the same
cause into one metric bucket.

[[mail-soy-template-provider]]
== MailSoyTemplateProvider

This extension point allows to provide soy templates for registration
so that they can be used for sending emails from a plugin.

[[quota-enforcer]]
== Quota Enforcer

Gerrit provides an extension point that allows a plugin to enforce quota.
link:quota.html[This documentation page] has a list of all quota requests that
Gerrit core issues. Plugins can choose to respond to all or just a subset of
requests. Some implementations might want to keep track of user quota in buckets,
others might just check against instance or project state to enforce limits on how
many projects can be created or how large a repository can become.

Checking against instance state can be racy for concurrent requests as the server does not
refill tokens if the action fails in a later stage (e.g. database failure). If
plugins want to guarantee an absolute maximum on a resource, they have to do their own
book-keeping.

[source, java]
----
import com.google.server.quota.QuotaEnforcer;

class ProjectLimiter implements QuotaEnforcer {
  private final long maxNumberOfProjects = 100;
  @Override
  QuotaResponse requestTokens(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
    if (!"/projects/create".equals(quotaGroup)) {
      return QuotaResponse.noOp();
    }
    // No deduction because we always check against the instance state (racy but fine for
    // this plugin)
    if (currentNumberOfProjects() + numTokens > maxNumberOfProjects) {
      return QuotaResponse.error("too many projects");
    }
    return QuotaResponse.ok();
  }

  @Override
  QuotaResponse dryRun(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
    // Since we are not keeping any state in this enforcer, we can simply call requestTokens().
    return requestTokens(quotaGroup, ctx, numTokens);
  }

  void refill(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
    // No-op
  }
}
----

[source, java]
----
import com.google.server.quota.QuotaEnforcer;

class ApiQpsEnforcer implements QuotaEnforcer {
  // AutoRefillingPerUserBuckets is a imaginary bucket implementation that could be based on
  // a loading cache or a commonly used bucketing algorithm.
  private final AutoRefillingPerUserBuckets<CurrentUser, Long> buckets;
  @Override
  QuotaResponse requestTokens(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
    if (!quotaGroup.startsWith("/restapi/")) {
      return QuotaResponse.noOp();
    }
    boolean success = buckets.deduct(ctx.user(), numTokens);
    if (!success) {
      return QuotaResponse.error("user sent too many qps, please wait for 5 minutes");
    }
    return QuotaResponse.ok();
  }

  @Override
  QuotaResponse dryRun(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
    if (!quotaGroup.startsWith("/restapi/")) {
      return QuotaResponse.noOp();
    }
    boolean success = buckets.checkOnly(ctx.user(), numTokens);
    if (!success) {
      return QuotaResponse.error("user sent too many qps, please wait for 5 minutes");
    }
    return QuotaResponse.ok();
  }

  @Override
  void refill(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
    if (!quotaGroup.startsWith("/restapi/")) {
      return;
    }
    buckets.add(ctx.user(), numTokens);
  }
}
----

[[performance-logger]]
== Performance Logger

`com.google.gerrit.server.logging.PerformanceLogger` is an extension point that
is invoked for all operations for which the execution time is measured. The
invocation of the extension point does not happen immediately, but only at the
end of a request (REST call, SSH call, git push). Implementors can write the
execution times into a performance log for further analysis.

[[request-listener]]
== Request Listener

`com.google.gerrit.server.RequestListener` is an extension point that is
invoked each time the server executes a request from a user.

== SEE ALSO

* link:js-api.html[JavaScript API]
* link:dev-rest-api.html[REST API Developers' Notes]

GERRIT
------
Part of link:index.html[Gerrit Code Review]

SEARCHBOX
---------
