: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. See the overall
link:dev-plugins-lifecycle.html[Plugin Lifecycle] document for how plugins can
be hosted on gerrit-review.googlesource.com.

For JavaScript plugin development, consult with
link:pg-plugin-dev.html[JavaScript 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`.

=== Cross-Plugin communication

A plugin can optionally declare an API to be used by other plugins.

---
Gerrit-ApiModule: tld.example.project.APIClassName
---

Notably, when injecting 'DynamicItem,' 'DynamicSet,' or 'DynamicMap' defined by
the API, a plugin can register new concrete implementations or replace existing
ones.
However, these are not the only classes available for consumption; API plugins
can also define and provide interfaces and concrete classes for other plugins.

This enables plugins to influence other plugins by customizing or extending the
their behaviour.

When a plugin wants to expose an API that *must* not be further overridden by
other plugins, it could use the additional annotation `@DynamicItem.Final` which
also gives the option to further limit the name of the plugin that is designated
to bind the only implementation available.

For example, a `plugin B` may declare an API as `@DynamicItem.Final` which is then
bound in its `ApiModule`.

```
 @DynamicItem.Final(implementedByPlugin = "plugin-b-impl")
 public interface PluginAPI {}

 public class PluginApiModule extends AbstractModule {
   @Override
   protected void configure() {
      DynamicItem.itemOf(binder(), PluginAPI.class);
   }
 }
```

The above definition of the `PluginApi` would be allowed to bound only by
the `plugin-b-impl` which would associate its implementation class.

```
public class PluginImpl implements PluginAPI {}

 public class PluginImplModule extends AbstractModule {
   @Override
   protected void configure() {
      DynamicItem.bind(binder(), PluginAPI.class).to(PluginImpl.class);
   }
 }
```

*Gotchas and Limitations*:

- A `plugin A` depending on a `plugin B` (declaring a `Gerrit-ApiModule`),
  should include `plugin B` as a `neverlink` library in its BUILD file, as
  follows:

  ```
  java_library(
      name = "gerrit-pluginB-neverlink",
      neverlink = True,
      exports = ["//plugins/pluginB"],
  )
  ```

  The reason is that the `plugin B` dependency should not be included as a
  shaded jar of the plugin: Gerrit will load the dependency dynamically at
  runtime instead of packaging it in the consumer plugin fat jar.

- Removing/renaming the plugin jar that defines the classes declared in the
  `Gerrit-ApiModule` is currently not supported.
  The behaviour in this case is unpredictable and depends on the specifics of
  the classes involved.

- An API plugin cannot depend on another API plugin.

*Gerrit CI and Validation*:

To build this as part of the gerrit-ci the plugin Api (in our example,
`plugin B`) needs to be added as a dependency via the `extra-plugins` property.
For example:

```
 project:
    name: plugin-A
    jobs:
      - 'plugin-{name}-bazel-{branch}':
          extra-plugins: 'plugin-B'
          branch:
            - master
```

Additionally, for `plugin A` to be verified by the gerrit-ci, the `Jenkinsfile`
also needs to be inclusive of the API dependency, as such:

```
pluginPipeline(
  formatCheckId: 'gerritforge:plugin-A-format-3852e64366bb37d13b8baf8af9b15cfd38eb9227',
  buildCheckId: 'gerritforge:plugin-A-3852e64366bb37d13b8baf8af9b15cfd38eb9227',
  extraPlugins: ['plugin-B'])
```

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

[[plugin_resources]]
=== Plugin resources

Plugins are able to access their own resources without having to go through
the implementation details on how they are packaged or deployed to Gerrit.

The following example shows a MyClass in a plugin that is able to access the
last modified time of the "myresource" loaded.

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

  @Inject
  public MyClass(Plugin plugin) {
    long myresourceTime = plugin.getContentScanner().getEntry("myresource").getTime();
  }

  [...]
}
----

[[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.GitReferenceUpdatedListener`:
+
A git reference was updated. A separate event for every ref updated in
a BatchRefUpdate will be fired.

* `com.google.gerrit.extensions.events.GitBatchRefUpdateListener`:
+
One or more git references were updated. Alternative to GitReferenceUpdatedListener.
A single event will inform about all refs updated by a BatchRefUpdate. Will also be
fired, if only a single ref was updated.

* `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.CustomKeyedValueValidationListener`:
+
Updates to custom keyed values

* `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].

[[taskListeners]]
== WorkQueue.TaskListeners

It is possible for plugins to listen to
`com.google.gerrit.server.git.WorkQueue$Task`s directly before they run, and
directly after they complete. This may be used to delay task executions based
on custom criteria by blocking, likely on a lock or semaphore, inside
onStart(), and a lock/semaphore release in onStop(). Plugins may listen to
tasks by implementing a `com.google.gerrit.server.git.WorkQueue$TaskListener`
and registering the new listener like this:

[source,java]
----
bind(TaskListener.class)
    .annotatedWith(Exports.named("MyListener"))
    .to(MyListener.class);
----

Blocking inside onStop() is a good choice for QOS limits which are
attempting to restrict total usage of resources as might be done to
to prevent a server overload. In these cases, when a server's resources
are being exhausted, it is important to throttle all `Tasks`, and blocking
the current thread from being used by any Task makes sense. However,
Task parking (see below) is more appropriate if it desirable to limit a
specific resource usage in favor of other resources, such as when
prioritization or fairness policies are desired.

[[taskParker]]
== TaskParkers

It is possible to park `com.google.gerrit.server.git.WorkQueue$Task`s
before they run without depriving other `Tasks` of a thread. Parking is
particularly useful for (de-)prioritizing certain `Tasks` based on resource
quotas without blocking `Tasks` not using those resources. For example,
when there is a desire to limit how many commands a single user can run
concurrently it is typically also desirable to not limit the total amount
of concurrently running commands to the same limit. The Task parking
mechanism is useful for such Task limiting scenarios.

The `TaskParker` interface works well with a Semaphore's `tryAcquire()`
method even when the Semaphore is unavailable. However, blocking should
not be done with a `TaskParker` and if it is desired, such as when using a
Semaphore's `acquire()` method, use a `TaskListener` interface instead.

To make use of Task parking, implement a
`com.google.gerrit.server.git.WorkQueue$TaskParker` and register the
TaskParker (as a TaskListener) from a plugin like this:

[source,java]
----
  public class MyParker implements TaskParker {
    Semaphore semaphore = new Semaphore(3);

    @Override
    public boolean isReadyToStart(Task<?> task) {
      try {
        return semaphore.tryAcquire();
      } catch (InterruptedException e) {
        return false;
      }
    }

    @Override
    public void onNotReadyToStart(Task<?> task) {
      semaphore.release();
    }

    @Override
    public void onStart(Task<?> task) {}

    @Override
    public void onStop(Task<?> task) {
      semaphore.release();
    }
  }

  bind(TaskListener.class)
      .annotatedWith(Exports.named("MyParker"))
      .to(MyParker.class);
----

Before running a Task, the executor will query each `TaskParker` to see
if the Task may be run by calling `isReadyToStart()`. If any `TaskParker`
returns `false` from `isReadyToStart()`, then the Task will get parked
and the executor will wait until another Task completes before
attempting to run a parked task again.

Since parked `Tasks` are not actually running and consuming resources,
they generally should also not be contributing towards those resource
quotas which caused the task to be parked. For this reason, once it is
determined that a Task will be parked, the executor will call
`onNotReadyToStart()` on every `TaskParker` that previously returned `true`
from `isReadyToStart()`. This allows those TaskParkers to reduce their
resource usage counts which they bumped up in `isReadyToStart()` with
the expectation that the Task may run. Since the Task is not running and
the resource is not being used, reducing the resource usage count allows
other `Tasks` needing that resource to run while the Task is parked.

Once a running Task completes, the executor will attempt to run
parked `Tasks` (in the order in which they were parked) by again calling
`isReadyToStart()` on the TaskParkers, even the TaskParkers which
previously returned a `true` before the Task was parked. This is
necessary because although a Task may not have exceeded a specific
resource limit before it was parked, another Task may since have been
allowed to run and its usage of that resource may now cause the parked
task under evaluation to need to be throttled and parked again.

Note, the reason that it is important to not block inside the
`isReadyToStart()` method is to avoid delaying the executor from calling
`onNotReadyToStart()` on other TaskParkers holding resources, as this
would prevent them from freeing those resources. Also, just as it is
important to later release any resources acquired within
`isReadyToStart()` in `onStop()`, it is even more important to release
those resources in `onNotReadyToStart()` since `isReadyToStart()` may
be called many times per `TaskParker`, but `onStop()` will only ever be
be called once.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[ssh]]
== SSH Commands

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

Command implementations must extend the base class SshCommand:

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

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

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

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

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

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

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

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

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

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

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

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

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

With the possible implementation:

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

And the call:

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

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

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

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

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

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

[[search_operators]]
== Search Operators

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

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

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

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

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

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

[[search_operands]]
== Search Operands

Plugins can define new search operands to extend change searching.
Plugin methods implementing search operands (returning a
`Predicate<ChangeData>`), must be defined on a class implementing
one of the `ChangeQueryBuilder.ChangeOperandsFactory` interfaces
(.e.g., ChangeQueryBuilder.ChangeHasOperandFactory 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:

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

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

[[command_options]]
== Command Options

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

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

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

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

To provide additional Guice bindings for options to a command in another classloader, bind a
ModulesClassNamesProvider which provides the name of your Modules needed for your DynamicBean
in the other classLoader.

Do this by binding to the name of the command you are going to bind to and providing an
Iterable of Module names to instantiate and add to the Injector used to instantiate the
DynamicBean in the other classLoader. This interface supports running LifecycleListeners
which are defined by the Modules being provided. The duration of the lifecycle starts when
a ssh or http request starts and ends when the request completes.

[source, java]
----
bind(DynamicOptions.DynamicBean.class)
    .annotatedWith(Exports.named(
        "com.google.gerrit.plugins.otherplugin.command"))
    .to(MyOptionsModulesClassNamesProvider.class);

static class MyOptionsModulesClassNamesProvider implements DynamicOptions.ModulesClassNamesProvider {
  @Override
  public String getClassName() {
    return "com.googlesource.gerrit.plugins.myplugin.CommandOptions";
  }
  @Override
  public Iterable<String> getModulesClassNames()() {
    return "com.googlesource.gerrit.plugins.myplugin.MyOptionsModule";
  }
}
----

Plugins can receive a bean object for each of the gerrit ssh and the REST API
commands by implementing BeanParseListener interface and registering it to a
command class name in the plugin module's `configure()` method. The below
example shows a plugin that always limits the number of projects returned
by the ls-projects SSH command.

[source, java]
----
protected static class PluginModule extends AbstractModule {
  @Override
  public void configure() {
    bind(DynamicOptions.DynamicBean.class)
        .annotatedWith(Exports.named(ListProjectsCommand.class))
        .to(ListProjectsCommandBeanListener.class);
  }

  protected static class ListProjectsCommandBeanListener
      implements DynamicOptions.BeanParseListener {
    @Override
    public void onBeanParseStart(String plugin, Object bean) {
      ListProjectsCommand command = (ListProjectsCommand) bean;
      command.impl.setLimit(1);
    }

    @Override
    public void onBeanParseEnd(String plugin, Object bean) {}
  }
}
----

The below example shows a plugin that always limits the number of projects
returned by the /projects/ REST API.

[source, java]
----
protected static class PluginModule extends AbstractModule {
  @Override
  public void configure() {
    bind(DynamicOptions.DynamicBean.class)
        .annotatedWith(Exports.named(ListProjects.class))
        .to(ListProjectsBeanListener.class);
  }

  protected static class ListProjectsBeanListener
      implements DynamicOptions.BeanParseListener {
    @Override
    public void onBeanParseStart(String plugin, Object bean) {
      ListProjects listProjects = (ListProjects) bean;
      listProjects.setLimit(1);
    }

    @Override
    public void onBeanParseEnd(String plugin, Object bean) {}
  }
}
----

=== 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 against 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 = "output results using json",
  handler = JsonOutputOptionHandler.class
)
boolean json;
----

[[query_attributes]]
== Change Attributes

=== ChangePluginDefinedInfoFactory

Plugins can provide additional attributes to be returned from the Get Change and
Query Change APIs by implementing the `ChangePluginDefinedInfoFactory` 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 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(), ChangePluginDefinedInfoFactory.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 ChangePluginDefinedInfoFactory {
  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 Map<Change.Id, PluginDefinedInfo> createPluginDefinedInfos(
      Collection<ChangeData> cds, BeanProvider bp, String plugin) {
    if (options == null) {
      options = (MyChangeOptions) bp.getDynamicBean(plugin);
    }
    Map<Change.Id, PluginDefinedInfo> out = new HashMap<>();
    if (options.all) {
      cds.forEach(cd -> out.put(cd.getId(), new PluginAttribute(cd)));
      return out;
    }
    return ImmutableMap.of();
  }
}
----

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

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

Runtime exceptions generated by the implementors of ChangePluginDefinedInfoFactory
are encapsulated in PluginDefinedInfo objects which are part of SSH/REST query output.

Implementors of the `ChangePluginDefinedInfoFactory` 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)
  [...]
----

[post_review_extensions]
== Post Review Extensions

By implementing the `com.google.gerrit.server.restapi.change.OnPostReview`
interface plugins can extend the change message that is being posted when the
link:rest-api-changes.html#set-review[post review] REST endpoint is invoked.

This is useful if certain approvals have a special meaning (e.g. custom logic
that is implemented in Prolog submit rules, signal for triggering an action
like running CI etc.), as it allows the plugin to tell users about this meaning
in the change message. This makes the effect of a given approval more
transparent to the user.

[[ui_extension]]
== UI Extension

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

Plugins can filter the branches and tags that are included by implementing
`com.google.gerrit.server.change.FilterIncludedIn`.

[source, java]
----
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.change.FilterIncludedIn;
import java.util.function.Predicate;
import org.eclipse.jgit.revwalk.RevCommit;

public class MyFilter implements FilterIncludedIn {
  @Override
  public Predicate<String> getBranchFilter(Project.NameKey project, RevCommit commit) {
    if (project.get() != "myproject") {
      return branch -> true;
    }
    return branch -> !branch.startsWith("feature/");
  }

  @Override
  public Predicate<String> getTagFilter(Project.NameKey project, RevCommit commit) {
    if (project.get() != "myproject") {
      return tag -> true;
    }
    return tag -> tag.startsWith("v");
  }
}
----

And register your class:

[source, java]
----
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.server.change.FilterIncludedIn;
import com.google.inject.AbstractModule;

public class MyPluginModule extends AbstractModule {
  @Override
  protected void configure() {
    DynamicSet.bind(binder(), FilterIncludedIn.class).to(MyFilter.class);
  }
}
----

[[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-SHA-1 in the UI.

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

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

  @Override
  public WebLinkInfo getPatchSetWebLink(String projectName, String commit,
   String commitMessage, String branchName, String changeKey, int
   numericChangeId) {
    return new WebLinkInfo(name,
        imageUrl,
        String.format(placeHolderUrlProjectCommit, project, commit, changeKey,
	numericChangeId));
  }
}
----

ParentWebLinks will appear to the right of the SHA-1 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.

EditWebLinks will appear in the top-right part of the file diff page.

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]
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}`.

Note that metric name can be expressed through a limited set of characters
`[a-zA-Z0-9_-]+(/[a-zA-Z0-9_-]+)*` therefore one should either ensure it
or call
link:https://gerrit.googlesource.com/gerrit/+/master/java/com/google/gerrit/metrics/dropwizard/DropWizardMetricMaker.java[
sanitizeMetricName,role=external,window=_blank] to have it enforced.

The
link:https://gerrit.googlesource.com/gerrit/+/master/java/com/google/gerrit/metrics/dropwizard/DropWizardMetricMaker.java[
sanitizeMetricName,role=external,window=_blank] performs the following
modifications:

* leading `/` is replaced with `_`
* doubled (or repeated more times) `/` are reduced to a single `/`
* ending `/` is removed
* all characters that are not `/a-zA-Z0-9_-` are replaced with
  `\_0x[HEX CODE]_` (code is capitalized)
* if the replacement prefix (`_0x`) is found then it is prepended with another
  replacement prefix

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

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

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

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

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

...

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


[[documentation]]
== Documentation

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

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

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

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

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

The following macros are supported:

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

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

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

Documentation should typically contain the following content:

[width="100%",options="header"]
|===================================================
|File                                           | Content
|`README.md`                                    | Home page of the plugin when browsing its source code on Git
|`LICENSE`                                      | Open-source license
|`resources/Documentation/about.md`             | Overview of the plugin and its purpose
|`resources/Documentation/config.md`            | Plugin configuration settings and sample configs
|`resources/Documentation/build.md`             | How to build the plugin
|`resources/Documentation/cmd-<command>.md`     | SSH commands
|`resources/Documentation/rest-api-<api>.md`    | REST API
|`resources/Documentation/servlet-<servlet>.md` | HTTP Servlets
|===================================================

The documentation under resources/Documentation may contain macro that
will be included and expanded by Gerrit once the plugin is loaded.

The files in the root directory are not included in the plugin package
and must not have any macro for expansion. It may also collect
additional information that would make the plugin more discoverable, such as
a more user-friendly description of its use-cases.

The documentation can also include images that can help understanding more
visually how the plugin can interact with the other Gerrit components.

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

The generated index page contains 3 sections:

1. Manifest 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
|===================================================

2. About section
+
If an `about.md` or `about.html` file exists, its content will be inserted in an
'About' section.
+
If both `about.md` and `about.html` exist, only the first discovered file will
be used.

3. TOC section
+
If a `toc.md` or `toc.html` file exists, its content will be inserted in a
'Documentation' section.
+
`toc.md` or `toc.html` is a manually maintained index of the documentation pages
that exist in the plugin. Having a manually maintained index has the advantage
that you can group the documentation pages by topic and sort them by importance.
+
If both `toc.md` and `toc.html` exist, only the first discovered file will
be used.
+
If no `toc` file is present the TOC section is automatically generated 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 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.

[[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 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)`. For Web UI plugins, the name
of the file, minus the `.js` 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 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;
  }
}
----


[[account-tag]]
== Account Tag Plugins

Gerrit provides an extension point that enables Plugins to supply additional
tags on an account.

[source, java]
----
import com.google.gerrit.entities.Account;
import com.google.gerrit.server.account.AccountTagProvider;
import java.util.List;

public class MyPlugin implements AccountTagProvider {
  public List<String> getTags(Account.Id id) {
    // Implement your logic here
  }
}
----

[[account-state-provider]]
== Account State Provider

Gerrit provides an extension point that enables plugins to supply additional
data for account states which are returned from the
link:rest-api-accounts.html#get-state[Get Account State] REST endpoint (see
`metadata` field in
link:rest-api-accounts.html#account-state-info[AccountStateInfo]).

[source, java]
----
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.entities.Account;
import com.google.gerrit.extensions.common.MetadataInfo;
import com.google.gerrit.server.account.AccountStateProvider;

public class MyPlugin implements AccountStateProvider {
  public ImmutableList<MetadataInfo> getMetadata(Account.Id accountId) {
    // Implement your logic here
  }
}
----

[[server-state-provider]]
== Server State Provider

Gerrit provides an extension point that enables plugins to supply additional
data for server states which are returned from the
link:rest-api-config.html#get-info[Get Server State] REST endpoint (see
`metadata` field in link:rest-api-config.html#server-info[ServerInfo]).

[source, java]
----
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.common.MetadataInfo;
import com.google.gerrit.server.ServerStateProvider;

public class MyPlugin implements ServerStateProvider {
  public ImmutableList<MetadataInfo> getMetadata() {
    // Implement your logic here
  }
}
----

[[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: miscommunication 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, its 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.entities.SubmitRecord;
import com.google.gerrit.entities.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.

`SubmitRule` interface will soon deprecated. Instead, a global `SubmitRequirement`
can be bound by plugin.

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

public class MyPluginModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(SubmitRequirement.class).annotatedWith(Exports.named("myPlugin"))
        .toInstance(myPluginSubmitRequirement);
  }
}
----

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

[[custom-keyed-values]]
== Custom Keyed values

It is possible to associate custom keyed values with a change. This is a map
from string to string, allowing for the storage of small keys and values. An
example would be for storing an associated workspace with the given change.

As an example:
```
  private void setWorkspace(ChangeResource rsrc, String workspaceId)
      throws RestApiException, UpdateException {
    try (RefUpdateContext pluginCtx = RefUpdateContext.open(PLUGIN);
        RefUpdateContext ctx = RefUpdateContext.open(CHANGE_MODIFICATION);
        BatchUpdate bu =
            updateFactory.create(rsrc.getChange().getProject(), rsrc.getUser(), TimeUtil.now())) {
      SetCustomKeyedValuesOp op =
          customKeyedValuesFactory.create(
              new CustomKeyedValuesInput(ImmutableMap.of("workspace", workspaceId)));
      bu.addOp(rsrc.getId(), op);
      bu.execute();
    }
  }
```

These custom-keyed-values can be fetched by passing the option `o=CUSTOM_KEYED_VALUES`
to a change details fetch.

[[diff-validators]]
== Diff Validators

`com.google.gerrit.server.patch.DiffValidator` is an extension point that is
invoked after the file diff is computed through the
link:rest-api-changes.html#get-diff[Get Diff] REST endpoint.

Implementors can write logic to validate the diff before it's returned on the
API.

== SEE ALSO

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

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

SEARCHBOX
---------
