: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.server.events.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.server.events.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:

    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 or
ChangeQueryBuilder.ChangeIsOperandFactory).  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:

====
  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

Output:

{
   "url" : "http://localhost:8080/1",
   "plugins" : [
      {
         "name" : "myplugin-name",
         "exampleName" : "Attribute Example",
         "changeValue" : "1"
      }
   ],
    ...
}

curl http://localhost:8080/changes/1?myplugin-name--all

Output:

{
  "_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.

----
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
---------
