Metadata and configuration
The shared mechanics — discovery, annotation attributes, classloading, how a plugin gets into the distribution — are on the plugin types overview.
Metadata
A metadata plugin adds a new kind of object to the Metadata perspective: relational database connections, run configurations, VFS connections, servers, partition schemas and around forty others are all metadata objects. This is usually the plugin type you want when a plugin needs configuration that is shared between pipelines rather than living inside one.
- Annotation
-
@HopMetadata - Implement
-
IHopMetadata, in practice by extendingHopMetadataBase - Plugin type
-
MetadataPluginType, idMETADATA - Details
Any plain Java object will do.
Annotate the class with @HopMetadata, the fields with @HopMetadataProperty, and serialisation to JSON is handled for you.
key-
The serialisation key, which also becomes the folder name under
metadata/in a project. Permanent, like any plugin id. name,description,image,category-
How the type appears in the Metadata perspective.
hopMetadataPropertyType-
Ties the type into metadata injection and the "used by" bookkeeping.
supportsGlobalReplace-
Whether a global find-and-replace may rewrite references to objects of this type.
An editor class extending MetadataEditor gives it a GUI.
|
Metadata classes and the code using them must share a |
AI provider
An AI provider plugin is one backend behind the named AI Provider metadata object: OpenAI-compatible, Anthropic, Ollama, and so on. The metadata object holds credentials; the plugin supplies defaults (base URL, model name, auth kind) and maps onto Language Model Chat.
- Annotation
-
@AiProviderPlugin - Implement
-
IAiProvider, in practice by extendingBaseAiProvider - Plugin type
-
AiProviderPluginType, idAI_PROVIDERS - Examples
-
plugins/tech/ai
Keep langchain4j off this interface — it lives in hop-core.
Implementations belong in a plugin JAR and should set classLoaderGroup = "hop-ai" so they share a classloader with Language Model Chat.
Language Model Chat stores only the provider name (aiProviderName) and overlays connection fields at runtime through AiChatFactory.overlayNamedProvider.
The transform dialog uses @GuiWidgetElement(metadataKey = "ai-provider") so it does not compile against hop-tech-ai.
AI advisor
An AI advisor plugin is one kind of help the AI Assistant workbench can run: pipeline design, workflow error diagnosis, or a third-party modeler (Data Vault, Business Vault, dimensional, lineage, …).
- Annotation
-
@AiAdvisorPlugin - Implement
-
IAiAdvisor - Plugin type
-
AiAdvisorPluginType, idAI_ADVISORS - Examples
-
plugins/tech/ai(PipelineAiAdvisor,WorkflowAiAdvisor)
Locations are free-form strings, not a closed enum.
GUI entry points are separate toolbar / context-action plugins that call HopGui.openAiAdvisorSession.
The full pattern — location ids, the open-session request, inclusions, proposals, classloading and a worked Data Vault-style example — is on AI advisor plugins.
Configuration options
A configuration plugin adds options to an existing Hop command line tool, and — with one extra annotation — a tab in the GUI options dialog.
The projects plugin uses this to add project options to hop run, and the search settings use it to add a Search tab to the options.
- Annotation
-
@ConfigPlugin - Implement
-
IConfigOptions - Plugin type
-
ConfigPluginType, idCONFIG - Examples
-
plugins/misc/projects,ui/src/main/java/org/apache/hop/ui/hopgui/search/config/SearchConfigPlugin.java
The category decides which tool picks the options up.
Each tool mixes in only the plugins of its own category:
| Category | Tool |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
the documentation builder |
|
the Python command |
|
|
The options themselves are picocli @CommandLine.Option fields on the class; the plugin is added to the command as a mixin.
handleOption(…) is then called and returns true when it handled something and the tool should not continue with its default behaviour.
Add @GuiPlugin and @GuiWidgetElement annotations to the same fields and the same options become a tab in the Hop GUI options dialog.
That path requires a static getInstance() method on the class, because the dialog needs the singleton holding the current values.
Hop command
Where a configuration plugin extends an existing command, a @HopCommand plugin adds a whole new hop sub-command — this is how hop run, hop conf, hop server, hop encrypt, hop search, hop doc, hop marketplace and hop export are all built.
- Annotation
-
@HopCommand - Implement
-
IHopCommand, plusRunnableand picocli’s@Command - Plugin type
-
HopCommandPluginType, idHOP_COMMAND - Examples
-
engine/src/main/java/org/apache/hop/encryption/HopCommandEncrypt.java,engine/src/main/java/org/apache/hop/run/HopCommandRun.java
The id is the word the user types.
initialize(CommandLine, IVariables, MultiMetadataProvider) hands you the command line and the environment; run() does the work.
Import
An import plugin converts a project from another tool into a Hop project, and shows up in hop import and in the GUI import wizard.
Hop ships one, for Kettle/PDI.
- Annotation
-
@ImportPlugin - Implement
-
IHopImport, in practice by extendingHopImportBase - Plugin type
-
ImportPluginType, idIMPORT - Example
-
plugins/misc/import
The interface is broad because importing is: it covers the input and output folders, the property and shared-object files of the source tool, the target project and environment to create, and an import report.
Variable resolver
A variable resolver fetches a value from somewhere else when a variable is dereferenced — a secret manager, a key vault, or another pipeline.
It is what makes #{secret/path} work without a password ever being written into a file.
- Annotation
-
@VariableResolverPlugin - Implement
-
IVariableResolver - Plugin type
-
VariableResolverPluginType, idVARIABLERESOLVERPLUGIN - Examples
-
plugins/tech/azure(Key Vault),plugins/tech/google(Secret Manager),plugins/tech/aws,plugins/resolvers/pipeline,plugins/misc/passwords
The interface is two methods that matter: init() and resolve(String secretPath, IVariables variables).
The settings are held in a Variable Resolver metadata object, so the resolver’s fields carry both @HopMetadataProperty (to be saved) and @GuiWidgetElement with parentId = VariableResolver.GUI_PLUGIN_ELEMENT_PARENT_ID (to be edited).
|
Resolution goes through the metadata provider of the running pipeline or workflow, not a process-wide one. A resolver that reaches for a global metadata provider will miss the metadata of an exported run on a Hop Server. |
Two-way password encoder
This decides how passwords are obfuscated or encrypted in metadata files.
Hop ships the default Hop obfuscation, and the passwords plugin adds AES variants.
- Annotation
-
@TwoWayPasswordEncoderPlugin - Implement
-
ITwoWayPasswordEncoder - Plugin type
-
TwoWayPasswordEncoderPluginType, idTWOWAYPASSWORDENCODERPLUGIN - Examples
-
core/src/main/java/org/apache/hop/core/encryption/HopTwoWayPasswordEncoder.java,plugins/misc/passwords
encode(…), decode(…) and getPrefixes(): the prefixes (`Encrypted `, `AES `, …) are how Hop recognises which encoder produced a stored value, so an encoder must claim a prefix nothing else uses.
Only one encoder is active per process.
It is selected by the HOP_PASSWORD_ENCODER_PLUGIN variable or system property and defaults to Hop; HopClientEnvironment.init() reads it and calls Encr.init(…).
|
Obfuscation is not encryption. The default encoder keeps passwords out of plain sight in files; it does not protect them from someone who has the files. See the password documentation for what the guarantees actually are. |
Authentication provider and consumer
Two related plugin types describing credentials rather than connections: a provider is a kind of credential (username/password, Kerberos), a consumer is something that can use one.
- Annotations
-
@AuthenticationProviderPluginand@AuthenticationConsumerPlugin - Implement
-
IAuthenticationProviderTypeandIAuthenticationConsumerType - Plugin types
-
AuthenticationProviderPluginType(idAUTHENTICATION_PROVIDER) andAuthenticationConsumerPluginType(idAUTHENTICATION_CONSUMER) - Examples
-
engine/src/main/java/org/apache/hop/core/auth
Both are small: a display name, and for the consumer the class that performs the authentication. Hop ships two providers and no consumers, so this pair is best treated as a low-traffic extension point — most plugins that need credentials use a metadata object instead.