diff --git a/docs/features/index.md b/docs/features/index.md index a963e1490..d913f4b94 100644 --- a/docs/features/index.md +++ b/docs/features/index.md @@ -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) diff --git a/docs/features/opensearch/plugin-dependencies.md b/docs/features/opensearch/plugin-dependencies.md new file mode 100644 index 000000000..dfe812498 --- /dev/null +++ b/docs/features/opensearch/plugin-dependencies.md @@ -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 diff --git a/docs/releases/v3.4.0/features/opensearch/plugin-dependencies.md b/docs/releases/v3.4.0/features/opensearch/plugin-dependencies.md new file mode 100644 index 000000000..60d8f4e35 --- /dev/null +++ b/docs/releases/v3.4.0/features/opensearch/plugin-dependencies.md @@ -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) diff --git a/docs/releases/v3.4.0/index.md b/docs/releases/v3.4.0/index.md index 5ad0bbb7e..1ed57e30e 100644 --- a/docs/releases/v3.4.0/index.md +++ b/docs/releases/v3.4.0/index.md @@ -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