Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/features/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
- [Percentiles Aggregation](opensearch/percentiles-aggregation.md)
- [Phone Number Analyzer](opensearch/phone-analyzer.md)
- [Platform Support](opensearch/platform-support.md)
- [Plugin Dependencies](opensearch/plugin-dependencies.md)
- [Plugin Installation](opensearch/plugin-installation.md)
- [Plugin Testing Framework](opensearch/plugin-testing-framework.md)
- [Profiler](opensearch/profiler.md)
Expand Down
158 changes: 158 additions & 0 deletions docs/features/opensearch/plugin-dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Plugin Dependencies

## Summary

OpenSearch plugins declare their compatibility with OpenSearch versions through the `plugin-descriptor.properties` file. The plugin dependencies feature allows plugins to specify version compatibility using semantic versioning (semver) notation, including range expressions. This enables plugins to declare compatibility with multiple OpenSearch versions without requiring separate builds for each version.

## Details

### Architecture

```mermaid
graph TB
subgraph "Plugin Descriptor"
PDF[plugin-descriptor.properties]
OV[opensearch.version]
DEP[dependencies]
end

subgraph "Version Parsing"
PI[PluginInfo]
SR[SemverRange]
RP[RANGE_PATTERN]
end

subgraph "Range Operators"
EQ[Equal =]
TL[Tilde ~]
CR[Caret ^]
RG[Range [...]]
end

PDF --> OV
PDF --> DEP
OV --> PI
DEP --> PI
PI --> SR
SR --> RP
RP --> RG
SR --> EQ
SR --> TL
SR --> CR
```

### Data Flow

```mermaid
flowchart LR
A[Plugin ZIP] --> B[Extract]
B --> C[Read plugin-descriptor.properties]
C --> D{Has dependencies?}
D -->|Yes| E[Parse JSON]
D -->|No| F[Use opensearch.version]
E --> G[Extract opensearch version]
F --> G
G --> H{Is range pattern?}
H -->|Yes| I[Parse as range]
H -->|No| J[Parse as single version]
I --> K[SemverRange]
J --> K
K --> L[Validate against running version]
L -->|Compatible| M[Install plugin]
L -->|Incompatible| N[Reject installation]
```

### Components

| Component | Description |
|-----------|-------------|
| `SemverRange` | Represents a semantic version range with operator and bounds |
| `SemverRange.RangeOperator` | Enum defining supported operators (EQ, TILDE, CARET, RANGE) |
| `SemverRange.RANGE_PATTERN` | Regex pattern for parsing range expressions |
| `PluginInfo` | In-memory representation of plugin descriptor |
| `Range` | Expression class for evaluating explicit range bounds |

### Configuration

Plugins specify version compatibility in `plugin-descriptor.properties`:

| Property | Description | Example |
|----------|-------------|---------|
| `opensearch.version` | Single version or semver expression | `2.3.0`, `~2.3.0`, `^2.3.0` |
| `dependencies` | JSON object with opensearch version | `{ opensearch: "[2.0.0, 3.0.0)" }` |

Note: Only one of `opensearch.version` or `dependencies` can be specified.

### Supported Version Notations

| Notation | Syntax | Compatible Versions |
|----------|--------|---------------------|
| Exact | `2.3.0` or `=2.3.0` | Only 2.3.0 |
| Tilde | `~2.3.0` | 2.3.0 ≤ v < 2.4.0 |
| Caret | `^2.3.0` | 2.3.0 ≤ v < 3.0.0 |
| Inclusive Range | `[2.0.0, 3.0.0]` | 2.0.0 ≤ v ≤ 3.0.0 |
| Exclusive Range | `(2.0.0, 3.0.0)` | 2.0.0 < v < 3.0.0 |
| Mixed Range | `[2.0.0, 3.0.0)` | 2.0.0 ≤ v < 3.0.0 |

### Usage Example

#### Using opensearch.version (traditional)

```properties
name=my-plugin
description=My custom plugin
version=1.0.0
opensearch.version=2.3.0
java.version=21
classname=org.example.MyPlugin
```

#### Using dependencies with range (recommended for multi-version support)

```properties
name=my-plugin
description=My custom plugin
version=1.0.0
dependencies={ opensearch: "[2.0.0, 3.0.0)" }
java.version=21
classname=org.example.MyPlugin
```

#### Using tilde notation

```properties
name=my-plugin
description=My custom plugin
version=1.0.0
opensearch.version=~2.3.0
java.version=21
classname=org.example.MyPlugin
```

## Limitations

- Only one dependency (`opensearch`) is allowed in the `dependencies` field
- Only one range can be specified per plugin
- Cannot use both `opensearch.version` and `dependencies` properties simultaneously
- Range expressions must follow the exact pattern: `[( ]version, version[) ]`

## Related PRs

| Version | PR | Description |
|---------|-----|-------------|
| v3.4.0 | [#19939](https://github.com/opensearch-project/OpenSearch/pull/19939) | Add RangeSemver for `dependencies` in `plugin-descriptor.properties` |
| v2.16.0 | [#18557](https://github.com/opensearch-project/OpenSearch/pull/18557) | Added support for range version support in semver |
| v2.13.0 | - | Initial SemverRange implementation with tilde and caret operators |

## References

- [Issue #1707](https://github.com/opensearch-project/OpenSearch/issues/1707): Cannot install old patch version of plugins on newer OpenSearch builds
- [Issue #18554](https://github.com/opensearch-project/OpenSearch/issues/18554): Add range support in SemVer
- [Documentation: Installing plugins](https://docs.opensearch.org/3.0/install-and-configure/plugins/): Official plugin installation guide
- [OpenSearch Versioning Blog](https://opensearch.org/blog/what-is-semver/): OpenSearch Versioning, or What is SemVer anyway?

## Change History

- **v3.4.0** (2025-11): Extended range semver support to `dependencies` field in plugin-descriptor.properties
- **v2.16.0** (2025-07): Added explicit range notation support (`[2.0.0, 3.0.0)`) for `opensearch.version`
- **v2.13.0** (2024-02): Initial SemverRange implementation with tilde (`~`) and caret (`^`) operators
124 changes: 124 additions & 0 deletions docs/releases/v3.4.0/features/opensearch/plugin-dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Plugin Dependencies

## Summary

This release extends range semver support to the `dependencies` field in `plugin-descriptor.properties`. Previously, range version notation (e.g., `[2.0.0, 3.0.0)`) only worked for the `opensearch.version` field. Now plugins can specify compatible OpenSearch version ranges in their dependencies, enabling more flexible plugin compatibility declarations.

## Details

### What's New in v3.4.0

PR #19939 adds support for range semver notation in the `dependencies` field of plugin descriptor properties. This builds on the range semver support added in PR #18557 for `opensearch.version`.

### Technical Changes

#### Architecture Changes

```mermaid
graph TB
subgraph "Plugin Installation"
PD[plugin-descriptor.properties]
PI[PluginInfo.readFromProperties]
SR[SemverRange]
end

PD -->|dependencies field| PI
PI -->|parse version| SR
SR -->|RANGE_PATTERN| RangeExpr[Range Expression]

subgraph "Version Formats"
Single["Single: 2.3.0"]
Equal["Equal: =2.3.0"]
Tilde["Tilde: ~2.3.0"]
Caret["Caret: ^2.3.0"]
Range["Range: [2.0.0, 3.0.0)"]
end
```

#### Code Changes

The `SemverRange.RANGE_PATTERN` was made public to allow `PluginInfo` to detect range expressions:

```java
public static final Pattern RANGE_PATTERN = Pattern.compile("([\\[\\(])([\\d.]+)\\s*,\\s*([\\d.]+)([\\]\\)])");
```

The `PluginInfo.readFromProperties()` method now checks if the dependency version matches the range pattern before parsing:

```java
String opensearchDependencyVersion = dependenciesMap.get("opensearch");
String[] ranges = opensearchDependencyVersion.split(",");
String opensearchVersion = ranges[0];
if (RANGE_PATTERN.matcher(opensearchDependencyVersion).matches()) {
opensearchVersion = opensearchDependencyVersion;
} else if (ranges.length != 1) {
throw new IllegalArgumentException(
"Exactly one range is allowed to be specified in dependencies for the plugin [" + name + "]"
);
}
opensearchVersionRanges.add(SemverRange.fromString(opensearchVersion.trim()));
```

### Usage Example

Plugins can now specify version ranges in `plugin-descriptor.properties`:

```properties
name=my-plugin
description=My custom plugin
version=1.0.0
dependencies={ opensearch: "[2.0.0, 3.0.0)" }
java.version=21
classname=org.example.MyPlugin
```

This declares the plugin compatible with OpenSearch versions from 2.0.0 (inclusive) to 3.0.0 (exclusive).

#### Supported Range Notations

| Notation | Example | Description |
|----------|---------|-------------|
| Exact | `2.3.0` or `=2.3.0` | Compatible only with version 2.3.0 |
| Tilde | `~2.3.0` | Compatible with 2.3.x (patch variability) |
| Caret | `^2.3.0` | Compatible with 2.x.x (minor variability) |
| Range | `[2.0.0, 3.0.0)` | Explicit range with inclusive/exclusive bounds |

#### Range Bracket Notation

| Bracket | Meaning |
|---------|---------|
| `[` | Include lower bound |
| `(` | Exclude lower bound |
| `]` | Include upper bound |
| `)` | Exclude upper bound |

### Migration Notes

If you have plugins using the `dependencies` field with a single version, no changes are required. To adopt range notation:

1. Update `plugin-descriptor.properties` to use range syntax
2. Test plugin installation on target OpenSearch versions
3. Rebuild and redistribute the plugin

## Limitations

- Only one range can be specified in the `dependencies` field
- Only `opensearch` is allowed as a dependency key
- Cannot use both `opensearch.version` and `dependencies` properties simultaneously

## Related PRs

| PR | Description |
|----|-------------|
| [#19939](https://github.com/opensearch-project/OpenSearch/pull/19939) | Add RangeSemver for `dependencies` in `plugin-descriptor.properties` |
| [#18557](https://github.com/opensearch-project/OpenSearch/pull/18557) | Added support for range version support in semver (prerequisite) |

## References

- [Issue #1707](https://github.com/opensearch-project/OpenSearch/issues/1707): Cannot install old patch version of plugins on newer OpenSearch builds
- [Issue #18554](https://github.com/opensearch-project/OpenSearch/issues/18554): Add range support in SemVer
- [Documentation: Installing plugins](https://docs.opensearch.org/3.0/install-and-configure/plugins/): Plugin compatibility section

## Related Feature Report

- [Full feature documentation](../../../../features/opensearch/plugin-dependencies.md)
1 change: 1 addition & 0 deletions docs/releases/v3.4.0/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- [Settings Bugfixes](features/opensearch/settings-bugfixes.md) - Fix duplicate registration of dynamic settings and patch version build issues
- [Stats Builder Pattern Deprecations](features/opensearch/stats-builder-pattern-deprecations.md) - Deprecated constructors in 30+ Stats classes in favor of Builder pattern
- [XContent Filtering](features/opensearch/xcontent-filtering.md) - Case-insensitive filtering support for XContentMapValues.filter
- [Plugin Dependencies](features/opensearch/plugin-dependencies.md) - Range semver support for dependencies in plugin-descriptor.properties

### OpenSearch Dashboards

Expand Down