Commit eeb87de
authored
Fix selectSparkVersion() crash on non-SemVer runtime keys (#832)
## Summary
`WorkspaceClient.clusters().selectSparkVersion(...)` throws
`IllegalArgumentException: Not a valid SemVer: ...` when the Spark
versions API returns a runtime key that is not a valid SemVer. This
makes the sort that picks the latest runtime resilient to such keys,
mirroring the behavior of the Go SDK.
## Why
`selectSparkVersion(latest)` gathers the matching runtime keys and sorts
them to pick the newest:
```java
versions.sort((v1, v2) -> SemVer.parse(v2).compareTo(SemVer.parse(v1)));
```
`SemVer.parse` throws `IllegalArgumentException` on any string it cannot
parse, and because that happens *inside* the sort comparator, a single
unparseable key aborts the entire selection. The clusters API recently
started returning the key `v18.x-scala2.13` — two version segments
(`18.x`) plus a leading `v` — which the SemVer regex (it expects
`major.minor.patch`) rejects. As a result, every caller of
`selectSparkVersion(latest)` in such a workspace fails, and the
`ClustersIT.latestRuntime` integration test started failing across all
clouds.
The Go SDK does not have this problem: its comparator uses
`golang.org/x/mod/semver.Compare`, which is total and never throws —
invalid versions simply sort lowest and are effectively ignored when
picking "latest". This PR brings the Java behavior in line, which also
keeps the two SDKs consistent and makes selection robust to any future
malformed key, not just this specific shape.
## What changed
### Interface changes
- **`SemVer.parseOrNull(String)`** — parses a version string, returning
`null` instead of throwing when the input is not a valid SemVer.
### Behavioral changes
- `selectSparkVersion(latest)` no longer throws when the API returns a
non-SemVer runtime key. Unparseable keys are ranked lowest and the
latest parseable runtime is returned, matching the Go SDK. (Previously
every such call threw `IllegalArgumentException`.)
### Internal changes
- The version sort in `ClustersExt.selectSparkVersion` now uses a
null-safe comparator (`compareSparkVersionsDescending`) built on
`SemVer.parseOrNull`.
## How is this tested?
Unit tests (run via `mvn`):
- `SemVerTest` — `parseOrNull` returns `null` for the `v18.x-scala2.13`
shape, malformed input, `null`, and empty string, and still parses valid
versions.
- `ClustersExtTest` — new regression test feeds a versions list
containing `v18.x-scala2.13` and asserts `selectSparkVersion(latest)`
does not throw and returns the latest parseable runtime
(`15.4.x-scala2.12`). This test fails on the pre-fix code.
NO_CHANGELOG=true1 parent bb48b1e commit eeb87de
4 files changed
Lines changed: 82 additions & 1 deletion
File tree
- databricks-sdk-java/src
- main/java/com/databricks/sdk/mixin
- test/java/com/databricks/sdk/mixin
Lines changed: 22 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
| 66 | + | |
67 | 67 | | |
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
71 | 92 | | |
72 | 93 | | |
73 | 94 | | |
| |||
Lines changed: 13 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
50 | 63 | | |
51 | 64 | | |
52 | 65 | | |
| |||
Lines changed: 30 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
143 | 143 | | |
144 | 144 | | |
145 | 145 | | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
146 | 176 | | |
Lines changed: 17 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
40 | 57 | | |
0 commit comments