diff --git a/opensearchapi/api_ingest-create-params.go b/opensearchapi/api_ingest-create-params.go new file mode 100644 index 000000000..4a448b9ad --- /dev/null +++ b/opensearchapi/api_ingest-create-params.go @@ -0,0 +1,65 @@ +// 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 "time" + +// IngestCreateParams represents possible parameters for the IngestCreateReq +type IngestCreateParams struct { + MasterTimeout time.Duration + ClusterManagerTimeout time.Duration + Timeout time.Duration + + Pretty bool + Human bool + ErrorTrace bool +} + +func (r IngestCreateParams) get() map[string]string { + params := make(map[string]string) + + if r.MasterTimeout != 0 { + params["master_timeout"] = formatDuration(r.MasterTimeout) + } + + if r.ClusterManagerTimeout != 0 { + params["cluster_manager_timeout"] = formatDuration(r.ClusterManagerTimeout) + } + + if r.Timeout != 0 { + params["timeout"] = formatDuration(r.Timeout) + } + + 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_ingest-create.go b/opensearchapi/api_ingest-create.go new file mode 100644 index 000000000..ff733eb80 --- /dev/null +++ b/opensearchapi/api_ingest-create.go @@ -0,0 +1,62 @@ +// 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 ( + "fmt" + "io" + "net/http" + + "github.com/opensearch-project/opensearch-go/v2" +) + +// IngestCreateReq represents possible options for the index create request +type IngestCreateReq struct { + PipelineID string + + Body io.Reader + + Header http.Header + Params IngestCreateParams +} + +// GetRequest returns the *http.Request that gets executed by the client +func (r IngestCreateReq) GetRequest() (*http.Request, error) { + return opensearch.BuildRequest( + "PUT", + fmt.Sprintf("/_ingest/pipeline/%s", r.PipelineID), + r.Body, + r.Params.get(), + r.Header, + ) +} + +// IngestCreateResp represents the returned struct of the index create response +type IngestCreateResp struct { + Acknowledged bool `json:"acknowledged"` + response *opensearch.Response +} + +// Inspect returns the Inspect type containing the raw *opensearch.Reponse +func (r IngestCreateResp) Inspect() Inspect { + return Inspect{Response: r.response} +} diff --git a/opensearchapi/api_ingest-delete-params.go b/opensearchapi/api_ingest-delete-params.go new file mode 100644 index 000000000..ed686cac0 --- /dev/null +++ b/opensearchapi/api_ingest-delete-params.go @@ -0,0 +1,65 @@ +// 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 "time" + +// IngestDeleteParams represents possible parameters for the IngestDeleteReq +type IngestDeleteParams struct { + MasterTimeout time.Duration + ClusterManagerTimeout time.Duration + Timeout time.Duration + + Pretty bool + Human bool + ErrorTrace bool +} + +func (r IngestDeleteParams) get() map[string]string { + params := make(map[string]string) + + if r.MasterTimeout != 0 { + params["master_timeout"] = formatDuration(r.MasterTimeout) + } + + if r.ClusterManagerTimeout != 0 { + params["cluster_manager_timeout"] = formatDuration(r.ClusterManagerTimeout) + } + + if r.Timeout != 0 { + params["timeout"] = formatDuration(r.Timeout) + } + + 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_ingest-delete.go b/opensearchapi/api_ingest-delete.go new file mode 100644 index 000000000..57cb1e204 --- /dev/null +++ b/opensearchapi/api_ingest-delete.go @@ -0,0 +1,59 @@ +// 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 ( + "fmt" + "net/http" + + "github.com/opensearch-project/opensearch-go/v2" +) + +// IngestDeleteReq represents possible options for the index create request +type IngestDeleteReq struct { + PipelineID string + + Header http.Header + Params IngestDeleteParams +} + +// GetRequest returns the *http.Request that gets executed by the client +func (r IngestDeleteReq) GetRequest() (*http.Request, error) { + return opensearch.BuildRequest( + "DELETE", + fmt.Sprintf("/_ingest/pipeline/%s", r.PipelineID), + nil, + r.Params.get(), + r.Header, + ) +} + +// IngestDeleteResp represents the returned struct of the index create response +type IngestDeleteResp struct { + Acknowledged bool `json:"acknowledged"` + response *opensearch.Response +} + +// Inspect returns the Inspect type containing the raw *opensearch.Reponse +func (r IngestDeleteResp) Inspect() Inspect { + return Inspect{Response: r.response} +} diff --git a/opensearchapi/api_ingest-get-params.go b/opensearchapi/api_ingest-get-params.go new file mode 100644 index 000000000..51656386b --- /dev/null +++ b/opensearchapi/api_ingest-get-params.go @@ -0,0 +1,68 @@ +// 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" + "time" +) + +// IngestGetParams represents possible parameters for the IngestGetReq +type IngestGetParams struct { + MasterTimeout time.Duration + ClusterManagerTimeout time.Duration + Summary *bool + + Pretty bool + Human bool + ErrorTrace bool +} + +func (r IngestGetParams) get() map[string]string { + params := make(map[string]string) + + if r.MasterTimeout != 0 { + params["master_timeout"] = formatDuration(r.MasterTimeout) + } + + if r.ClusterManagerTimeout != 0 { + params["cluster_manager_timeout"] = formatDuration(r.ClusterManagerTimeout) + } + + if r.Summary != nil { + params["summary"] = strconv.FormatBool(*r.Summary) + } + + 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_ingest-get.go b/opensearchapi/api_ingest-get.go new file mode 100644 index 000000000..cbd88f308 --- /dev/null +++ b/opensearchapi/api_ingest-get.go @@ -0,0 +1,64 @@ +// 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 ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/opensearch-project/opensearch-go/v2" +) + +// IngestGetReq represents possible options for the index create request +type IngestGetReq struct { + PipelineIDs []string + + Header http.Header + Params IngestGetParams +} + +// GetRequest returns the *http.Request that gets executed by the client +func (r IngestGetReq) GetRequest() (*http.Request, error) { + return opensearch.BuildRequest( + "GET", + fmt.Sprintf("/_ingest/pipeline/%s", strings.Join(r.PipelineIDs, ",")), + nil, + r.Params.get(), + r.Header, + ) +} + +// IngestGetResp represents the returned struct of the index create response +type IngestGetResp struct { + Pipelines map[string]struct { + Description string `json:"description"` + Processors []map[string]json.RawMessage `json:"processors"` + } + response *opensearch.Response +} + +// Inspect returns the Inspect type containing the raw *opensearch.Reponse +func (r IngestGetResp) Inspect() Inspect { + return Inspect{Response: r.response} +} diff --git a/opensearchapi/api_ingest-simulate-params.go b/opensearchapi/api_ingest-simulate-params.go new file mode 100644 index 000000000..ab5e5d719 --- /dev/null +++ b/opensearchapi/api_ingest-simulate-params.go @@ -0,0 +1,55 @@ +// 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" + +// IngestSimulateParams represents possible parameters for the IngestSimulateReq +type IngestSimulateParams struct { + Verbose *bool + + Pretty bool + Human bool + ErrorTrace bool +} + +func (r IngestSimulateParams) get() map[string]string { + params := make(map[string]string) + + if r.Verbose != nil { + params["verbose"] = strconv.FormatBool(*r.Verbose) + } + + 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_ingest-simulate.go b/opensearchapi/api_ingest-simulate.go new file mode 100644 index 000000000..c62eafd6d --- /dev/null +++ b/opensearchapi/api_ingest-simulate.go @@ -0,0 +1,71 @@ +// 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 ( + "encoding/json" + "io" + "net/http" + "strings" + + "github.com/opensearch-project/opensearch-go/v2" +) + +// IngestSimulateReq represents possible options for the index create request +type IngestSimulateReq struct { + PipelineID string + + Body io.Reader + + Header http.Header + Params IngestSimulateParams +} + +// GetRequest returns the *http.Request that gets executed by the client +func (r IngestSimulateReq) GetRequest() (*http.Request, error) { + var path strings.Builder + path.Grow(len("/_ingest/pipeline//_simulate") + len(r.PipelineID)) + path.WriteString("/_ingest/pipeline/") + if len(r.PipelineID) > 0 { + path.WriteString(r.PipelineID) + path.WriteString("/") + } + path.WriteString("_simulate") + return opensearch.BuildRequest( + "POST", + path.String(), + r.Body, + r.Params.get(), + r.Header, + ) +} + +// IngestSimulateResp represents the returned struct of the index create response +type IngestSimulateResp struct { + Docs []json.RawMessage `json:"docs"` + response *opensearch.Response +} + +// Inspect returns the Inspect type containing the raw *opensearch.Reponse +func (r IngestSimulateResp) Inspect() Inspect { + return Inspect{Response: r.response} +} diff --git a/opensearchapi/api_ingest.go b/opensearchapi/api_ingest.go new file mode 100644 index 000000000..75233446a --- /dev/null +++ b/opensearchapi/api_ingest.go @@ -0,0 +1,86 @@ +// 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" +) + +type ingestClient struct { + apiClient *Client +} + +// Create executes a creade ingest request with the required IngestCreateReq +func (c ingestClient) Create(ctx context.Context, req IngestCreateReq) (*IngestCreateResp, error) { + var ( + data IngestCreateResp + err error + ) + if data.response, err = c.apiClient.do(ctx, req, &data); err != nil { + return &data, err + } + + return &data, nil +} + +// Delete executes a delete ingest request with the required IngestDeleteReq +func (c ingestClient) Delete(ctx context.Context, req IngestDeleteReq) (*IngestDeleteResp, error) { + var ( + data IngestDeleteResp + err error + ) + if data.response, err = c.apiClient.do(ctx, req, &data); err != nil { + return &data, err + } + + return &data, nil +} + +// Get executes a get ingest request with the optional IngestGetReq +func (c ingestClient) Get(ctx context.Context, req *IngestGetReq) (*IngestGetResp, error) { + if req == nil { + req = &IngestGetReq{} + } + + var ( + data IngestGetResp + err error + ) + if data.response, err = c.apiClient.do(ctx, req, &data.Pipelines); err != nil { + return &data, err + } + + return &data, nil +} + +// Simulate executes a stats ingest request with the optional IngestSimulateReq +func (c ingestClient) Simulate(ctx context.Context, req IngestSimulateReq) (*IngestSimulateResp, error) { + var ( + data IngestSimulateResp + err error + ) + if data.response, err = c.apiClient.do(ctx, req, &data); err != nil { + return &data, err + } + + return &data, nil +} diff --git a/opensearchapi/api_ingest_test.go b/opensearchapi/api_ingest_test.go new file mode 100644 index 000000000..ef038a3fd --- /dev/null +++ b/opensearchapi/api_ingest_test.go @@ -0,0 +1,178 @@ +// 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 ( + "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 TestIngestClient(t *testing.T) { + client, err := opensearchapi.NewDefaultClient() + require.Nil(t, err) + failingClient, err := osapitest.CreateFailingClient() + require.Nil(t, err) + + ingest := "ingest-test" + + type ingestTests struct { + Name string + Results func() (osapitest.Response, error) + } + + testCases := []struct { + Name string + Tests []ingestTests + }{ + { + Name: "Create", + Tests: []ingestTests{ + { + Name: "with request", + Results: func() (osapitest.Response, error) { + return client.Ingest.Create( + nil, + opensearchapi.IngestCreateReq{ + PipelineID: ingest, + Body: strings.NewReader(`{"description":"This pipeline processes student data","processors":[{"set":{"description":"Sets the graduation year to 2023","field":"grad_year","value":2023}},{"set":{"description":"Sets graduated to true","field":"graduated","value":true}}]}`), + }, + ) + }, + }, + { + Name: "inspect", + Results: func() (osapitest.Response, error) { + return failingClient.Ingest.Create(nil, opensearchapi.IngestCreateReq{}) + }, + }, + }, + }, + { + Name: "Get", + Tests: []ingestTests{ + { + Name: "with request", + Results: func() (osapitest.Response, error) { + return client.Ingest.Get(nil, &opensearchapi.IngestGetReq{PipelineIDs: []string{ingest}}) + }, + }, + { + Name: "inspect", + Results: func() (osapitest.Response, error) { + return failingClient.Ingest.Get(nil, nil) + }, + }, + }, + }, + { + Name: "Simulate", + Tests: []ingestTests{ + { + Name: "with request", + Results: func() (osapitest.Response, error) { + return client.Ingest.Simulate( + nil, + opensearchapi.IngestSimulateReq{ + PipelineID: ingest, + Body: strings.NewReader(`{"docs":[{"_index":"my-index","_id":"1","_source":{"grad_year":2024,"graduated":false,"name":"John Doe"}}]}`), + Params: opensearchapi.IngestSimulateParams{Verbose: opensearchapi.ToPointer(true), Pretty: true, Human: true, ErrorTrace: true}, + }, + ) + }, + }, + { + Name: "inspect", + Results: func() (osapitest.Response, error) { + return failingClient.Ingest.Simulate(nil, opensearchapi.IngestSimulateReq{}) + }, + }, + }, + }, + { + Name: "Delete", + Tests: []ingestTests{ + { + Name: "with request", + Results: func() (osapitest.Response, error) { + return client.Ingest.Delete(nil, opensearchapi.IngestDeleteReq{PipelineID: ingest}) + }, + }, + { + Name: "inspect", + Results: func() (osapitest.Response, error) { + return failingClient.Ingest.Delete(nil, opensearchapi.IngestDeleteReq{PipelineID: ingest}) + }, + }, + }, + }, + } + for _, value := range testCases { + t.Run(value.Name, func(t *testing.T) { + for _, testCase := range value.Tests { + t.Run(testCase.Name, func(t *testing.T) { + res, err := testCase.Results() + if testCase.Name == "inspect" { + assert.NotNil(t, err) + assert.NotNil(t, res) + osapitest.VerifyInspect(t, res.Inspect()) + } else { + require.Nil(t, err) + require.NotNil(t, res) + assert.NotNil(t, res.Inspect().Response) + if value.Name != "Get" { + osapitest.CompareRawJSONwithParsedJSON(t, res, res.Inspect().Response) + } + } + }) + } + }) + } + t.Run("ValidateResponse", func(t *testing.T) { + t.Run("Get", func(t *testing.T) { + t.Cleanup(func() { + failingClient.Ingest.Delete(nil, opensearchapi.IngestDeleteReq{PipelineID: ingest}) + }) + _, err := client.Ingest.Create( + nil, + opensearchapi.IngestCreateReq{ + PipelineID: ingest, + Body: strings.NewReader(`{"description":"This pipeline processes student data","processors":[{"set":{"description":"Sets the graduation year to 2023","field":"grad_year","value":2023}},{"set":{"description":"Sets graduated to true","field":"graduated","value":true}}]}`), + }, + ) + require.Nil(t, err) + + resp, err := client.Ingest.Get(nil, nil) + require.Nil(t, err) + require.NotNil(t, resp) + require.NotNil(t, resp.Inspect().Response) + osapitest.CompareRawJSONwithParsedJSON(t, resp.Pipelines, resp.Inspect().Response) + }) + }) +}