github.com/opensearch-project/opensearch-go/v2@v2.3.0/opensearchapi/api.reindex.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // 3 // The OpenSearch Contributors require contributions made to 4 // this file be licensed under the Apache-2.0 license or a 5 // compatible open source license. 6 // 7 // Modifications Copyright OpenSearch Contributors. See 8 // GitHub history for details. 9 10 // Licensed to Elasticsearch B.V. under one or more contributor 11 // license agreements. See the NOTICE file distributed with 12 // this work for additional information regarding copyright 13 // ownership. Elasticsearch B.V. licenses this file to you under 14 // the Apache License, Version 2.0 (the "License"); you may 15 // not use this file except in compliance with the License. 16 // You may obtain a copy of the License at 17 // 18 // http://www.apache.org/licenses/LICENSE-2.0 19 // 20 // Unless required by applicable law or agreed to in writing, 21 // software distributed under the License is distributed on an 22 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 23 // KIND, either express or implied. See the License for the 24 // specific language governing permissions and limitations 25 // under the License. 26 27 package opensearchapi 28 29 import ( 30 "context" 31 "fmt" 32 "io" 33 "net/http" 34 "strconv" 35 "strings" 36 "time" 37 ) 38 39 func newReindexFunc(t Transport) Reindex { 40 return func(body io.Reader, o ...func(*ReindexRequest)) (*Response, error) { 41 var r = ReindexRequest{Body: body} 42 for _, f := range o { 43 f(&r) 44 } 45 return r.Do(r.ctx, t) 46 } 47 } 48 49 // ----- API Definition ------------------------------------------------------- 50 51 // Reindex allows to copy documents from one index to another, optionally filtering the source 52 // documents by a query, changing the destination index settings, or fetching the 53 // documents from a remote cluster. 54 // 55 // 56 type Reindex func(body io.Reader, o ...func(*ReindexRequest)) (*Response, error) 57 58 // ReindexRequest configures the Reindex API request. 59 // 60 type ReindexRequest struct { 61 Body io.Reader 62 63 MaxDocs *int 64 Refresh *bool 65 RequestsPerSecond *int 66 Scroll time.Duration 67 Slices interface{} 68 Timeout time.Duration 69 WaitForActiveShards string 70 WaitForCompletion *bool 71 72 Pretty bool 73 Human bool 74 ErrorTrace bool 75 FilterPath []string 76 77 Header http.Header 78 79 ctx context.Context 80 } 81 82 // Do executes the request and returns response or error. 83 // 84 func (r ReindexRequest) Do(ctx context.Context, transport Transport) (*Response, error) { 85 var ( 86 method string 87 path strings.Builder 88 params map[string]string 89 ) 90 91 method = "POST" 92 93 path.Grow(len("/_reindex")) 94 path.WriteString("/_reindex") 95 96 params = make(map[string]string) 97 98 if r.MaxDocs != nil { 99 params["max_docs"] = strconv.FormatInt(int64(*r.MaxDocs), 10) 100 } 101 102 if r.Refresh != nil { 103 params["refresh"] = strconv.FormatBool(*r.Refresh) 104 } 105 106 if r.RequestsPerSecond != nil { 107 params["requests_per_second"] = strconv.FormatInt(int64(*r.RequestsPerSecond), 10) 108 } 109 110 if r.Scroll != 0 { 111 params["scroll"] = formatDuration(r.Scroll) 112 } 113 114 if r.Slices != nil { 115 params["slices"] = fmt.Sprintf("%v", r.Slices) 116 } 117 118 if r.Timeout != 0 { 119 params["timeout"] = formatDuration(r.Timeout) 120 } 121 122 if r.WaitForActiveShards != "" { 123 params["wait_for_active_shards"] = r.WaitForActiveShards 124 } 125 126 if r.WaitForCompletion != nil { 127 params["wait_for_completion"] = strconv.FormatBool(*r.WaitForCompletion) 128 } 129 130 if r.Pretty { 131 params["pretty"] = "true" 132 } 133 134 if r.Human { 135 params["human"] = "true" 136 } 137 138 if r.ErrorTrace { 139 params["error_trace"] = "true" 140 } 141 142 if len(r.FilterPath) > 0 { 143 params["filter_path"] = strings.Join(r.FilterPath, ",") 144 } 145 146 req, err := newRequest(method, path.String(), r.Body) 147 if err != nil { 148 return nil, err 149 } 150 151 if len(params) > 0 { 152 q := req.URL.Query() 153 for k, v := range params { 154 q.Set(k, v) 155 } 156 req.URL.RawQuery = q.Encode() 157 } 158 159 if r.Body != nil { 160 req.Header[headerContentType] = headerContentTypeJSON 161 } 162 163 if len(r.Header) > 0 { 164 if len(req.Header) == 0 { 165 req.Header = r.Header 166 } else { 167 for k, vv := range r.Header { 168 for _, v := range vv { 169 req.Header.Add(k, v) 170 } 171 } 172 } 173 } 174 175 if ctx != nil { 176 req = req.WithContext(ctx) 177 } 178 179 res, err := transport.Perform(req) 180 if err != nil { 181 return nil, err 182 } 183 184 response := Response{ 185 StatusCode: res.StatusCode, 186 Body: res.Body, 187 Header: res.Header, 188 } 189 190 return &response, nil 191 } 192 193 // WithContext sets the request context. 194 // 195 func (f Reindex) WithContext(v context.Context) func(*ReindexRequest) { 196 return func(r *ReindexRequest) { 197 r.ctx = v 198 } 199 } 200 201 // WithMaxDocs - maximum number of documents to process (default: all documents). 202 // 203 func (f Reindex) WithMaxDocs(v int) func(*ReindexRequest) { 204 return func(r *ReindexRequest) { 205 r.MaxDocs = &v 206 } 207 } 208 209 // WithRefresh - should the affected indexes be refreshed?. 210 // 211 func (f Reindex) WithRefresh(v bool) func(*ReindexRequest) { 212 return func(r *ReindexRequest) { 213 r.Refresh = &v 214 } 215 } 216 217 // WithRequestsPerSecond - the throttle to set on this request in sub-requests per second. -1 means no throttle.. 218 // 219 func (f Reindex) WithRequestsPerSecond(v int) func(*ReindexRequest) { 220 return func(r *ReindexRequest) { 221 r.RequestsPerSecond = &v 222 } 223 } 224 225 // WithScroll - control how long to keep the search context alive. 226 // 227 func (f Reindex) WithScroll(v time.Duration) func(*ReindexRequest) { 228 return func(r *ReindexRequest) { 229 r.Scroll = v 230 } 231 } 232 233 // WithSlices - the number of slices this task should be divided into. defaults to 1, meaning the task isn't sliced into subtasks. can be set to `auto`.. 234 // 235 func (f Reindex) WithSlices(v interface{}) func(*ReindexRequest) { 236 return func(r *ReindexRequest) { 237 r.Slices = v 238 } 239 } 240 241 // WithTimeout - time each individual bulk request should wait for shards that are unavailable.. 242 // 243 func (f Reindex) WithTimeout(v time.Duration) func(*ReindexRequest) { 244 return func(r *ReindexRequest) { 245 r.Timeout = v 246 } 247 } 248 249 // WithWaitForActiveShards - sets the number of shard copies that must be active before proceeding with the reindex operation. defaults to 1, meaning the primary shard only. set to `all` for all shard copies, otherwise set to any non-negative value less than or equal to the total number of copies for the shard (number of replicas + 1). 250 // 251 func (f Reindex) WithWaitForActiveShards(v string) func(*ReindexRequest) { 252 return func(r *ReindexRequest) { 253 r.WaitForActiveShards = v 254 } 255 } 256 257 // WithWaitForCompletion - should the request should block until the reindex is complete.. 258 // 259 func (f Reindex) WithWaitForCompletion(v bool) func(*ReindexRequest) { 260 return func(r *ReindexRequest) { 261 r.WaitForCompletion = &v 262 } 263 } 264 265 // WithPretty makes the response body pretty-printed. 266 // 267 func (f Reindex) WithPretty() func(*ReindexRequest) { 268 return func(r *ReindexRequest) { 269 r.Pretty = true 270 } 271 } 272 273 // WithHuman makes statistical values human-readable. 274 // 275 func (f Reindex) WithHuman() func(*ReindexRequest) { 276 return func(r *ReindexRequest) { 277 r.Human = true 278 } 279 } 280 281 // WithErrorTrace includes the stack trace for errors in the response body. 282 // 283 func (f Reindex) WithErrorTrace() func(*ReindexRequest) { 284 return func(r *ReindexRequest) { 285 r.ErrorTrace = true 286 } 287 } 288 289 // WithFilterPath filters the properties of the response body. 290 // 291 func (f Reindex) WithFilterPath(v ...string) func(*ReindexRequest) { 292 return func(r *ReindexRequest) { 293 r.FilterPath = v 294 } 295 } 296 297 // WithHeader adds the headers to the HTTP request. 298 // 299 func (f Reindex) WithHeader(h map[string]string) func(*ReindexRequest) { 300 return func(r *ReindexRequest) { 301 if r.Header == nil { 302 r.Header = make(http.Header) 303 } 304 for k, v := range h { 305 r.Header.Add(k, v) 306 } 307 } 308 } 309 310 // WithOpaqueID adds the X-Opaque-Id header to the HTTP request. 311 // 312 func (f Reindex) WithOpaqueID(s string) func(*ReindexRequest) { 313 return func(r *ReindexRequest) { 314 if r.Header == nil { 315 r.Header = make(http.Header) 316 } 317 r.Header.Set("X-Opaque-Id", s) 318 } 319 }