: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) and `Gerrit-ApiModule` supplies bindings that
exposed to all the other plugins loaded in Gerrit, which can be
used for implementing cross-plugin communication.
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
Gerrit-ApiModule:  tls.example.project.ApiModuleClassName
----

=== 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 declare an API to be used by other plugins using the `Gerrit-ApiModule`
declaration in the `MANIFEST.MF`:

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

Note that it is also possible to replace DynamicItem bound by one plugin by
another binding in another plugin. This can be used when exposing a DynamicItem
via an API module: we can bind a default impelmentation in the plugin declaring
the DynamicItem and then replace the implementation by another plugin.

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.

* `com.google.gerrit.server.update.RetryListener`:
+
Invoked when Gerrit retries a block of code because there was a failure.

[[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();
  }
}
----

[[copy_condition_operands]]
== Label Copy-Condition Operands

Plugins can define operands to extend what votes are copied as part of label's
link:config-labels.html#label_copyCondition[copyCondition].
Plugin defines a Predicate<ApprovalContext> implementation and a factory that is
bound to the `DynamicSet` from a module's `configure()` method in the plugin.

Following operators supported:
* "uploaderin:" and "approverin" by implementing UserInOperandFactory.

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

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

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

  @Override
  public Predicate<ApprovalContext> create()
      throws QueryParseException {
    return new UserInSamplePredicate();
  }
}
----

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

[[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");
  }
}
----

`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"));
}
----

[[cache-def]]
== Cache Definitions

Plugins can request a view of the definitions of all registered caches by
injecting a `DynamicMap<CacheDef<?,?>>`. This will allow plugins to inspect what
caches are currently registered and what their schema looks like.

[source,java]
----
@Inject
public MyClass(DynamicMap<CacheDef<?, ?>> cacheMap) {
  // your code
}
----

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


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.

[[submit-requirement]]
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.

`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);
  }
}
----

[[label-type]]
== Label Type

The `com.google.gerrit.entities.LabelType` extension point allows to define a
global label programmatically that applies to all projects, unless overriding
the label is allowed and projects override the label by defining a label with
the same name.

[source, java]
----
import com.google.common.collect.ImmutableList;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.LabelValue;
import com.google.inject.AbstractModule;

public class MyPluginModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(LabelType.class).toInstance(
        LabelType.builder(
                "Global-Label",
                ImmutableList.of(
                    LabelValue.create((short) 1, "Approved"),
                    LabelValue.create((short) 0, "No vote"),
                    LabelValue.create((short) -1, "Rejected")))
            .setDescription("A global label")
            .setFunction(LabelFunction.NO_OP)
            .setCanOverride(false)
            .build());
  }
}
----

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

[[validation-options-listener]]
== ValidationOptionsListener

`com.google.gerrit.server.ValidationOptionsListener` is an extension point that
is invoked when a patch set is created. The extension point gets the validation
options that were specified by the user. For example, this extension point can
be used to log validation options for auditing purposes.

[[commit-validation-info-listener]]
== CommitValidationInfoListener

`com.google.gerrit.server.git.validators.ValidationOptionsListener` is an
extension point that is invoked after a commit has passed the validations that
are done by `CommitValidationListener`'s.

If any `CommitValidationListener` rejects the commit (by throwing a
`CommitValidationException`) this extension point is not invoked.

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

[[flow-service]]
== Flow Service

`com.google.gerrit.server.flow.FlowService` is an extension point to plug in a
service to manage flows.

A flow is an automation rule on a change that triggers actions on the change
when the flow conditions become satisfied. For example, a flow can be an
automation rule that adds a reviewer to the change when the change has been
verified by the CI.

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