From 42a477164195b2c02cd5f7f900c205dc32db8774 Mon Sep 17 00:00:00 2001 From: Jakob Hahn Date: Fri, 29 Sep 2023 15:49:48 +0200 Subject: [PATCH] opensearchapi: add msearch template function to rootClient Signed-off-by: Jakob Hahn --- opensearchapi/api_msearch-template-params.go | 77 ++++++++++++++ opensearchapi/api_msearch-template.go | 104 +++++++++++++++++++ opensearchapi/api_msearch-template_test.go | 82 +++++++++++++++ 3 files changed, 263 insertions(+) create mode 100644 opensearchapi/api_msearch-template-params.go create mode 100644 opensearchapi/api_msearch-template.go create mode 100644 opensearchapi/api_msearch-template_test.go diff --git a/opensearchapi/api_msearch-template-params.go b/opensearchapi/api_msearch-template-params.go new file mode 100644 index 000000000..6940a6ee0 --- /dev/null +++ b/opensearchapi/api_msearch-template-params.go @@ -0,0 +1,77 @@ +// 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" +) + +// MSearchTemplateParams represents possible parameters for the MSearchTemplateReq +type MSearchTemplateParams struct { + CcsMinimizeRoundtrips *bool + MaxConcurrentSearches *int + RestTotalHitsAsInt *bool + SearchType string + TypedKeys *bool + + Pretty bool + Human bool + ErrorTrace bool +} + +func (r MSearchTemplateParams) get() map[string]string { + params := make(map[string]string) + + if r.CcsMinimizeRoundtrips != nil { + params["ccs_minimize_roundtrips"] = strconv.FormatBool(*r.CcsMinimizeRoundtrips) + } + + if r.MaxConcurrentSearches != nil { + params["max_concurrent_searches"] = strconv.FormatInt(int64(*r.MaxConcurrentSearches), 10) + } + + if r.RestTotalHitsAsInt != nil { + params["rest_total_hits_as_int"] = strconv.FormatBool(*r.RestTotalHitsAsInt) + } + + if r.SearchType != "" { + params["search_type"] = r.SearchType + } + + if r.TypedKeys != nil { + params["typed_keys"] = strconv.FormatBool(*r.TypedKeys) + } + + if r.Pretty { + params["pretty"] = "true" + } + + if r.Human { + params["human"] = "true" + } + + if r.ErrorTrace { + params["error_trace"] = "true" + } + + return params +} diff --git a/opensearchapi/api_msearch-template.go b/opensearchapi/api_msearch-template.go new file mode 100644 index 000000000..e090b1b95 --- /dev/null +++ b/opensearchapi/api_msearch-template.go @@ -0,0 +1,104 @@ +// 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" + "io" + "net/http" + "strings" + + "github.com/opensearch-project/opensearch-go/v2" +) + +// MSearchTemplate executes a /_msearch request with the optional MSearchTemplateReq +func (c Client) MSearchTemplate(ctx context.Context, req MSearchTemplateReq) (*MSearchTemplateResp, error) { + var ( + data MSearchTemplateResp + err error + ) + if data.response, err = c.do(ctx, req, &data); err != nil { + return &data, err + } + + return &data, nil +} + +// MSearchTemplateReq represents possible options for the /_msearch request +type MSearchTemplateReq struct { + Indices []string + + Body io.Reader + + Header http.Header + Params MSearchTemplateParams +} + +// GetRequest returns the *http.Request that gets executed by the client +func (r MSearchTemplateReq) GetRequest() (*http.Request, error) { + indices := strings.Join(r.Indices, ",") + var path strings.Builder + path.Grow(len("//_msearch/template") + len(indices)) + if len(r.Indices) > 0 { + path.WriteString("/") + path.WriteString(indices) + } + path.WriteString("/_msearch/template") + return opensearch.BuildRequest( + "POST", + path.String(), + r.Body, + r.Params.get(), + r.Header, + ) +} + +// MSearchTemplateResp represents the returned struct of the /_msearch response +type MSearchTemplateResp struct { + Took int `json:"took"` + Responses []struct { + Took int `json:"took"` + Timeout bool `json:"timed_out"` + Shards struct { + Total int `json:"total"` + Successful int `json:"successful"` + Failed int `json:"failed"` + Failures int `json:"failures"` // Deprecated field + Skipped int `json:"skipped"` + } `json:"_shards"` + Hits struct { + Total struct { + Value int `json:"value"` + Relation string `json:"relation"` + } `json:"total"` + MaxScore *float32 `json:"max_score"` + Hits []SearchHit `json:"hits"` + } `json:"hits"` + Status int `json:"status"` + } `json:"responses"` + response *opensearch.Response +} + +// Inspect returns the Inspect type containing the raw *opensearch.Reponse +func (r MSearchTemplateResp) Inspect() Inspect { + return Inspect{Response: r.response} +} diff --git a/opensearchapi/api_msearch-template_test.go b/opensearchapi/api_msearch-template_test.go new file mode 100644 index 000000000..a4e27db15 --- /dev/null +++ b/opensearchapi/api_msearch-template_test.go @@ -0,0 +1,82 @@ +// 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 TestMSearchTemplate(t *testing.T) { + client, err := opensearchapi.NewDefaultClient() + require.Nil(t, err) + + testIndex := "test-msearch" + 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"}`), + DocumentID: strconv.Itoa(i), + Params: opensearchapi.DocumentCreateParams{Refresh: "true"}, + }, + ) + require.Nil(t, err) + } + + t.Run("with request", func(t *testing.T) { + resp, err := client.MSearchTemplate( + nil, + opensearchapi.MSearchTemplateReq{ + Indices: []string{testIndex}, + Body: strings.NewReader("{}\n{\"source\":{\"query\":{\"exists\":{\"field\":\"{{field}}\"}}},\"params\": {\"field\": \"foo\"}}\n"), + }, + ) + 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.MSearchTemplate(nil, opensearchapi.MSearchTemplateReq{}) + assert.NotNil(t, err) + assert.NotNil(t, res) + osapitest.VerifyInspect(t, res.Inspect()) + }) +}