From d7a770681d11de4a82804fce52a9aa662f9bd20d Mon Sep 17 00:00:00 2001 From: Jakob Hahn Date: Thu, 16 Nov 2023 12:02:29 +0100 Subject: [PATCH] UPGRADING: add differences of 3.0.0 release Signed-off-by: Jakob Hahn --- UPGRADING.md | 189 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 170 insertions(+), 19 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index d09583b4d..5532e5a75 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,17 +1,21 @@ - [Upgrading Opensearch GO Client](#upgrading-opensearch-go-client) + - [Upgraading to >= 2.3.0](#upgrading-to->=-2.3.0) + - [snapshot delete](#opensearchapi-snapshot-delete) - [Upgraading to >= 3.0.0](#upgrading-to->=-3.0.0) - - [opensearchapi](#opensearchapi-snapshot-delete) - - [opensearchapi](#opensearchapi-error-handling) + - [client creation](#client-creation) + - [requests](#requests) + - [responses](#responses) + - [error handing](#opensearchapi-error-handling) # Upgrading Opensearch GO Client -## Upgrading to >= 3.0.0 +## Upgrading to >= 2.3.0 ### opensearchapi snapshot delete `SnapshotDeleteRequest` and `SnapshotDelete` changed the argument `Snapshot` type from `string` to `[]string`. -Before 3.0.0: +Before 2.3.0: ```go // If you have a string containing your snapshot @@ -29,7 +33,7 @@ reqSnapshots := &opensearchapi.SnapshotDeleteRequest{ } ``` -With 3.0.0: +With 2.3.0: ```go // If you have a string containing your snapshots @@ -46,6 +50,148 @@ reqSnapshots := &opensearchapi.SnapshotDeleteRequest{ Snapshot: sliceSnapshotsToDelete, ``` +## Upgrading to >= 3.0.0 + +Version 3.0.0 contains a large restructure of the lib braking all existing implementations. + +### Client creation +You now create the client from the opensearchapi and not from the opensearch lib. This was done to make the different APIs independent from each other. Plugin APIs like Security will get there own folder and therefore its own sub-lib. + +Before 3.0.0: +```go +// default client +client, err := opensearch.NewDefaultClient() + +// with config +client, err := opensearch.NewClient( + opensearch.Config{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + Addresses: []string{"https://localhost:9200"}, + Username: "admin", + Password: "admin", + }, +) +``` + +With 3.0.0: + +```go +// default client +client, err := opensearchapi.NewDefaultClient() + +// with config +client, err := opensearchapi.NewClient( + opensearchapi.Config{ + Client: opensearch.Config{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // For testing only. Use certificate for validation. + }, + Addresses: []string{"https://localhost:9200"}, + Username: "admin", // For testing only. Don't store credentials in code. + Password: "admin", + }, + }, +) +``` + +### Requests + +Prior version 3.0.0 there were two options on how to perform requests. You could either use the request struct of the wished function and execute it with the client .Do() function or use the client function and add wanted args with so called With() functions. With the new version you now use functions attached to the client and give a context and the wanted request body as argument. + +Before 3.0.0: + +```go +// using the client function and adding args by using the With() functions +createIndex, err := client.Indices.Create( + "some-index", + client.Indices.Create.WithContext(ctx), + client.Indices.Create.WithBody(strings.NewReader(`{"settings":{"index":{"number_of_shards":4}}}`)), +) + +// using the request struct +createIndex := opensearchapi.IndicesCreateRequest{ + Index: "some-index", + Body: strings.NewReader(`{"settings":{"index":{"number_of_shards":4}}}`), +} +createIndexResponse, err := createIndex.Do(ctx, client) +``` + +With 3.0.0: + +```go +createIndexResponse, err := client.Indices.Create( + ctx, + opensearchapi.IndicesCreateReq{ + Index: "some-index", + Body: strings.NewReader(`{"settings":{"index":{"number_of_shards":4}}}`), + }, +) +``` + + +### Responses + +With the version 3.0.0 the lib no longer returns the opensearch.Response which is just a wrap up http.Response. Instead it will check the response for errors and try to parse the body into existing structs. Please note that some responses are so complex that we parse them as [json.RawMessage](https://pkg.go.dev/encoding/json#RawMessage) so you can parse them to your expected struct. If you need the opensearch.Response, then you can call .Inspect(). + +Before 3.0.0: + +```go +// Create the request +createIndex := opensearchapi.IndicesCreateRequest{ + Index: "some-index", + Body: strings.NewReader(`{"settings":{"index":{"number_of_shards":4}}}`), +} +// Execute the requests +resp, err := createIndex.Do(ctx, client) +if err != nil { + return err +} +// Close the body +defer resp.Body.Close() + +// Check if the status code is >299 +if resp.IsError() { + return fmt.Errorf("Opensearch Returned an error: %#v", resp) +} + +// Create a struct that represents the create index response +createResp := struct { + Acknowledged bool `json:"acknowledged"` + ShardsAcknowledged bool `json:"shards_acknowledged"` + Index string `json:"index"` +} + +// Try to parse the response into the created struct +if err := json.NewDecoder(resp.Body).Decode(&createResp); err != nil { + return fmt.Errorf("Undexpected response body: %s, %#v, %s"resp.StatusCode, resp.Body, err) +} +// Print the created index name +fmt.Println(createResp.Index) +``` + +With 3.0.0: + +```go +// Create and execute the requests +createResp, err := client.Indices.Create( + ctx, + opensearchapi.IndicesCreateReq{ + Index: "some-index", + Body: strings.NewReader(`{"settings":{"index":{"number_of_shards":4}}}`), + }, +) +if err != nil { + return err +} +// Print the created index name +fmt.Println(createResp.Index) + +// To get the opensearch.Response/http.Response +rawResp := createResp.Inspect().Response +``` + ### opensearchapi error handling With opensearch-go >= 3.0.0 opensearchapi responses are now checked for errors. Checking for errors twice is no longer needed. @@ -55,16 +201,21 @@ Prior versions only returned an error if the request failed to execute. For exam Before 3.0.0: ```go +// Create the request createIndex := opensearchapi.IndicesCreateRequest{ - Index: IndexName, - Body: mapping, + Index: "some-index", + Body: strings.NewReader(`{"settings":{"index":{"number_of_shards":4}}}`), } -ctx := context.Background() -createIndexResp, err := createIndex.Do(ctx, client) +// Execute the requests +resp, err := createIndex.Do(ctx, client) if err != nil { - return err + return err } +// Close the body +defer resp.Body.Close() + +// Check if the status code is >299 if createIndexResp.IsError() { fmt.Errorf("Opensearch returned an error. Status: %d", createIndexResp.StatusCode) } @@ -73,15 +224,15 @@ if createIndexResp.IsError() { With 3.0.0: ```go -createIndex := opensearchapi.IndicesCreateRequest{ - Index: IndexName, - Body: mapping, -} - -ctx := context.Background() -var opensearchError *opensearchapi.Error - -createIndexResponse, err := createIndex.Do(ctx, client) +var opensearchError opensearchapi.Error +// Create and execute the requests +createResp, err := client.Indices.Create( + ctx, + opensearchapi.IndicesCreateReq{ + Index: "some-index", + Body: strings.NewReader(`{"settings":{"index":{"number_of_shards":4}}}`), + }, +) // Load err into opensearchapi.Error to access the fields and tolerate if the index already exists if err != nil { if errors.As(err, &opensearchError) {