Skip to content

Commit 13a0f59

Browse files
committed
feat!: bump module to /v5 and promote generated opensearchapi
BREAKING CHANGE: module path is now github.com/opensearch-project/opensearch-go/v5. The generated API (formerly v5preview/opensearchapi) is now the canonical opensearchapi package; the hand-written package is removed. Default Router is on unless OPENSEARCH_GO_ROUTER=false; partial-failure errors report by default (errmask.Empty). Field renames: Indices->Index, DocumentID->ID, Params now pointer, BulkResp.Items is []BulkItem. Track 6 of opensearch-project#835. Signed-off-by: Sean Chittenden <sean.chittenden@crowdstrike.com>
1 parent a4c1e4e commit 13a0f59

159 files changed

Lines changed: 888 additions & 633 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.codecov.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ coverage:
2929
opensearchapi:
3030
paths:
3131
- "opensearchapi/"
32-
target: 14%
33-
threshold: 2%
34-
opensearchapiv5:
35-
paths:
36-
- "v5preview/opensearchapi/"
3732
target: 25%
3833
threshold: 5%
3934
patch: off

.github/workflows/check-gen.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
run: make -j gen
1818
- name: Check for diff
1919
run: |
20-
if ! git diff --exit-code internal/path/builders_gen.go internal/path/builders_gen_test.go v5preview/opensearchapi/; then
20+
if ! git diff --exit-code internal/path/builders_gen.go internal/path/builders_gen_test.go opensearchapi/; then
2121
echo "::warning::Generated code is out of date. Run 'make gen' and commit the result."
2222
exit 1
2323
fi

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ linters:
168168
# template level.
169169
- linters:
170170
- lll
171-
path: _integ_gen_test\.go|internal/path/builders_gen(_test)?\.go|v5preview/opensearchapi/.*_gen\.go
171+
path: _integ_gen_test\.go|internal/path/builders_gen(_test)?\.go|opensearchapi/.*_gen\.go
172172
paths:
173173
- third_party$
174174
- builtin$

Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ OPENAPI_SPEC_URL := https://github.com/opensearch-project/opensearch-api-specifi
159159

160160
# Generated code output directories.
161161
GEN_PATH_DIR := $(REPO_ROOT)/internal/path
162-
GEN_OSAPI_DIR := $(REPO_ROOT)/v5preview/opensearchapi
162+
GEN_OSAPI_DIR := $(REPO_ROOT)/opensearchapi
163163
GEN_PLUGINS_DIR := $(GEN_OSAPI_DIR)/plugins
164164

165165
# Version filtering defaults for code generation.
@@ -182,7 +182,7 @@ fetch-opensearch-spec-force: ## Re-download the OpenSearch OpenAPI spec from ups
182182
@printf "\033[2m-> Downloading %s...\033[0m\n" "$(OPENAPI_SPEC)"
183183
@curl -sSfL "$(OPENAPI_SPEC_URL)" -o "$(OPENAPI_SPEC)"
184184

185-
clean-gen: ## Remove all generated Go files (v5preview/opensearchapi, plugins, internal/path)
185+
clean-gen: ## Remove all generated Go files (opensearchapi, plugins, internal/path)
186186
@printf "\033[2m-> Removing generated files...\033[0m\n"
187187
@rm -f $(GEN_PATH_DIR)/builders_gen.go $(GEN_PATH_DIR)/builders_gen_test.go
188188
@rm -f $(GEN_OSAPI_DIR)/*_gen.go $(GEN_OSAPI_DIR)/*_gen_test.go
@@ -218,7 +218,7 @@ test-gen: regen ## Regen then run unit + integration tests (ensures tests use f
218218
@$(MAKE) test-unit
219219
@printf "\033[2m-> Running integration tests...\033[0m\n"
220220
$(eval SECURE_INTEGRATION ?= true)
221-
@SECURE_INTEGRATION=$(SECURE_INTEGRATION) go test -v -tags=integration -count=1 -timeout=5m ./v5preview/opensearchapi/...
221+
@SECURE_INTEGRATION=$(SECURE_INTEGRATION) go test -v -tags=integration -count=1 -timeout=5m ./opensearchapi/...
222222

223223
lint: ## Run lint on the package
224224
@$(MAKE) linters
@@ -352,7 +352,6 @@ godoc: ## Display documentation for the package
352352
@printf "\033[2m-> Generating documentation...\033[0m\n"
353353
@echo "* http://localhost:6060/pkg/github.com/opensearch-project/opensearch-go"
354354
@echo "* http://localhost:6060/pkg/github.com/opensearch-project/opensearch-go/opensearchapi"
355-
@echo "* http://localhost:6060/pkg/github.com/opensearch-project/opensearch-go/v4/v5preview/opensearchapi"
356355
@echo "* http://localhost:6060/pkg/github.com/opensearch-project/opensearch-go/opensearchtransport"
357356
@echo "* http://localhost:6060/pkg/github.com/opensearch-project/opensearch-go/opensearchutil"
358357
@printf "\n"

UPGRADING.md

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
- [Upgrading OpenSearch Go Client](#upgrading-opensearch-go-client)
22
- [Upgrading to >= 5.0.0](#upgrading-to->=-5.0.0)
33
- [Partial failure errors (Config.Errors)](#partial-failure-errors-configerrors)
4-
- [Default Router Injection in v5preview](#default-router-injection-in-v5preview)
4+
- [Default Router Injection in v5](#default-router-injection-in-v5)
55
- [DiscoverNodes() blocking semantics](#discovernodes-blocking-semantics)
66
- [opensearchtransport.Route interface gained OpID()](#opensearchtransportroute-interface-gained-opid)
77
- [Response.Body becomes a method](#responsebody-becomes-a-method)
88
- [Upgrading to >= 4.7.0](#upgrading-to->=-4.7.0)
99
- [opensearch.Request interface signature change](#opensearchrequest-interface-signature-change)
1010
- [Path segment values are percent-encoded](#path-segment-values-are-percent-encoded)
11-
- [v5preview/opensearchapi/ package - v5 preview API surface](#v5previewopensearchapi-package---v5-preview-api-surface)
11+
- [opensearchapi/ package - generated v5 API surface](#opensearchapi-package---generated-v5-api-surface)
1212
- [Upgrading to >= 4.0.0](#upgrading-to->=-4.0.0)
1313
- [Import path](#import-path)
1414
- [Error types](#error-types)
@@ -56,9 +56,9 @@ The recommended call-site pattern is a `for`/`switch` over `opensearchapi.Errors
5656

5757
**Where to read more:**
5858

59-
- [`v5preview/opensearchapi/README.md`](v5preview/opensearchapi/README.md) - full v5preview usage guide for these errors, including the type-switch pattern and the rationale for preferring it over `errors.As`/`Has`.
60-
- [`guides/error_handling.md`](guides/error_handling.md) - cross-version best-practices guide with v4 and v5preview examples side-by-side.
61-
- [`v5preview/opensearchapi/MIGRATING.md`](v5preview/opensearchapi/MIGRATING.md) - v4 -> v5preview surface delta.
59+
- [`opensearchapi/README.md`](opensearchapi/README.md) - full v5 usage guide for these errors, including the type-switch pattern and the rationale for preferring it over `errors.As`/`Has`.
60+
- [`guides/error_handling.md`](guides/error_handling.md) - cross-version best-practices guide with v4 and v5 examples side-by-side.
61+
- [`opensearchapi/MIGRATING.md`](opensearchapi/MIGRATING.md) - v4 -> v5 surface delta.
6262

6363
**Error types in v4 `opensearchapi/`** (the upgrade source):
6464

@@ -71,24 +71,24 @@ The recommended call-site pattern is a `for`/`switch` over `opensearchapi.Errors
7171
| `*MSearchErrors` | `MSearch` when 2+ wrappers fire | `Unwrap() []error` (multi-error contract) |
7272
| `*MSearchTemplateErrors` | `MSearchTemplate` when 2+ wrappers fire | `Unwrap() []error` |
7373

74-
The v5preview surface ports the same model with internal field types regenerated from the [OpenSearch API specification](https://github.com/opensearch-project/opensearch-api-specification) ([see MIGRATING.md](v5preview/opensearchapi/MIGRATING.md#partial-failure-type-renames) for the table).
74+
The v5 surface ports the same model with internal field types regenerated from the [OpenSearch API specification](https://github.com/opensearch-project/opensearch-api-specification) ([see MIGRATING.md](opensearchapi/MIGRATING.md#partial-failure-type-renames) for the table).
7575

76-
### Default Router Injection in v5preview
76+
### Default Router Injection in v5
7777

78-
`v5preview/opensearchapi.NewClient` (and `NewDefaultClient`) now inject [`opensearchtransport.NewDefaultRouter`](https://pkg.go.dev/github.com/opensearch-project/opensearch-go/v4/opensearchtransport#NewDefaultRouter) when the caller leaves `config.Client.Router` nil. The `OPENSEARCH_GO_ROUTER` environment variable acts as an opt-out:
78+
`opensearchapi.NewClient` (and `NewDefaultClient`) now inject [`opensearchtransport.NewDefaultRouter`](https://pkg.go.dev/github.com/opensearch-project/opensearch-go/v5/opensearchtransport#NewDefaultRouter) when the caller leaves `config.Client.Router` nil. The `OPENSEARCH_GO_ROUTER` environment variable acts as an opt-out:
7979

80-
| `OPENSEARCH_GO_ROUTER` | v4 | v5preview |
80+
| `OPENSEARCH_GO_ROUTER` | v4 | v5 |
8181
| ---------------------- | --------------------------------------------------- | ----------------------------------------------------------- |
8282
| unset | no Router, no auto-discovery | **default Router injected**, no auto-discovery |
8383
| `true` / `1` | default Router (transport layer), auto-discovery on | **default Router injected, auto-discovery on** |
8484
| `false` / `0` | no Router, no auto-discovery | **injection skipped (Router stays nil)**, no auto-discovery |
8585
| unparseable | no Router, no auto-discovery | default Router injected, no auto-discovery |
8686

87-
Truthy and falsy semantics are preserved end-to-end: a v4 caller running with `OPENSEARCH_GO_ROUTER=true` keeps auto-discovery when migrating to v5preview, and `=false` opts out of both Router injection and auto-discovery. A caller-supplied `DiscoverNodesOnStart` value always wins over the env-var-driven side-effect.
87+
Truthy and falsy semantics are preserved end-to-end: a v4 caller running with `OPENSEARCH_GO_ROUTER=true` keeps auto-discovery when migrating to v5, and `=false` opts out of both Router injection and auto-discovery. A caller-supplied `DiscoverNodesOnStart` value always wins over the env-var-driven side-effect.
8888

89-
v4's `opensearchapi.NewClient` is unchanged: it doesn't auto-inject a Router, so existing v4 code keeps its current behavior.
89+
v4's `opensearchapi.NewClient` did not auto-inject a Router, so v4 code keeps its original behavior; v5 flips the default so the Router is on unless `OPENSEARCH_GO_ROUTER=false`.
9090

91-
For full usage and rationale see [`v5preview/opensearchapi/README.md` Default Router Injection](v5preview/opensearchapi/README.md#default-router-injection).
91+
For full usage and rationale see [`opensearchapi/README.md` Default Router Injection](opensearchapi/README.md#default-router-injection).
9292

9393
### `DiscoverNodes()` blocking semantics
9494

@@ -133,7 +133,7 @@ type Route interface {
133133
}
134134
```
135135

136-
External code that implements `Route` (custom routing policies) must add an `OpID() OperationID` method returning the [`OperationID`](https://pkg.go.dev/github.com/opensearch-project/opensearch-go/v4/opensearchtransport#OperationID) for the route -- typically the `Op*` constant matching the route's HTTP method+path. Built-in routes built via `NewRouteMux` are populated automatically; only hand-written `Route` implementations are affected.
136+
External code that implements `Route` (custom routing policies) must add an `OpID() OperationID` method returning the [`OperationID`](https://pkg.go.dev/github.com/opensearch-project/opensearch-go/v5/opensearchtransport#OperationID) for the route -- typically the `Op*` constant matching the route's HTTP method+path. Built-in routes built via `NewRouteMux` are populated automatically; only hand-written `Route` implementations are affected.
137137

138138
### `Response.Body` becomes a method
139139

@@ -168,7 +168,7 @@ GetRequest() (*http.Request, error)
168168
GetRequest(method string) (*http.Request, error)
169169
```
170170

171-
This change is invisible to almost all callers: the typed `Req` structs that the client consumes (e.g. `opensearchapi.SearchReq`, the v5-preview `opensearchapi.IndexReq`) already implement the new signature. Only code that defines a custom type satisfying `opensearch.Request` is affected. If you maintain such a type, add a `method string` parameter and forward it to your underlying `http.NewRequest` call (or `opensearch.BuildRequest`).
171+
This change is invisible to almost all callers: the typed `Req` structs that the client consumes (e.g. `opensearchapi.SearchReq`, `opensearchapi.IndexReq`) already implement the new signature. Only code that defines a custom type satisfying `opensearch.Request` is affected. If you maintain such a type, add a `method string` parameter and forward it to your underlying `http.NewRequest` call (or `opensearch.BuildRequest`).
172172

173173
### Path segment values are percent-encoded
174174

@@ -188,19 +188,19 @@ If your code intentionally passes percent-encoded values, decode them with `url.
188188

189189
[#650]: https://github.com/opensearch-project/opensearch-go/issues/650
190190

191-
### `v5preview/opensearchapi/` package — v5 preview API surface
191+
### `opensearchapi/` package - generated v5 API surface
192192

193-
This release introduces a new `v5preview/opensearchapi/` package alongside the existing top-level `opensearchapi/` package. The new package is the **preview of the v5 API in the v4 branch** and is generated from the [OpenSearch API specification](https://github.com/opensearch-project/opensearch-api-specification) by `cmd/osgen`. It deliberately reuses the package name `opensearchapi` so that callers who migrate during the v4 branch only need to change the import path at v5 release time -- every reference in code (e.g. `opensearchapi.IndexReq`, `opensearchapi.NewClient`) stays the same.
193+
The v5 `opensearchapi/` package is generated from the [OpenSearch API specification](https://github.com/opensearch-project/opensearch-api-specification) by `cmd/osgen`, replacing the hand-written `opensearchapi/` package that shipped through v4. The same surface was distributed during the v4 branch as an early-access preview package for early adopters; it deliberately reused the package name `opensearchapi` so that callers who migrated during v4 only needed to change the import path at v5 release time -- every reference in code (e.g. `opensearchapi.IndexReq`, `opensearchapi.NewClient`) stays the same.
194194

195195
**Migration Considerations:**
196196

197-
- Migrating to `v5preview/opensearchapi/` in v4 gives you the v5 surface ahead of v5 release. The trade-off at v5 release time is a single edit per consuming file: change the import path from `/v4/v5preview/opensearchapi` to `/v5/opensearchapi`. Package qualifiers do not change.
198-
- Staying on the top-level `opensearchapi/` package is fine through the rest of v4. At v5, the hand-written `opensearchapi/` is removed; the only forward path is the code-generated API surface (closely matches the existing hand-written ergonomics).
197+
- Migrating from the hand-written v4 `opensearchapi/` to the v5 generated surface is a single import-path edit per consuming file: change the module path from `/v4/opensearchapi` to `/v5/opensearchapi`. Package qualifiers do not change. (Early adopters of the v4 preview package likewise change their import to `/v5/opensearchapi`.)
198+
- At v5, the hand-written `opensearchapi/` is removed; the only forward path is the code-generated API surface (closely matches the existing hand-written ergonomics).
199199

200200
**Import path:**
201201

202202
```go
203-
import "github.com/opensearch-project/opensearch-go/v4/v5preview/opensearchapi"
203+
import "github.com/opensearch-project/opensearch-go/v5/opensearchapi"
204204

205205
client, err := opensearchapi.NewClient(opensearchapi.Config{...})
206206
```
@@ -210,9 +210,9 @@ client, err := opensearchapi.NewClient(opensearchapi.Config{...})
210210
- Optional `Params` are `*Params` pointer fields (nil-safe; pass `&opensearchapi.IndexParams{...}` to set).
211211
- Optional boolean query parameters are `*bool` so a deliberate `false` can be sent over the wire.
212212
- Multi-index `Req` types use `Index []string` (the spec spelling); v4's hand-written `Indices` is renamed.
213-
- Plugin APIs (k-NN, ML, Security, ISM, etc.) live in `v5preview/opensearchapi/plugins/`.
213+
- Plugin APIs (k-NN, ML, Security, ISM, etc.) live in `opensearchapi/plugins/`.
214214

215-
For the full v4 -> v5preview surface delta and the optional forward-compatible `replace` directive, see [`v5preview/opensearchapi/MIGRATING.md`](v5preview/opensearchapi/MIGRATING.md). For everyday usage (errors, routing, response handling) see [`v5preview/opensearchapi/README.md`](v5preview/opensearchapi/README.md).
215+
For the full v4 -> v5 surface delta and the optional forward-compatible `replace` directive, see [`opensearchapi/MIGRATING.md`](opensearchapi/MIGRATING.md). For everyday usage (errors, routing, response handling) see [`opensearchapi/README.md`](opensearchapi/README.md).
216216

217217
## Upgrading to >= 4.0.0
218218

@@ -231,15 +231,15 @@ import (
231231

232232
// After (v4)
233233
import (
234-
"github.com/opensearch-project/opensearch-go/v4"
235-
"github.com/opensearch-project/opensearch-go/v4/opensearchapi"
234+
"github.com/opensearch-project/opensearch-go/v5"
235+
"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
236236
)
237237
```
238238

239239
Update your `go.mod`:
240240

241241
```bash
242-
go get github.com/opensearch-project/opensearch-go/v4@latest
242+
go get github.com/opensearch-project/opensearch-go/v5@latest
243243
```
244244

245245
### Error Types
@@ -338,7 +338,7 @@ With 4.0.0 (AWS SDK v2):
338338
import (
339339
"context"
340340
"github.com/aws/aws-sdk-go-v2/config"
341-
signer "github.com/opensearch-project/opensearch-go/v4/signer/aws"
341+
signer "github.com/opensearch-project/opensearch-go/v5/signer/aws"
342342
)
343343

344344
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-east-1"))
@@ -348,7 +348,7 @@ if err != nil {
348348
awsSigner, err := signer.NewSigner(cfg)
349349
```
350350

351-
The `signer/awsv2` package (which already used AWS SDK v2) remains available at `github.com/opensearch-project/opensearch-go/v4/signer/awsv2` with the same API.
351+
The `signer/awsv2` package (which already used AWS SDK v2) remains available at `github.com/opensearch-project/opensearch-go/v5/signer/awsv2` with the same API.
352352

353353
### Typed Failure Arrays in By-Query and Reindex Responses
354354

_samples/DISCOVERY_DEMO.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Discovery Demo
2+
3+
This demo demonstrates the complete node discovery flow with request routing.
4+
5+
## What It Shows
6+
7+
1. **Phase 1: Initial Request** - Seed URLs are used as `coordinating_only` nodes
8+
2. **Phase 2: Discovery** - Client discovers actual cluster nodes with roles
9+
3. **Phase 3: Request Routing** - Requests routed based on operation type and node roles
10+
11+
## Requirements
12+
13+
- OpenSearch cluster running on `localhost:9200` and `localhost:9201`
14+
- The demo will discover a third node at `localhost:9202` if available
15+
16+
## Running
17+
18+
```bash
19+
go run discovery_demo.go
20+
```
21+
22+
## Key Features Demonstrated
23+
24+
### Metrics Tracking
25+
26+
The demo shows the new client-side metrics:
27+
28+
- **Live/Dead Connections**: Current connection pool state
29+
- **Connections Promoted/Demoted**: Lifecycle tracking (resurrections and failures)
30+
- **Zombie Connections**: Dead connections forcibly retried when no live connections available
31+
- **Health Checks**: Baseline and cluster health check counts
32+
- **Overloaded Servers**: Number of servers currently marked as overloaded
33+
34+
### Request Routing
35+
36+
After discovery completes:
37+
38+
- **Bulk operations** -> Route to ingest nodes
39+
- **Search operations** -> Route to data/search nodes
40+
- **General operations** -> Round-robin across all nodes
41+
42+
### Discovery Flow
43+
44+
Watch the debug logs (when not in CI) to see:
45+
46+
1. Seed URLs added to `coordinator_only` policy
47+
2. Initial request uses seed URL
48+
3. Discovery runs automatically
49+
4. Seed URLs removed from `coordinator_only` after nodes with actual roles discovered
50+
5. Router takes over with role-based routing
51+
52+
## Configuration
53+
54+
The demo uses fast timeouts for quick demonstration:
55+
56+
- Discovery interval: 5 seconds
57+
- Health check timeout: 2 seconds
58+
- Resurrection timeouts: 1-10 seconds
59+
60+
Production should use the default values (much longer intervals).

_samples/advanced_index_actions.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import (
1111
"os"
1212
"strings"
1313

14-
"github.com/opensearch-project/opensearch-go/v4"
15-
"github.com/opensearch-project/opensearch-go/v4/opensearchapi"
14+
"github.com/opensearch-project/opensearch-go/v5"
15+
"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
1616
)
1717

1818
func main() {

_samples/bulk.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import (
1313
"os"
1414
"strings"
1515

16-
"github.com/opensearch-project/opensearch-go/v4"
17-
"github.com/opensearch-project/opensearch-go/v4/opensearchapi"
16+
"github.com/opensearch-project/opensearch-go/v5"
17+
"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
1818
)
1919

2020
func main() {

_samples/client_config_retrieval.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
"fmt"
1111
"os"
1212

13-
"github.com/opensearch-project/opensearch-go/v4"
14-
"github.com/opensearch-project/opensearch-go/v4/opensearchapi"
13+
"github.com/opensearch-project/opensearch-go/v5"
14+
"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
1515
)
1616

1717
func main() {

_samples/client_from_existing.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
"fmt"
1111
"os"
1212

13-
"github.com/opensearch-project/opensearch-go/v4"
14-
"github.com/opensearch-project/opensearch-go/v4/opensearchapi"
13+
"github.com/opensearch-project/opensearch-go/v5"
14+
"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
1515
)
1616

1717
func main() {

0 commit comments

Comments
 (0)