Skip to content

Commit

Permalink
opensearchapi: add update function to rootClient
Browse files Browse the repository at this point in the history
Signed-off-by: Jakob Hahn <[email protected]>
  • Loading branch information
Jakob3xD committed Oct 27, 2023
1 parent 5a52292 commit c382309
Show file tree
Hide file tree
Showing 3 changed files with 288 additions and 0 deletions.
118 changes: 118 additions & 0 deletions opensearchapi/api_update-params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// SPDX-License-Identifier: Apache-2.0
//
// The OpenSearch Contributors require contributions made to
// this file be licensed under the Apache-2.0 license or a
// compatible open source license.
//
// Modifications Copyright OpenSearch Contributors. See
// GitHub history for details.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package opensearchapi

import (
"strconv"
"strings"
"time"
)

// UpdateParams represents possible parameters for the UpdateReq
type UpdateParams struct {
IfPrimaryTerm *int
IfSeqNo *int
Lang string
Refresh string
RequireAlias *bool
RetryOnConflict *int
Routing string
Source interface{}
SourceExcludes []string
SourceIncludes []string
Timeout time.Duration
WaitForActiveShards string

Pretty bool
Human bool
ErrorTrace bool
}

func (r UpdateParams) get() map[string]string {
params := make(map[string]string)

if r.IfPrimaryTerm != nil {
params["if_primary_term"] = strconv.FormatInt(int64(*r.IfPrimaryTerm), 10)
}

if r.IfSeqNo != nil {
params["if_seq_no"] = strconv.FormatInt(int64(*r.IfSeqNo), 10)
}

if r.Lang != "" {
params["lang"] = r.Lang
}

if r.Refresh != "" {
params["refresh"] = r.Refresh
}

if r.RequireAlias != nil {
params["require_alias"] = strconv.FormatBool(*r.RequireAlias)
}

if r.RetryOnConflict != nil {
params["retry_on_conflict"] = strconv.FormatInt(int64(*r.RetryOnConflict), 10)
}

if r.Routing != "" {
params["routing"] = r.Routing
}

if source, ok := r.Source.(bool); ok {
params["_source"] = strconv.FormatBool(source)
} else if source, ok := r.Source.(string); ok && source != "" {
params["_source"] = source
} else if sources, ok := r.Source.([]string); ok && len(sources) > 0 {
params["_source"] = strings.Join(sources, ",")
}

if len(r.SourceExcludes) > 0 {
params["_source_excludes"] = strings.Join(r.SourceExcludes, ",")
}

if len(r.SourceIncludes) > 0 {
params["_source_includes"] = strings.Join(r.SourceIncludes, ",")
}

if r.Timeout != 0 {
params["timeout"] = formatDuration(r.Timeout)
}

if r.WaitForActiveShards != "" {
params["wait_for_active_shards"] = r.WaitForActiveShards
}

if r.Pretty {
params["pretty"] = "true"
}

if r.Human {
params["human"] = "true"
}

if r.ErrorTrace {
params["error_trace"] = "true"
}

return params
}
87 changes: 87 additions & 0 deletions opensearchapi/api_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: Apache-2.0
//
// The OpenSearch Contributors require contributions made to
// this file be licensed under the Apache-2.0 license or a
// compatible open source license.
//
// Modifications Copyright OpenSearch Contributors. See
// GitHub history for details.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package opensearchapi

import (
"context"
"fmt"
"io"
"net/http"

"github.com/opensearch-project/opensearch-go/v2"
)

// Update executes a /_update request with the optional UpdateReq
func (c Client) Update(ctx context.Context, req UpdateReq) (*UpdateResp, error) {
var (
data UpdateResp
err error
)
if data.response, err = c.do(ctx, req, &data); err != nil {
return &data, err
}

return &data, nil
}

// UpdateReq represents possible options for the /_update request
type UpdateReq struct {
Index string
DocumentID string

Body io.Reader

Header http.Header
Params UpdateParams
}

// GetRequest returns the *http.Request that gets executed by the client
func (r UpdateReq) GetRequest() (*http.Request, error) {
return opensearch.BuildRequest(
"POST",
fmt.Sprintf("/%s/_update/%s", r.Index, r.DocumentID),
r.Body,
r.Params.get(),
r.Header,
)
}

// UpdateResp represents the returned struct of the /_update response
type UpdateResp struct {
Index string `json:"_index"`
ID string `json:"_id"`
Version int `json:"_version"`
Result string `json:"result"`
Shards struct {
Total int `json:"total"`
Successful int `json:"successful"`
Failed int `json:"failed"`
} `json:"_shards"`
SeqNo int `json:"_seq_no"`
PrimaryTerm int `json:"_primary_term"`
response *opensearch.Response
}

// Inspect returns the Inspect type containing the raw *opensearch.Reponse
func (r UpdateResp) Inspect() Inspect {
return Inspect{Response: r.response}
}
83 changes: 83 additions & 0 deletions opensearchapi/api_update_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// SPDX-License-Identifier: Apache-2.0
//
// The OpenSearch Contributors require contributions made to
// this file be licensed under the Apache-2.0 license or a
// compatible open source license.
//
// Modifications Copyright OpenSearch Contributors. See
// GitHub history for details.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//go:build integration

package opensearchapi_test

import (
"strconv"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/opensearch-project/opensearch-go/v2/opensearchapi"
osapitest "github.com/opensearch-project/opensearch-go/v2/opensearchapi/internal/test"
)

func TestUpdate(t *testing.T) {
client, err := opensearchapi.NewDefaultClient()
require.Nil(t, err)

testIndex := "test-update"
t.Cleanup(func() {
client.Indices.Delete(nil, opensearchapi.IndicesDeleteReq{Indices: []string{testIndex}})
})

for i := 1; i <= 2; i++ {
_, err = client.Document.Create(
nil,
opensearchapi.DocumentCreateReq{
Index: testIndex,
Body: strings.NewReader(`{"foo": "bar", "counter": 1}`),
DocumentID: strconv.Itoa(i),
Params: opensearchapi.DocumentCreateParams{Refresh: "true"},
},
)
require.Nil(t, err)
}

t.Run("with request", func(t *testing.T) {
resp, err := client.Update(
nil,
opensearchapi.UpdateReq{
Index: testIndex,
DocumentID: "1",
Body: strings.NewReader(`{"script":{"source":"ctx._source.counter += params.count","lang":"painless","params":{"count":4}}}`),
},
)
require.Nil(t, err)
assert.NotEmpty(t, resp)
osapitest.CompareRawJSONwithParsedJSON(t, resp, resp.Inspect().Response)
})

t.Run("inspect", func(t *testing.T) {
failingClient, err := osapitest.CreateFailingClient()
require.Nil(t, err)

res, err := failingClient.Update(nil, opensearchapi.UpdateReq{})
assert.NotNil(t, err)
assert.NotNil(t, res)
osapitest.VerifyInspect(t, res.Inspect())
})
}

0 comments on commit c382309

Please sign in to comment.