diff --git a/go.mod b/go.mod index 50fc03362269e108c9b8430c14ccf8b898cb93f7..396f9523a83cc2c97a652eef3c7d3c0900463ee6 100644 --- a/go.mod +++ b/go.mod @@ -4,4 +4,4 @@ go 1.11 // go: no requirements found in vendor/vendor.json -require github.com/olivere/elastic/v7 v7.0.19 +require github.com/olivere/elastic/v7 v7.0.22 diff --git a/go.sum b/go.sum index b29dfb560f77d6392be27b835bfbab8ab47a513f..5dc25b8cc64f964f1418137aadbb0989c800306b 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/aws/aws-sdk-go v1.33.5/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.35.20/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= @@ -14,11 +15,20 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8= github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/olivere/elastic/v7 v7.0.19 h1:w4F6JpqOISadhYf/n0NR1cNj73xHqh4pzPwD1Gkidts= github.com/olivere/elastic/v7 v7.0.19/go.mod h1:4Jqt5xvjqpjCqgnTcHwl3j8TLs8mvoOK8NYgo/qEOu4= +github.com/olivere/elastic/v7 v7.0.22 h1:esBA6JJwvYgfms0EVlH7Z+9J4oQ/WUADF2y/nCNDw7s= +github.com/olivere/elastic/v7 v7.0.22/go.mod h1:VDexNy9NjmtAkrjNoI7tImv7FR4tf5zUA3ickqu5Pc8= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -26,11 +36,13 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/gunit v1.3.4/go.mod h1:ZjM1ozSIMJlAz/ay4SG8PeKF00ckUp+zMHZXV9/bvak= +github.com/smartystreets/gunit v1.4.2/go.mod h1:ZjM1ozSIMJlAz/ay4SG8PeKF00ckUp+zMHZXV9/bvak= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -51,6 +63,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -65,4 +78,5 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/vendor/github.com/josharian/intern/README.md b/vendor/github.com/josharian/intern/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ffc44b219b2f80a46b6bceee25e04c223fce778e --- /dev/null +++ b/vendor/github.com/josharian/intern/README.md @@ -0,0 +1,5 @@ +Docs: https://godoc.org/github.com/josharian/intern + +See also [Go issue 5160](https://golang.org/issue/5160). + +License: MIT diff --git a/vendor/github.com/josharian/intern/go.mod b/vendor/github.com/josharian/intern/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..f2262ff0d54a98755c5ecb1db5547f6bbbb07636 --- /dev/null +++ b/vendor/github.com/josharian/intern/go.mod @@ -0,0 +1,3 @@ +module github.com/josharian/intern + +go 1.5 diff --git a/vendor/github.com/josharian/intern/intern.go b/vendor/github.com/josharian/intern/intern.go new file mode 100644 index 0000000000000000000000000000000000000000..7acb1fe90a11079e1340d28f17f12220f8c2bd2c --- /dev/null +++ b/vendor/github.com/josharian/intern/intern.go @@ -0,0 +1,44 @@ +// Package intern interns strings. +// Interning is best effort only. +// Interned strings may be removed automatically +// at any time without notification. +// All functions may be called concurrently +// with themselves and each other. +package intern + +import "sync" + +var ( + pool sync.Pool = sync.Pool{ + New: func() interface{} { + return make(map[string]string) + }, + } +) + +// String returns s, interned. +func String(s string) string { + m := pool.Get().(map[string]string) + c, ok := m[s] + if ok { + pool.Put(m) + return c + } + m[s] = s + pool.Put(m) + return s +} + +// Bytes returns b converted to a string, interned. +func Bytes(b []byte) string { + m := pool.Get().(map[string]string) + c, ok := m[string(b)] + if ok { + pool.Put(m) + return c + } + s := string(b) + m[s] = s + pool.Put(m) + return s +} diff --git a/vendor/github.com/josharian/intern/license.md b/vendor/github.com/josharian/intern/license.md new file mode 100644 index 0000000000000000000000000000000000000000..353d3055f0b4a23158e098fa0d66c2516f5341c7 --- /dev/null +++ b/vendor/github.com/josharian/intern/license.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Josh Bleecher Snyder + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mailru/easyjson/Makefile b/vendor/github.com/mailru/easyjson/Makefile index 80449f0d27490277f486bf715428ee3f6724847f..c5273407b8847e39958c9a0ae7098c2fc503a94c 100644 --- a/vendor/github.com/mailru/easyjson/Makefile +++ b/vendor/github.com/mailru/easyjson/Makefile @@ -20,22 +20,38 @@ generate: build ./tests/reference_to_pointer.go \ ./tests/html.go \ ./tests/unknown_fields.go \ - - bin/easyjson -all ./tests/data.go - bin/easyjson -all ./tests/nothing.go - bin/easyjson -all ./tests/errors.go - bin/easyjson -all ./tests/html.go + ./tests/type_declaration.go \ + ./tests/type_declaration_skip.go \ + ./tests/members_escaped.go \ + ./tests/members_unescaped.go \ + ./tests/intern.go \ + ./tests/nocopy.go \ + ./tests/escaping.go + bin/easyjson -all \ + ./tests/data.go \ + ./tests/nothing.go \ + ./tests/errors.go \ + ./tests/html.go \ + ./tests/type_declaration_skip.go + bin/easyjson \ + ./tests/nested_easy.go \ + ./tests/named_type.go \ + ./tests/custom_map_key_type.go \ + ./tests/embedded_type.go \ + ./tests/reference_to_pointer.go \ + ./tests/key_marshaler_map.go \ + ./tests/unknown_fields.go \ + ./tests/type_declaration.go \ + ./tests/members_escaped.go \ + ./tests/intern.go \ + ./tests/nocopy.go \ + ./tests/escaping.go \ + ./tests/nested_marshaler.go bin/easyjson -snake_case ./tests/snake.go bin/easyjson -omit_empty ./tests/omitempty.go - bin/easyjson -build_tags=use_easyjson ./benchmark/data.go - bin/easyjson ./tests/nested_easy.go - bin/easyjson ./tests/named_type.go - bin/easyjson ./tests/custom_map_key_type.go - bin/easyjson ./tests/embedded_type.go - bin/easyjson ./tests/reference_to_pointer.go - bin/easyjson ./tests/key_marshaler_map.go + bin/easyjson -build_tags=use_easyjson -disable_members_unescape ./benchmark/data.go bin/easyjson -disallow_unknown_fields ./tests/disallow_unknown.go - bin/easyjson ./tests/unknown_fields.go + bin/easyjson -disable_members_unescape ./tests/members_unescaped.go test: generate go test \ diff --git a/vendor/github.com/mailru/easyjson/README.md b/vendor/github.com/mailru/easyjson/README.md index 3bdcf2d06c235e314f53394793a5f85108d172a9..952575b9dec5742f0bacabe27c673a6b4b2f7097 100644 --- a/vendor/github.com/mailru/easyjson/README.md +++ b/vendor/github.com/mailru/easyjson/README.md @@ -34,7 +34,11 @@ Usage of easyjson: -all generate marshaler/unmarshalers for all structs in a file -build_tags string - build tags to add to generated file + build tags to add to generated file + -gen_build_flags string + build flags when running the generator while bootstrapping + -byte + use simple bytes instead of Base64Bytes for slice of bytes -leave_temps do not delete temporary files -no_std_marshalers @@ -55,10 +59,20 @@ Usage of easyjson: only generate stubs for marshaler/unmarshaler funcs -disallow_unknown_fields return error if some unknown field in json appeared + -disable_members_unescape + disable unescaping of \uXXXX string sequences in member names ``` Using `-all` will generate marshalers/unmarshalers for all Go structs in the -file. If `-all` is not provided, then only those structs whose preceding +file excluding those structs whose preceding comment starts with `easyjson:skip`. +For example: + +```go +//easyjson:skip +type A struct {} +``` + +If `-all` is not provided, then only those structs whose preceding comment starts with `easyjson:json` will have marshalers/unmarshalers generated. For example: @@ -76,10 +90,26 @@ Additional option notes: * `-build_tags` will add the specified build tags to generated Go sources. +* `-gen_build_flags` will execute the easyjson bootstapping code to launch the + actual generator command with provided flags. Multiple arguments should be + separated by space e.g. `-gen_build_flags="-mod=mod -x"`. + +## Structure json tag options + +Besides standart json tag options like 'omitempty' the following are supported: + +* 'nocopy' - disables allocation and copying of string values, making them + refer to original json buffer memory. This works great for short lived + objects which are not hold in memory after decoding and immediate usage. + Note if string requires unescaping it will be processed as normally. +* 'intern' - string "interning" (deduplication) to save memory when the very + same string dictionary values are often met all over the structure. + See below for more details. + ## Generated Marshaler/Unmarshaler Funcs For Go struct types, easyjson generates the funcs `MarshalEasyJSON` / -`UnmarshalEasyJSON` for marshaling/unmarshaling JSON. In turn, these satisify +`UnmarshalEasyJSON` for marshaling/unmarshaling JSON. In turn, these satisfy the `easyjson.Marshaler` and `easyjson.Unmarshaler` interfaces and when used in conjunction with `easyjson.Marshal` / `easyjson.Unmarshal` avoid unnecessary reflection / type assertions during marshaling/unmarshaling to/from JSON for Go @@ -102,17 +132,17 @@ utility funcs that are available. ## Controlling easyjson Marshaling and Unmarshaling Behavior Go types can provide their own `MarshalEasyJSON` and `UnmarshalEasyJSON` funcs -that satisify the `easyjson.Marshaler` / `easyjson.Unmarshaler` interfaces. +that satisfy the `easyjson.Marshaler` / `easyjson.Unmarshaler` interfaces. These will be used by `easyjson.Marshal` and `easyjson.Unmarshal` when defined for a Go type. -Go types can also satisify the `easyjson.Optional` interface, which allows the +Go types can also satisfy the `easyjson.Optional` interface, which allows the type to define its own `omitempty` logic. ## Type Wrappers easyjson provides additional type wrappers defined in the `easyjson/opt` -package. These wrap the standard Go primitives and in turn satisify the +package. These wrap the standard Go primitives and in turn satisfy the easyjson interfaces. The `easyjson/opt` type wrappers are useful when needing to distinguish between @@ -133,6 +163,27 @@ through a call to `buffer.Init()` prior to any marshaling or unmarshaling. Please see the [GoDoc listing](https://godoc.org/github.com/mailru/easyjson/buffer) for more information. +## String interning + +During unmarshaling, `string` field values can be optionally +[interned](https://en.wikipedia.org/wiki/String_interning) to reduce memory +allocations and usage by deduplicating strings in memory, at the expense of slightly +increased CPU usage. + +This will work effectively only for `string` fields being decoded that have frequently +the same value (e.g. if you have a string field that can only assume a small number +of possible values). + +To enable string interning, add the `intern` keyword tag to your `json` tag on `string` +fields, e.g.: + +```go +type Foo struct { + UUID string `json:"uuid"` // will not be interned during unmarshaling + State string `json:"state,intern"` // will be interned during unmarshaling +} +``` + ## Issues, Notes, and Limitations * easyjson is still early in its development. As such, there are likely to be @@ -174,7 +225,7 @@ for more information. needs to be known prior to sending the data. Currently this is not possible with easyjson's architecture. -* easyjson parser and codegen based on reflection, so it wont works on `package main` +* easyjson parser and codegen based on reflection, so it won't work on `package main` files, because they cant be imported by parser. ## Benchmarks @@ -239,7 +290,7 @@ since the memory is not freed between marshaling operations. ### easyjson vs 'ujson' python module [ujson](https://github.com/esnme/ultrajson) is using C code for parsing, so it -is interesting to see how plain golang compares to that. It is imporant to note +is interesting to see how plain golang compares to that. It is important to note that the resulting object for python is slower to access, since the library parses JSON object into dictionaries. diff --git a/vendor/github.com/mailru/easyjson/buffer/pool.go b/vendor/github.com/mailru/easyjson/buffer/pool.go index 07fb4bc1f7bf89f753b648e62239a4824176c481..598a54af9dbfc2194ab5233fd3b6be24d4bcc755 100644 --- a/vendor/github.com/mailru/easyjson/buffer/pool.go +++ b/vendor/github.com/mailru/easyjson/buffer/pool.go @@ -4,6 +4,7 @@ package buffer import ( "io" + "net" "sync" ) @@ -52,14 +53,12 @@ func putBuf(buf []byte) { // getBuf gets a chunk from reuse pool or creates a new one if reuse failed. func getBuf(size int) []byte { - if size < config.PooledSize { - return make([]byte, 0, size) - } - - if c := buffers[size]; c != nil { - v := c.Get() - if v != nil { - return v.([]byte) + if size >= config.PooledSize { + if c := buffers[size]; c != nil { + v := c.Get() + if v != nil { + return v.([]byte) + } } } return make([]byte, 0, size) @@ -78,9 +77,12 @@ type Buffer struct { // EnsureSpace makes sure that the current chunk contains at least s free bytes, // possibly creating a new chunk. func (b *Buffer) EnsureSpace(s int) { - if cap(b.Buf)-len(b.Buf) >= s { - return + if cap(b.Buf)-len(b.Buf) < s { + b.ensureSpaceSlow(s) } +} + +func (b *Buffer) ensureSpaceSlow(s int) { l := len(b.Buf) if l > 0 { if cap(b.toPool) != cap(b.Buf) { @@ -105,18 +107,22 @@ func (b *Buffer) EnsureSpace(s int) { // AppendByte appends a single byte to buffer. func (b *Buffer) AppendByte(data byte) { - if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined. - b.EnsureSpace(1) - } + b.EnsureSpace(1) b.Buf = append(b.Buf, data) } // AppendBytes appends a byte slice to buffer. func (b *Buffer) AppendBytes(data []byte) { + if len(data) <= cap(b.Buf)-len(b.Buf) { + b.Buf = append(b.Buf, data...) // fast path + } else { + b.appendBytesSlow(data) + } +} + +func (b *Buffer) appendBytesSlow(data []byte) { for len(data) > 0 { - if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined. - b.EnsureSpace(1) - } + b.EnsureSpace(1) sz := cap(b.Buf) - len(b.Buf) if sz > len(data) { @@ -128,12 +134,18 @@ func (b *Buffer) AppendBytes(data []byte) { } } -// AppendBytes appends a string to buffer. +// AppendString appends a string to buffer. func (b *Buffer) AppendString(data string) { + if len(data) <= cap(b.Buf)-len(b.Buf) { + b.Buf = append(b.Buf, data...) // fast path + } else { + b.appendStringSlow(data) + } +} + +func (b *Buffer) appendStringSlow(data string) { for len(data) > 0 { - if cap(b.Buf) == len(b.Buf) { // EnsureSpace won't be inlined. - b.EnsureSpace(1) - } + b.EnsureSpace(1) sz := cap(b.Buf) - len(b.Buf) if sz > len(data) { @@ -156,18 +168,14 @@ func (b *Buffer) Size() int { // DumpTo outputs the contents of a buffer to a writer and resets the buffer. func (b *Buffer) DumpTo(w io.Writer) (written int, err error) { - var n int - for _, buf := range b.bufs { - if err == nil { - n, err = w.Write(buf) - written += n - } - putBuf(buf) + bufs := net.Buffers(b.bufs) + if len(b.Buf) > 0 { + bufs = append(bufs, b.Buf) } + n, err := bufs.WriteTo(w) - if err == nil { - n, err = w.Write(b.Buf) - written += n + for _, buf := range b.bufs { + putBuf(buf) } putBuf(b.toPool) @@ -175,7 +183,7 @@ func (b *Buffer) DumpTo(w io.Writer) (written int, err error) { b.Buf = nil b.toPool = nil - return + return int(n), err } // BuildBytes creates a single byte slice with all the contents of the buffer. Data is @@ -192,7 +200,7 @@ func (b *Buffer) BuildBytes(reuse ...[]byte) []byte { var ret []byte size := b.Size() - // If we got a buffer as argument and it is big enought, reuse it. + // If we got a buffer as argument and it is big enough, reuse it. if len(reuse) == 1 && cap(reuse[0]) >= size { ret = reuse[0][:0] } else { diff --git a/vendor/github.com/mailru/easyjson/go.mod b/vendor/github.com/mailru/easyjson/go.mod index 7bc4a65844252b0d4f58515a62053d5d932b5f64..f4945d347d345378d7b357cbd4075419649719d1 100644 --- a/vendor/github.com/mailru/easyjson/go.mod +++ b/vendor/github.com/mailru/easyjson/go.mod @@ -1,3 +1,5 @@ module github.com/mailru/easyjson go 1.12 + +require github.com/josharian/intern v1.0.0 diff --git a/vendor/github.com/mailru/easyjson/go.sum b/vendor/github.com/mailru/easyjson/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..cb47297b6bdbecc1819e7968c3cb023340a3ed2b --- /dev/null +++ b/vendor/github.com/mailru/easyjson/go.sum @@ -0,0 +1,2 @@ +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= diff --git a/vendor/github.com/mailru/easyjson/helpers.go b/vendor/github.com/mailru/easyjson/helpers.go index 04ac63562870ada757af51d28a1af4b5c80c7cfa..78dacb1b7b9c1becb1fd4faa9cb9fd315ddfa494 100644 --- a/vendor/github.com/mailru/easyjson/helpers.go +++ b/vendor/github.com/mailru/easyjson/helpers.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "net/http" "strconv" + "unsafe" "github.com/mailru/easyjson/jlexer" "github.com/mailru/easyjson/jwriter" @@ -21,6 +22,12 @@ type Unmarshaler interface { UnmarshalEasyJSON(w *jlexer.Lexer) } +// MarshalerUnmarshaler is an easyjson-compatible marshaler/unmarshaler interface. +type MarshalerUnmarshaler interface { + Marshaler + Unmarshaler +} + // Optional defines an undefined-test method for a type to integrate with 'omitempty' logic. type Optional interface { IsDefined() bool @@ -36,9 +43,17 @@ type UnknownsMarshaler interface { MarshalUnknowns(w *jwriter.Writer, first bool) } +func isNilInterface(i interface{}) bool { + return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0 +} + // Marshal returns data as a single byte slice. Method is suboptimal as the data is likely to be copied // from a chain of smaller chunks. func Marshal(v Marshaler) ([]byte, error) { + if isNilInterface(v) { + return nullBytes, nil + } + w := jwriter.Writer{} v.MarshalEasyJSON(&w) return w.BuildBytes() @@ -46,6 +61,10 @@ func Marshal(v Marshaler) ([]byte, error) { // MarshalToWriter marshals the data to an io.Writer. func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) { + if isNilInterface(v) { + return w.Write(nullBytes) + } + jw := jwriter.Writer{} v.MarshalEasyJSON(&jw) return jw.DumpTo(w) @@ -56,6 +75,13 @@ func MarshalToWriter(v Marshaler, w io.Writer) (written int, err error) { // false if an error occurred before any http.ResponseWriter methods were actually // invoked (in this case a 500 reply is possible). func MarshalToHTTPResponseWriter(v Marshaler, w http.ResponseWriter) (started bool, written int, err error) { + if isNilInterface(v) { + w.Header().Set("Content-Type", "application/json") + w.Header().Set("Content-Length", strconv.Itoa(len(nullBytes))) + written, err = w.Write(nullBytes) + return true, written, err + } + jw := jwriter.Writer{} v.MarshalEasyJSON(&jw) if jw.Error != nil { diff --git a/vendor/github.com/mailru/easyjson/jlexer/lexer.go b/vendor/github.com/mailru/easyjson/jlexer/lexer.go index ddd376b844cb5711ab86105e208d6dc4f9029983..a42e9d65ad79d809ed084336d76c11ac78635082 100644 --- a/vendor/github.com/mailru/easyjson/jlexer/lexer.go +++ b/vendor/github.com/mailru/easyjson/jlexer/lexer.go @@ -5,6 +5,7 @@ package jlexer import ( + "bytes" "encoding/base64" "encoding/json" "errors" @@ -14,6 +15,8 @@ import ( "unicode" "unicode/utf16" "unicode/utf8" + + "github.com/josharian/intern" ) // tokenKind determines type of a token. @@ -32,9 +35,10 @@ const ( type token struct { kind tokenKind // Type of a token. - boolValue bool // Value if a boolean literal token. - byteValue []byte // Raw value of a token. - delimValue byte + boolValue bool // Value if a boolean literal token. + byteValueCloned bool // true if byteValue was allocated and does not refer to original json body + byteValue []byte // Raw value of a token. + delimValue byte } // Lexer is a JSON lexer: it iterates over JSON tokens in a byte slice. @@ -240,23 +244,65 @@ func (r *Lexer) fetchNumber() { // findStringLen tries to scan into the string literal for ending quote char to determine required size. // The size will be exact if no escapes are present and may be inexact if there are escaped chars. -func findStringLen(data []byte) (isValid, hasEscapes bool, length int) { - delta := 0 - - for i := 0; i < len(data); i++ { - switch data[i] { - case '\\': - i++ - delta++ - if i < len(data) && data[i] == 'u' { - delta++ - } - case '"': - return true, (delta > 0), (i - delta) +func findStringLen(data []byte) (isValid bool, length int) { + for { + idx := bytes.IndexByte(data, '"') + if idx == -1 { + return false, len(data) + } + if idx == 0 || (idx > 0 && data[idx-1] != '\\') { + return true, length + idx + } + + // count \\\\\\\ sequences. even number of slashes means quote is not really escaped + cnt := 1 + for idx-cnt-1 >= 0 && data[idx-cnt-1] == '\\' { + cnt++ + } + if cnt%2 == 0 { + return true, length + idx + } + + length += idx + 1 + data = data[idx+1:] + } +} + +// unescapeStringToken performs unescaping of string token. +// if no escaping is needed, original string is returned, otherwise - a new one allocated +func (r *Lexer) unescapeStringToken() (err error) { + data := r.token.byteValue + var unescapedData []byte + + for { + i := bytes.IndexByte(data, '\\') + if i == -1 { + break + } + + escapedRune, escapedBytes, err := decodeEscape(data[i:]) + if err != nil { + r.errParse(err.Error()) + return err } + + if unescapedData == nil { + unescapedData = make([]byte, 0, len(r.token.byteValue)) + } + + var d [4]byte + s := utf8.EncodeRune(d[:], escapedRune) + unescapedData = append(unescapedData, data[:i]...) + unescapedData = append(unescapedData, d[:s]...) + + data = data[i+escapedBytes:] } - return false, false, len(data) + if unescapedData != nil { + r.token.byteValue = append(unescapedData, data...) + r.token.byteValueCloned = true + } + return } // getu4 decodes \uXXXX from the beginning of s, returning the hex value, @@ -286,36 +332,30 @@ func getu4(s []byte) rune { return val } -// processEscape processes a single escape sequence and returns number of bytes processed. -func (r *Lexer) processEscape(data []byte) (int, error) { +// decodeEscape processes a single escape sequence and returns number of bytes processed. +func decodeEscape(data []byte) (decoded rune, bytesProcessed int, err error) { if len(data) < 2 { - return 0, fmt.Errorf("syntax error at %v", string(data)) + return 0, 0, errors.New("incorrect escape symbol \\ at the end of token") } c := data[1] switch c { case '"', '/', '\\': - r.token.byteValue = append(r.token.byteValue, c) - return 2, nil + return rune(c), 2, nil case 'b': - r.token.byteValue = append(r.token.byteValue, '\b') - return 2, nil + return '\b', 2, nil case 'f': - r.token.byteValue = append(r.token.byteValue, '\f') - return 2, nil + return '\f', 2, nil case 'n': - r.token.byteValue = append(r.token.byteValue, '\n') - return 2, nil + return '\n', 2, nil case 'r': - r.token.byteValue = append(r.token.byteValue, '\r') - return 2, nil + return '\r', 2, nil case 't': - r.token.byteValue = append(r.token.byteValue, '\t') - return 2, nil + return '\t', 2, nil case 'u': rr := getu4(data) if rr < 0 { - return 0, errors.New("syntax error") + return 0, 0, errors.New("incorrectly escaped \\uXXXX sequence") } read := 6 @@ -328,13 +368,10 @@ func (r *Lexer) processEscape(data []byte) (int, error) { rr = unicode.ReplacementChar } } - var d [4]byte - s := utf8.EncodeRune(d[:], rr) - r.token.byteValue = append(r.token.byteValue, d[:s]...) - return read, nil + return rr, read, nil } - return 0, errors.New("syntax error") + return 0, 0, errors.New("incorrectly escaped bytes") } // fetchString scans a string literal token. @@ -342,43 +379,14 @@ func (r *Lexer) fetchString() { r.pos++ data := r.Data[r.pos:] - isValid, hasEscapes, length := findStringLen(data) + isValid, length := findStringLen(data) if !isValid { r.pos += length r.errParse("unterminated string literal") return } - if !hasEscapes { - r.token.byteValue = data[:length] - r.pos += length + 1 - return - } - - r.token.byteValue = make([]byte, 0, length) - p := 0 - for i := 0; i < len(data); { - switch data[i] { - case '"': - r.pos += i + 1 - r.token.byteValue = append(r.token.byteValue, data[p:i]...) - i++ - return - - case '\\': - r.token.byteValue = append(r.token.byteValue, data[p:i]...) - off, err := r.processEscape(data[i:]) - if err != nil { - r.errParse(err.Error()) - return - } - i += off - p = i - - default: - i++ - } - } - r.errParse("unterminated string literal") + r.token.byteValue = data[:length] + r.pos += length + 1 // skip closing '"' as well } // scanToken scans the next token if no token is currently available in the lexer. @@ -602,7 +610,7 @@ func (r *Lexer) Consumed() { } } -func (r *Lexer) unsafeString() (string, []byte) { +func (r *Lexer) unsafeString(skipUnescape bool) (string, []byte) { if r.token.kind == tokenUndef && r.Ok() { r.FetchToken() } @@ -610,6 +618,13 @@ func (r *Lexer) unsafeString() (string, []byte) { r.errInvalidToken("string") return "", nil } + if !skipUnescape { + if err := r.unescapeStringToken(); err != nil { + r.errInvalidToken("string") + return "", nil + } + } + bytes := r.token.byteValue ret := bytesToStr(r.token.byteValue) r.consume() @@ -621,13 +636,19 @@ func (r *Lexer) unsafeString() (string, []byte) { // Warning: returned string may point to the input buffer, so the string should not outlive // the input buffer. Intended pattern of usage is as an argument to a switch statement. func (r *Lexer) UnsafeString() string { - ret, _ := r.unsafeString() + ret, _ := r.unsafeString(false) return ret } // UnsafeBytes returns the byte slice if the token is a string literal. func (r *Lexer) UnsafeBytes() []byte { - _, ret := r.unsafeString() + _, ret := r.unsafeString(false) + return ret +} + +// UnsafeFieldName returns current member name string token +func (r *Lexer) UnsafeFieldName(skipUnescape bool) string { + ret, _ := r.unsafeString(skipUnescape) return ret } @@ -640,7 +661,34 @@ func (r *Lexer) String() string { r.errInvalidToken("string") return "" } - ret := string(r.token.byteValue) + if err := r.unescapeStringToken(); err != nil { + r.errInvalidToken("string") + return "" + } + var ret string + if r.token.byteValueCloned { + ret = bytesToStr(r.token.byteValue) + } else { + ret = string(r.token.byteValue) + } + r.consume() + return ret +} + +// StringIntern reads a string literal, and performs string interning on it. +func (r *Lexer) StringIntern() string { + if r.token.kind == tokenUndef && r.Ok() { + r.FetchToken() + } + if !r.Ok() || r.token.kind != tokenString { + r.errInvalidToken("string") + return "" + } + if err := r.unescapeStringToken(); err != nil { + r.errInvalidToken("string") + return "" + } + ret := intern.Bytes(r.token.byteValue) r.consume() return ret } @@ -839,7 +887,7 @@ func (r *Lexer) Int() int { } func (r *Lexer) Uint8Str() uint8 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -856,7 +904,7 @@ func (r *Lexer) Uint8Str() uint8 { } func (r *Lexer) Uint16Str() uint16 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -873,7 +921,7 @@ func (r *Lexer) Uint16Str() uint16 { } func (r *Lexer) Uint32Str() uint32 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -890,7 +938,7 @@ func (r *Lexer) Uint32Str() uint32 { } func (r *Lexer) Uint64Str() uint64 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -915,7 +963,7 @@ func (r *Lexer) UintptrStr() uintptr { } func (r *Lexer) Int8Str() int8 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -932,7 +980,7 @@ func (r *Lexer) Int8Str() int8 { } func (r *Lexer) Int16Str() int16 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -949,7 +997,7 @@ func (r *Lexer) Int16Str() int16 { } func (r *Lexer) Int32Str() int32 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -966,7 +1014,7 @@ func (r *Lexer) Int32Str() int32 { } func (r *Lexer) Int64Str() int64 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -1004,7 +1052,7 @@ func (r *Lexer) Float32() float32 { } func (r *Lexer) Float32Str() float32 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } @@ -1037,7 +1085,7 @@ func (r *Lexer) Float64() float64 { } func (r *Lexer) Float64Str() float64 { - s, b := r.unsafeString() + s, b := r.unsafeString(false) if !r.Ok() { return 0 } diff --git a/vendor/github.com/mailru/easyjson/jwriter/writer.go b/vendor/github.com/mailru/easyjson/jwriter/writer.go index eb8547ccc27a30118a049a054afc7e79f95cf378..2c5b20105bb90926e780775bb341c9dff1cc2689 100644 --- a/vendor/github.com/mailru/easyjson/jwriter/writer.go +++ b/vendor/github.com/mailru/easyjson/jwriter/writer.go @@ -297,11 +297,9 @@ func (w *Writer) String(s string) { p := 0 // last non-escape symbol - var escapeTable [128]bool + escapeTable := &htmlEscapeTable if w.NoEscapeHTML { - escapeTable = htmlNoEscapeTable - } else { - escapeTable = htmlEscapeTable + escapeTable = &htmlNoEscapeTable } for i := 0; i < len(s); { diff --git a/vendor/github.com/mailru/easyjson/unknown_fields.go b/vendor/github.com/mailru/easyjson/unknown_fields.go index 6cfdf8300ba06423d4a868f5c1b284babce09a19..55538eac99d6fbf97ea225b808a5d052155c88a5 100644 --- a/vendor/github.com/mailru/easyjson/unknown_fields.go +++ b/vendor/github.com/mailru/easyjson/unknown_fields.go @@ -1,8 +1,6 @@ package easyjson import ( - json "encoding/json" - jlexer "github.com/mailru/easyjson/jlexer" "github.com/mailru/easyjson/jwriter" ) @@ -10,14 +8,14 @@ import ( // UnknownFieldsProxy implemets UnknownsUnmarshaler and UnknownsMarshaler // use it as embedded field in your structure to parse and then serialize unknown struct fields type UnknownFieldsProxy struct { - unknownFields map[string]interface{} + unknownFields map[string][]byte } func (s *UnknownFieldsProxy) UnmarshalUnknown(in *jlexer.Lexer, key string) { if s.unknownFields == nil { - s.unknownFields = make(map[string]interface{}, 1) + s.unknownFields = make(map[string][]byte, 1) } - s.unknownFields[key] = in.Interface() + s.unknownFields[key] = in.Raw() } func (s UnknownFieldsProxy) MarshalUnknowns(out *jwriter.Writer, first bool) { @@ -29,6 +27,6 @@ func (s UnknownFieldsProxy) MarshalUnknowns(out *jwriter.Writer, first bool) { } out.String(string(key)) out.RawByte(':') - out.Raw(json.Marshal(val)) + out.Raw(val, nil) } } diff --git a/vendor/github.com/olivere/elastic/v7/CONTRIBUTORS b/vendor/github.com/olivere/elastic/v7/CONTRIBUTORS index dc1aa32d58301ba64db262581ef0f20171e58b5c..8028e21f956337e7c3dbd8b0fe6946f8f124ff78 100644 --- a/vendor/github.com/olivere/elastic/v7/CONTRIBUTORS +++ b/vendor/github.com/olivere/elastic/v7/CONTRIBUTORS @@ -63,6 +63,7 @@ Daniel Heckrath [@DanielHeckrath](https://github.com/DanielHeckrath) Daniel Imfeld [@dimfeld](https://github.com/dimfeld) Daniel Santos [@danlsgiga](https://github.com/danlsgiga) David Emanuel Buchmann [@wuurrd](https://github.com/wuurrd) +Devin Christensen [@quixoten](https://github.com/quixoten) diacone [@diacone](https://github.com/diacone) Diego Becciolini [@itizir](https://github.com/itizir) Dwayne Schultz [@myshkin5](https://github.com/myshkin5) @@ -88,6 +89,7 @@ Guillaume J. Charmes [@creack](https://github.com/creack) Guiseppe [@gm42](https://github.com/gm42) Han Yu [@MoonighT](https://github.com/MoonighT) Harmen [@alicebob](https://github.com/alicebob) +Haroldo Vélez [@Haroldov](https://github.com/Haroldov) Harrison Wright [@wright8191](https://github.com/wright8191) Henry Clifford [@hcliff](https://github.com/hcliff) Henry Stern [@hstern](https://github.com/hstern) @@ -148,6 +150,7 @@ navins [@ishare](https://github.com/ishare) Naoya Tsutsumi [@tutuming](https://github.com/tutuming) Nathan Lacey [@nlacey](https://github.com/nlacey) NeoCN [@NeoCN](https://github.com/NeoCN) +Nguyen Xuan Dung [@dungnx](https://github.com/dungnx) Nicholas Wolff [@nwolff](https://github.com/nwolff) Nick K [@utrack](https://github.com/utrack) Nick Whyte [@nickw444](https://github.com/nickw444) @@ -160,6 +163,7 @@ Pedro [@otherview](https://github.com/otherview) Pete C [@peteclark-ft](https://github.com/peteclark-ft) Peter Nagy [@nagypeterjob](https://github.com/nagypeterjob) Paolo [@ppiccolo](https://github.com/ppiccolo) +Phillip Baker [@phillbaker](https://github.com/phillbaker) Igor Panychek [@panychek](https://github.com/panychek) Radoslaw Wesolowski [@r--w](https://github.com/r--w) Rafał Gałus [@rgalus](https://github.com/rgalus) diff --git a/vendor/github.com/olivere/elastic/v7/Makefile b/vendor/github.com/olivere/elastic/v7/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7cd04a8133521cbb9e36c4f73b487554f2860065 --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/Makefile @@ -0,0 +1,3 @@ +.PHONY: test +test: + go test -race -deprecations -strict-decoder -v . ./aws/... ./config/... ./trace/... ./uritemplates/... diff --git a/vendor/github.com/olivere/elastic/v7/client.go b/vendor/github.com/olivere/elastic/v7/client.go index ca87aca67a9eca1187b1ec091fb00c0c08b09d57..38a93faa3a752fef75a6575544aeb2dd89d5d8e6 100644 --- a/vendor/github.com/olivere/elastic/v7/client.go +++ b/vendor/github.com/olivere/elastic/v7/client.go @@ -25,7 +25,7 @@ import ( const ( // Version is the current version of Elastic. - Version = "7.0.19" + Version = "7.0.22" // DefaultURL is the default endpoint of Elasticsearch on the local machine. // It is used e.g. when initializing a new Client without a specific URL. @@ -145,6 +145,7 @@ type Client struct { gzipEnabled bool // gzip compression enabled or disabled (default) requiredPlugins []string // list of required plugins retrier Retrier // strategy for retries + retryStatusCodes []int // HTTP status codes where to retry automatically (with retrier) headers http.Header // a list of default headers to add to each request } @@ -247,6 +248,7 @@ func NewSimpleClient(options ...ClientOptionFunc) (*Client, error) { sendGetBodyAs: DefaultSendGetBodyAs, gzipEnabled: DefaultGzipEnabled, retrier: noRetries, // no retries by default + retryStatusCodes: nil, // no automatic retries for specific HTTP status codes deprecationlog: noDeprecationLog, } @@ -332,6 +334,7 @@ func DialContext(ctx context.Context, options ...ClientOptionFunc) (*Client, err sendGetBodyAs: DefaultSendGetBodyAs, gzipEnabled: DefaultGzipEnabled, retrier: noRetries, // no retries by default + retryStatusCodes: nil, // no automatic retries for specific HTTP status codes deprecationlog: noDeprecationLog, } @@ -726,6 +729,17 @@ func SetRetrier(retrier Retrier) ClientOptionFunc { } } +// SetRetryStatusCodes specifies the HTTP status codes where the client +// will retry automatically. Notice that retries call the specified retrier, +// so calling SetRetryStatusCodes without setting a Retrier won't do anything +// for retries. +func SetRetryStatusCodes(statusCodes ...int) ClientOptionFunc { + return func(c *Client) error { + c.retryStatusCodes = statusCodes + return nil + } +} + // SetHeaders adds a list of default HTTP headers that will be added to // each requests executed by PerformRequest. func SetHeaders(headers http.Header) ClientOptionFunc { @@ -1262,15 +1276,16 @@ func (c *Client) mustActiveConn() error { // PerformRequestOptions must be passed into PerformRequest. type PerformRequestOptions struct { - Method string - Path string - Params url.Values - Body interface{} - ContentType string - IgnoreErrors []int - Retrier Retrier - Headers http.Header - MaxResponseSize int64 + Method string + Path string + Params url.Values + Body interface{} + ContentType string + IgnoreErrors []int + Retrier Retrier + RetryStatusCodes []int + Headers http.Header + MaxResponseSize int64 } // PerformRequest does a HTTP request to Elasticsearch. @@ -1294,9 +1309,23 @@ func (c *Client) PerformRequest(ctx context.Context, opt PerformRequestOptions) if opt.Retrier != nil { retrier = opt.Retrier } + retryStatusCodes := c.retryStatusCodes + if opt.RetryStatusCodes != nil { + retryStatusCodes = opt.RetryStatusCodes + } defaultHeaders := c.headers c.mu.RUnlock() + // retry returns true if statusCode indicates the request is to be retried + retry := func(statusCode int) bool { + for _, code := range retryStatusCodes { + if code == statusCode { + return true + } + } + return false + } + var err error var conn *conn var req *Request @@ -1404,6 +1433,21 @@ func (c *Client) PerformRequest(ctx context.Context, opt PerformRequestOptions) time.Sleep(wait) continue // try again } + if retry(res.StatusCode) { + n++ + wait, ok, rerr := retrier.Retry(ctx, n, (*http.Request)(req), res, err) + if rerr != nil { + c.errorf("elastic: %s is dead", conn.URL()) + conn.MarkAsDead() + return nil, rerr + } + if ok { + // retry + retried = true + time.Sleep(wait) + continue // try again + } + } defer res.Body.Close() // Tracing @@ -1698,30 +1742,82 @@ func (c *Client) Aliases() *AliasesService { return NewAliasesService(c) } -// IndexGetTemplate gets an index template. -// Use XXXTemplate funcs to manage search templates. +// -- Legacy templates -- + +// IndexGetTemplate gets an index template (v1/legacy version before 7.8). +// +// This service implements the legacy version of index templates as described +// in https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html. +// +// See e.g. IndexPutIndexTemplate and IndexPutComponentTemplate for the new version(s). func (c *Client) IndexGetTemplate(names ...string) *IndicesGetTemplateService { return NewIndicesGetTemplateService(c).Name(names...) } -// IndexTemplateExists gets check if an index template exists. -// Use XXXTemplate funcs to manage search templates. +// IndexTemplateExists gets check if an index template exists (v1/legacy version before 7.8). +// +// This service implements the legacy version of index templates as described +// in https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html. +// +// See e.g. IndexPutIndexTemplate and IndexPutComponentTemplate for the new version(s). func (c *Client) IndexTemplateExists(name string) *IndicesExistsTemplateService { return NewIndicesExistsTemplateService(c).Name(name) } -// IndexPutTemplate creates or updates an index template. -// Use XXXTemplate funcs to manage search templates. +// IndexPutTemplate creates or updates an index template (v1/legacy version before 7.8). +// +// This service implements the legacy version of index templates as described +// in https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html. +// +// See e.g. IndexPutIndexTemplate and IndexPutComponentTemplate for the new version(s). func (c *Client) IndexPutTemplate(name string) *IndicesPutTemplateService { return NewIndicesPutTemplateService(c).Name(name) } -// IndexDeleteTemplate deletes an index template. -// Use XXXTemplate funcs to manage search templates. +// IndexDeleteTemplate deletes an index template (v1/legacy version before 7.8). +// +// This service implements the legacy version of index templates as described +// in https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html. +// +// See e.g. IndexPutIndexTemplate and IndexPutComponentTemplate for the new version(s). func (c *Client) IndexDeleteTemplate(name string) *IndicesDeleteTemplateService { return NewIndicesDeleteTemplateService(c).Name(name) } +// -- Index templates -- + +// IndexPutIndexTemplate creates or updates an index template (new version after 7.8). +// +// This service implements the new version of index templates as described +// on https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-put-template.html. +// +// See e.g. IndexPutTemplate for the v1/legacy version. +func (c *Client) IndexPutIndexTemplate(name string) *IndicesPutIndexTemplateService { + return NewIndicesPutIndexTemplateService(c).Name(name) +} + +// IndexGetIndexTemplate returns an index template (new version after 7.8). +// +// This service implements the new version of index templates as described +// on https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-get-template.html. +// +// See e.g. IndexPutTemplate for the v1/legacy version. +func (c *Client) IndexGetIndexTemplate(name string) *IndicesGetIndexTemplateService { + return NewIndicesGetIndexTemplateService(c).Name(name) +} + +// IndexDeleteIndexTemplate deletes an index template (new version after 7.8). +// +// This service implements the new version of index templates as described +// on https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-delete-template.html. +// +// See e.g. IndexPutTemplate for the v1/legacy version. +func (c *Client) IndexDeleteIndexTemplate(name string) *IndicesDeleteIndexTemplateService { + return NewIndicesDeleteIndexTemplateService(c).Name(name) +} + +// -- TODO Component templates -- + // GetMapping gets a mapping. func (c *Client) GetMapping() *IndicesGetMappingService { return NewIndicesGetMappingService(c) @@ -1930,6 +2026,23 @@ func (c *Client) XPackInfo() *XPackInfoService { return NewXPackInfoService(c) } +// -- X-Pack Async Search -- + +// XPackAsyncSearchSubmit starts an asynchronous search. +func (c *Client) XPackAsyncSearchSubmit() *XPackAsyncSearchSubmit { + return NewXPackAsyncSearchSubmit(c) +} + +// XPackAsyncSearchGet retrieves the outcome of an asynchronous search. +func (c *Client) XPackAsyncSearchGet() *XPackAsyncSearchGet { + return NewXPackAsyncSearchGet(c) +} + +// XPackAsyncSearchDelete deletes an asynchronous search. +func (c *Client) XPackAsyncSearchDelete() *XPackAsyncSearchDelete { + return NewXPackAsyncSearchDelete(c) +} + // -- X-Pack Index Lifecycle Management -- // XPackIlmPutLifecycle adds or modifies an ilm policy. diff --git a/vendor/github.com/olivere/elastic/v7/count.go b/vendor/github.com/olivere/elastic/v7/count.go index d1c75be166fa54b51ecf8c706932a5a62100c22f..ad4cd084661a726a051177ad5987515581bfd199 100644 --- a/vendor/github.com/olivere/elastic/v7/count.go +++ b/vendor/github.com/olivere/elastic/v7/count.go @@ -35,6 +35,7 @@ type CountService struct { df string expandWildcards string ignoreUnavailable *bool + ignoreThrottled *bool lenient *bool lowercaseExpandedTerms *bool minScore interface{} @@ -163,6 +164,13 @@ func (s *CountService) IgnoreUnavailable(ignoreUnavailable bool) *CountService { return s } +// IgnoreThrottled indicates whether specified concrete, expanded or aliased +// indices should be ignored when throttled. +func (s *CountService) IgnoreThrottled(ignoreThrottled bool) *CountService { + s.ignoreThrottled = &ignoreThrottled + return s +} + // Lenient specifies whether format-based query failures (such as // providing text to a numeric field) should be ignored. func (s *CountService) Lenient(lenient bool) *CountService { @@ -291,6 +299,9 @@ func (s *CountService) buildURL() (string, url.Values, error) { if s.ignoreUnavailable != nil { params.Set("ignore_unavailable", fmt.Sprintf("%v", *s.ignoreUnavailable)) } + if s.ignoreThrottled != nil { + params.Set("ignore_throttled", fmt.Sprintf("%v", *s.ignoreThrottled)) + } if s.lenient != nil { params.Set("lenient", fmt.Sprintf("%v", *s.lenient)) } diff --git a/vendor/github.com/olivere/elastic/v7/docker-compose.yml b/vendor/github.com/olivere/elastic/v7/docker-compose.yml index d57e758e4fa1a603ec39f76bacab10e63d3cfac8..1adc197d0027ed3aae685c3cf5e54fba15ea249e 100644 --- a/vendor/github.com/olivere/elastic/v7/docker-compose.yml +++ b/vendor/github.com/olivere/elastic/v7/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.8.0 + image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.9.3 hostname: elasticsearch environment: - cluster.name=elasticsearch @@ -28,13 +28,12 @@ services: ports: - 9200:9200 platinum: - image: docker.elastic.co/elasticsearch/elasticsearch:7.8.0 + image: docker.elastic.co/elasticsearch/elasticsearch:7.9.3 hostname: elasticsearch-platinum environment: - cluster.name=platinum - bootstrap.memory_lock=true - discovery.type=single-node - - xpack.ilm.enabled=true - xpack.license.self_generated.type=trial - xpack.security.enabled=true - xpack.watcher.enabled=true diff --git a/vendor/github.com/olivere/elastic/v7/errors.go b/vendor/github.com/olivere/elastic/v7/errors.go index e9fd286ba9dab6af97aaaf224940fdf25c95227d..ee11f0b3f32458985315608cfc328788bd2ba6d2 100644 --- a/vendor/github.com/olivere/elastic/v7/errors.go +++ b/vendor/github.com/olivere/elastic/v7/errors.go @@ -107,6 +107,20 @@ func (e *Error) Error() string { return fmt.Sprintf("elastic: Error %d (%s)", e.Status, http.StatusText(e.Status)) } +// ErrorReason returns the reason of an error that Elasticsearch reported, +// if err is of kind Error and has ErrorDetails with a Reason. Any other +// value of err will return an empty string. +func ErrorReason(err error) string { + if err == nil { + return "" + } + e, ok := err.(*Error) + if !ok || e == nil || e.Details == nil { + return "" + } + return e.Details.Reason +} + // IsContextErr returns true if the error is from a context that was canceled or deadline exceeded func IsContextErr(err error) bool { if err == context.Canceled || err == context.DeadlineExceeded { diff --git a/vendor/github.com/olivere/elastic/v7/go.mod b/vendor/github.com/olivere/elastic/v7/go.mod index 636beaf2992028a07124b51b32f30f0b48000867..1aae642e74963539324258bba4125a4388454f0c 100644 --- a/vendor/github.com/olivere/elastic/v7/go.mod +++ b/vendor/github.com/olivere/elastic/v7/go.mod @@ -3,14 +3,16 @@ module github.com/olivere/elastic/v7 go 1.14 require ( - github.com/aws/aws-sdk-go v1.33.5 + github.com/aws/aws-sdk-go v1.35.20 github.com/fortytw2/leaktest v1.3.0 - github.com/google/go-cmp v0.5.0 - github.com/mailru/easyjson v0.7.1 + github.com/go-sql-driver/mysql v1.5.0 // indirect + github.com/google/go-cmp v0.5.2 + github.com/mailru/easyjson v0.7.6 github.com/opentracing/opentracing-go v1.2.0 github.com/pkg/errors v0.9.1 github.com/smartystreets/assertions v1.1.1 // indirect github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 - github.com/smartystreets/gunit v1.3.4 // indirect - go.opencensus.io v0.22.4 + github.com/smartystreets/gunit v1.4.2 // indirect + github.com/stretchr/testify v1.5.1 // indirect + go.opencensus.io v0.22.5 ) diff --git a/vendor/github.com/olivere/elastic/v7/indices_delete_index_template.go b/vendor/github.com/olivere/elastic/v7/indices_delete_index_template.go new file mode 100644 index 0000000000000000000000000000000000000000..1e7d22b0bcc4e9fa26a7961b00ada4935cbc551b --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/indices_delete_index_template.go @@ -0,0 +1,186 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/olivere/elastic/v7/uritemplates" +) + +// IndicesDeleteIndexTemplateService deletes index templates. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the new version (7.8 or later). If you want +// the old version, please use the IndicesDeleteTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-delete-template.html +// for more details. +type IndicesDeleteIndexTemplateService struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + name string + timeout string + masterTimeout string +} + +// NewIndicesDeleteIndexTemplateService creates a new IndicesDeleteIndexTemplateService. +func NewIndicesDeleteIndexTemplateService(client *Client) *IndicesDeleteIndexTemplateService { + return &IndicesDeleteIndexTemplateService{ + client: client, + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *IndicesDeleteIndexTemplateService) Pretty(pretty bool) *IndicesDeleteIndexTemplateService { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *IndicesDeleteIndexTemplateService) Human(human bool) *IndicesDeleteIndexTemplateService { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *IndicesDeleteIndexTemplateService) ErrorTrace(errorTrace bool) *IndicesDeleteIndexTemplateService { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *IndicesDeleteIndexTemplateService) FilterPath(filterPath ...string) *IndicesDeleteIndexTemplateService { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *IndicesDeleteIndexTemplateService) Header(name string, value string) *IndicesDeleteIndexTemplateService { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *IndicesDeleteIndexTemplateService) Headers(headers http.Header) *IndicesDeleteIndexTemplateService { + s.headers = headers + return s +} + +// Name is the name of the template. +func (s *IndicesDeleteIndexTemplateService) Name(name string) *IndicesDeleteIndexTemplateService { + s.name = name + return s +} + +// Timeout is an explicit operation timeout. +func (s *IndicesDeleteIndexTemplateService) Timeout(timeout string) *IndicesDeleteIndexTemplateService { + s.timeout = timeout + return s +} + +// MasterTimeout specifies the timeout for connection to master. +func (s *IndicesDeleteIndexTemplateService) MasterTimeout(masterTimeout string) *IndicesDeleteIndexTemplateService { + s.masterTimeout = masterTimeout + return s +} + +// buildURL builds the URL for the operation. +func (s *IndicesDeleteIndexTemplateService) buildURL() (string, url.Values, error) { + // Build URL + path, err := uritemplates.Expand("/_index_template/{name}", map[string]string{ + "name": s.name, + }) + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.timeout != "" { + params.Set("timeout", s.timeout) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *IndicesDeleteIndexTemplateService) Validate() error { + var invalid []string + if s.name == "" { + invalid = append(invalid, "Name") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *IndicesDeleteIndexTemplateService) Do(ctx context.Context) (*IndicesDeleteIndexTemplateResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "DELETE", + Path: path, + Params: params, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(IndicesDeleteIndexTemplateResponse) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// IndicesDeleteIndexTemplateResponse is the response of IndicesDeleteIndexTemplateService.Do. +type IndicesDeleteIndexTemplateResponse struct { + Acknowledged bool `json:"acknowledged"` + ShardsAcknowledged bool `json:"shards_acknowledged"` + Index string `json:"index,omitempty"` +} diff --git a/vendor/github.com/olivere/elastic/v7/indices_delete_template.go b/vendor/github.com/olivere/elastic/v7/indices_delete_template.go index e1ed3e68aa36216331f3f9f5cae4e8eec469a2a1..7dd5506046f36b1a9d0c89b15c1346b475c46374 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_delete_template.go +++ b/vendor/github.com/olivere/elastic/v7/indices_delete_template.go @@ -14,8 +14,14 @@ import ( "github.com/olivere/elastic/v7/uritemplates" ) -// IndicesDeleteTemplateService deletes index templates. -// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices-templates.html. +// IndicesDeleteTemplateService deletes templates. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the legacy version (7.7 or lower). If you want +// the new version, please use the IndicesDeleteIndexTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-delete-template-v1.html +// for more details. type IndicesDeleteTemplateService struct { client *Client diff --git a/vendor/github.com/olivere/elastic/v7/indices_exists_template.go b/vendor/github.com/olivere/elastic/v7/indices_exists_template.go index c5c9bbdc5b0eaa91858569761e58c5935e31b532..53f29fea6971e84fb665f38b006f62d475ae7c7e 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_exists_template.go +++ b/vendor/github.com/olivere/elastic/v7/indices_exists_template.go @@ -26,8 +26,9 @@ type IndicesExistsTemplateService struct { filterPath []string // list of filters used to reduce the response headers http.Header // custom request-level HTTP headers - name string - local *bool + name string + local *bool + masterTimeout string } // NewIndicesExistsTemplateService creates a new IndicesExistsTemplateService. @@ -90,6 +91,12 @@ func (s *IndicesExistsTemplateService) Local(local bool) *IndicesExistsTemplateS return s } +// MasterTimeout specifies the timeout for connection to master. +func (s *IndicesExistsTemplateService) MasterTimeout(masterTimeout string) *IndicesExistsTemplateService { + s.masterTimeout = masterTimeout + return s +} + // buildURL builds the URL for the operation. func (s *IndicesExistsTemplateService) buildURL() (string, url.Values, error) { // Build URL @@ -115,7 +122,10 @@ func (s *IndicesExistsTemplateService) buildURL() (string, url.Values, error) { params.Set("filter_path", strings.Join(s.filterPath, ",")) } if s.local != nil { - params.Set("local", fmt.Sprintf("%v", *s.local)) + params.Set("local", fmt.Sprint(*s.local)) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) } return path, params, nil } diff --git a/vendor/github.com/olivere/elastic/v7/indices_flush_synced.go b/vendor/github.com/olivere/elastic/v7/indices_flush_synced.go index 140ae62e2b79a49d1a8cb5ab5c0c8009a2f3b2f5..f0123273ee9962453f45a1fc7b8f5baeaf051395 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_flush_synced.go +++ b/vendor/github.com/olivere/elastic/v7/indices_flush_synced.go @@ -159,6 +159,9 @@ func (s *IndicesSyncedFlushService) Validate() error { } // Do executes the service. +// +// Deprecated: Synced flush is deprecated and will be removed in 8.0. +// Use flush at _/flush or /{index}/_flush instead. func (s *IndicesSyncedFlushService) Do(ctx context.Context) (*IndicesSyncedFlushResponse, error) { // Check pre-conditions if err := s.Validate(); err != nil { diff --git a/vendor/github.com/olivere/elastic/v7/indices_get_index_template.go b/vendor/github.com/olivere/elastic/v7/indices_get_index_template.go new file mode 100644 index 0000000000000000000000000000000000000000..0c3baef23589f8966e2faf61889a545054dc992d --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/indices_get_index_template.go @@ -0,0 +1,214 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/olivere/elastic/v7/uritemplates" +) + +// IndicesGetIndexTemplateService returns an index template. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the new version (7.8 or later). If you want +// the old version, please use the IndicesGetTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-get-template.html +// for more details. +type IndicesGetIndexTemplateService struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + name []string + masterTimeout string + flatSettings *bool + local *bool +} + +// NewIndicesGetIndexTemplateService creates a new IndicesGetIndexTemplateService. +func NewIndicesGetIndexTemplateService(client *Client) *IndicesGetIndexTemplateService { + return &IndicesGetIndexTemplateService{ + client: client, + name: make([]string, 0), + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *IndicesGetIndexTemplateService) Pretty(pretty bool) *IndicesGetIndexTemplateService { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *IndicesGetIndexTemplateService) Human(human bool) *IndicesGetIndexTemplateService { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *IndicesGetIndexTemplateService) ErrorTrace(errorTrace bool) *IndicesGetIndexTemplateService { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *IndicesGetIndexTemplateService) FilterPath(filterPath ...string) *IndicesGetIndexTemplateService { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *IndicesGetIndexTemplateService) Header(name string, value string) *IndicesGetIndexTemplateService { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *IndicesGetIndexTemplateService) Headers(headers http.Header) *IndicesGetIndexTemplateService { + s.headers = headers + return s +} + +// Name is the name of the index template. +func (s *IndicesGetIndexTemplateService) Name(name ...string) *IndicesGetIndexTemplateService { + s.name = append(s.name, name...) + return s +} + +// FlatSettings is returns settings in flat format (default: false). +func (s *IndicesGetIndexTemplateService) FlatSettings(flatSettings bool) *IndicesGetIndexTemplateService { + s.flatSettings = &flatSettings + return s +} + +// Local indicates whether to return local information, i.e. do not retrieve +// the state from master node (default: false). +func (s *IndicesGetIndexTemplateService) Local(local bool) *IndicesGetIndexTemplateService { + s.local = &local + return s +} + +// MasterTimeout specifies the timeout for connection to master. +func (s *IndicesGetIndexTemplateService) MasterTimeout(masterTimeout string) *IndicesGetIndexTemplateService { + s.masterTimeout = masterTimeout + return s +} + +// buildURL builds the URL for the operation. +func (s *IndicesGetIndexTemplateService) buildURL() (string, url.Values, error) { + // Build URL + var err error + var path string + if len(s.name) > 0 { + path, err = uritemplates.Expand("/_index_template/{name}", map[string]string{ + "name": strings.Join(s.name, ","), + }) + } else { + path = "/_template" + } + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.flatSettings != nil { + params.Set("flat_settings", fmt.Sprintf("%v", *s.flatSettings)) + } + if s.local != nil { + params.Set("local", fmt.Sprintf("%v", *s.local)) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *IndicesGetIndexTemplateService) Validate() error { + return nil +} + +// Do executes the operation. +func (s *IndicesGetIndexTemplateService) Do(ctx context.Context) (*IndicesGetIndexTemplateResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "GET", + Path: path, + Params: params, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + var ret *IndicesGetIndexTemplateResponse + if err := s.client.decoder.Decode(res.Body, &ret); err != nil { + return nil, err + } + return ret, nil +} + +// IndicesGetIndexTemplateResponse is the response of IndicesGetIndexTemplateService.Do. +type IndicesGetIndexTemplateResponse struct { + IndexTemplates []IndicesGetIndexTemplates `json:"index_templates"` +} + +type IndicesGetIndexTemplates struct { + Name string `json:"name"` + IndexTemplate *IndicesGetIndexTemplate `json:"index_template"` +} + +type IndicesGetIndexTemplate struct { + IndexPatterns []string `json:"index_patterns,omitempty"` + ComposedOf []string `json:"composed_of,omitempty"` + Priority int `json:"priority,omitempty"` + Version int `json:"version,omitempty"` + Template *IndicesGetIndexTemplateData `json:"template,omitempty"` +} + +type IndicesGetIndexTemplateData struct { + Settings map[string]interface{} `json:"settings,omitempty"` + Mappings map[string]interface{} `json:"mappings,omitempty"` + Aliases map[string]interface{} `json:"aliases,omitempty"` +} diff --git a/vendor/github.com/olivere/elastic/v7/indices_get_template.go b/vendor/github.com/olivere/elastic/v7/indices_get_template.go index aeafe9128eb0bebb82fc3fc04c8e2f8bd14023af..28bb4a0e5c8f5ee9452e7cf63c153fc69d894e87 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_get_template.go +++ b/vendor/github.com/olivere/elastic/v7/indices_get_template.go @@ -14,8 +14,14 @@ import ( "github.com/olivere/elastic/v7/uritemplates" ) -// IndicesGetTemplateService returns an index template. -// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices-templates.html. +// IndicesGetTemplateService returns an index template (v1). +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the legacy version (7.7 or lower). If you want +// the new version, please use the IndicesGetIndexTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-get-template-v1.html +// for more details. type IndicesGetTemplateService struct { client *Client diff --git a/vendor/github.com/olivere/elastic/v7/indices_put_index_template.go b/vendor/github.com/olivere/elastic/v7/indices_put_index_template.go new file mode 100644 index 0000000000000000000000000000000000000000..fb77657891d54b99533e7d02186c1e983c6b6371 --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/indices_put_index_template.go @@ -0,0 +1,226 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" + + "github.com/olivere/elastic/v7/uritemplates" +) + +// IndicesPutIndexTemplateService creates or updates index templates. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the new version (7.8 or higher) for managing +// index templates. If you want the v1/legacy version, please see e.g. +// IndicesPutTemplateService and friends. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-put-template.html +// for more details on this API. +type IndicesPutIndexTemplateService struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + name string + create *bool + cause string + masterTimeout string + + bodyJson interface{} + bodyString string +} + +// NewIndicesPutIndexTemplateService creates a new IndicesPutIndexTemplateService. +func NewIndicesPutIndexTemplateService(client *Client) *IndicesPutIndexTemplateService { + return &IndicesPutIndexTemplateService{ + client: client, + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *IndicesPutIndexTemplateService) Pretty(pretty bool) *IndicesPutIndexTemplateService { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *IndicesPutIndexTemplateService) Human(human bool) *IndicesPutIndexTemplateService { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *IndicesPutIndexTemplateService) ErrorTrace(errorTrace bool) *IndicesPutIndexTemplateService { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *IndicesPutIndexTemplateService) FilterPath(filterPath ...string) *IndicesPutIndexTemplateService { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *IndicesPutIndexTemplateService) Header(name string, value string) *IndicesPutIndexTemplateService { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *IndicesPutIndexTemplateService) Headers(headers http.Header) *IndicesPutIndexTemplateService { + s.headers = headers + return s +} + +// Name is the name of the index template. +func (s *IndicesPutIndexTemplateService) Name(name string) *IndicesPutIndexTemplateService { + s.name = name + return s +} + +// Create indicates whether the index template should only be added if +// new or can also replace an existing one. +func (s *IndicesPutIndexTemplateService) Create(create bool) *IndicesPutIndexTemplateService { + s.create = &create + return s +} + +// Cause is the user-defined reason for creating/updating the the index template. +func (s *IndicesPutIndexTemplateService) Cause(cause string) *IndicesPutIndexTemplateService { + s.cause = cause + return s +} + +// MasterTimeout specifies the timeout for connection to master. +func (s *IndicesPutIndexTemplateService) MasterTimeout(masterTimeout string) *IndicesPutIndexTemplateService { + s.masterTimeout = masterTimeout + return s +} + +// BodyJson is the index template definition as a JSON serializable +// type, e.g. map[string]interface{}. +func (s *IndicesPutIndexTemplateService) BodyJson(body interface{}) *IndicesPutIndexTemplateService { + s.bodyJson = body + return s +} + +// BodyString is the index template definition as a raw string. +func (s *IndicesPutIndexTemplateService) BodyString(body string) *IndicesPutIndexTemplateService { + s.bodyString = body + return s +} + +// buildURL builds the URL for the operation. +func (s *IndicesPutIndexTemplateService) buildURL() (string, url.Values, error) { + // Build URL + path, err := uritemplates.Expand("/_index_template/{name}", map[string]string{ + "name": s.name, + }) + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.create != nil { + params.Set("create", fmt.Sprint(*s.create)) + } + if s.cause != "" { + params.Set("cause", s.cause) + } + if s.masterTimeout != "" { + params.Set("master_timeout", s.masterTimeout) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *IndicesPutIndexTemplateService) Validate() error { + var invalid []string + if s.name == "" { + invalid = append(invalid, "Name") + } + if s.bodyString == "" && s.bodyJson == nil { + invalid = append(invalid, "BodyJson") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *IndicesPutIndexTemplateService) Do(ctx context.Context) (*IndicesPutIndexTemplateResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Setup HTTP request body + var body interface{} + if s.bodyJson != nil { + body = s.bodyJson + } else { + body = s.bodyString + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "PUT", + Path: path, + Params: params, + Body: body, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(IndicesPutIndexTemplateResponse) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// IndicesPutIndexTemplateResponse is the response of IndicesPutIndexTemplateService.Do. +type IndicesPutIndexTemplateResponse struct { + Acknowledged bool `json:"acknowledged"` + ShardsAcknowledged bool `json:"shards_acknowledged"` + Index string `json:"index,omitempty"` +} diff --git a/vendor/github.com/olivere/elastic/v7/indices_put_template.go b/vendor/github.com/olivere/elastic/v7/indices_put_template.go index 4ced8e8f496a0f216cc5ce202ed9d7b7edd5ba0a..bafa81ed91bc739a36613ff40f6ccf68080368d3 100644 --- a/vendor/github.com/olivere/elastic/v7/indices_put_template.go +++ b/vendor/github.com/olivere/elastic/v7/indices_put_template.go @@ -14,8 +14,14 @@ import ( "github.com/olivere/elastic/v7/uritemplates" ) -// IndicesPutTemplateService creates or updates index mappings. -// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices-templates.html. +// IndicesPutTemplateService creates or updates templates. +// +// Index templates have changed during in 7.8 update of Elasticsearch. +// This service implements the legacy version (7.7 or lower). If you want +// the new version, please use the IndicesPutIndexTemplateService. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.9/indices-templates-v1.html +// for more details. type IndicesPutTemplateService struct { client *Client diff --git a/vendor/github.com/olivere/elastic/v7/inner_hit.go b/vendor/github.com/olivere/elastic/v7/inner_hit.go index 803662646c48d1df35c8a52015964c50294c548a..2dbcbad1aa81796a87d98a877990a4e0367957da 100644 --- a/vendor/github.com/olivere/elastic/v7/inner_hit.go +++ b/vendor/github.com/olivere/elastic/v7/inner_hit.go @@ -41,6 +41,11 @@ func (hit *InnerHit) Query(query Query) *InnerHit { return hit } +func (hit *InnerHit) Collapse(collapse *CollapseBuilder) *InnerHit { + hit.source.Collapse(collapse) + return hit +} + func (hit *InnerHit) From(from int) *InnerHit { hit.source.From(from) return hit diff --git a/vendor/github.com/olivere/elastic/v7/run-es.sh b/vendor/github.com/olivere/elastic/v7/run-es.sh deleted file mode 100644 index 8b60fbc95d76d4c007814682da64b2167f4e3649..0000000000000000000000000000000000000000 --- a/vendor/github.com/olivere/elastic/v7/run-es.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -VERSION=${VERSION:=6.4.0} -docker run --rm -p 9200:9200 -e "http.host=0.0.0.0" -e "transport.host=127.0.0.1" -e "bootstrap.memory_lock=true" -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" docker.elastic.co/elasticsearch/elasticsearch-oss:$VERSION elasticsearch -Enetwork.host=_local_,_site_ -Enetwork.publish_host=_local_ diff --git a/vendor/github.com/olivere/elastic/v7/run-tests.sh b/vendor/github.com/olivere/elastic/v7/run-tests.sh deleted file mode 100644 index 1204ad367aac96bc34bdbc42bfc10334d5cdaeba..0000000000000000000000000000000000000000 --- a/vendor/github.com/olivere/elastic/v7/run-tests.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -go test . ./aws/... ./config/... ./trace/... ./uritemplates/... diff --git a/vendor/github.com/olivere/elastic/v7/scroll.go b/vendor/github.com/olivere/elastic/v7/scroll.go index 1d43203d212c80b00a167c28f5a3ebd35b8f9949..92c859e3f9a60c13b99b7ca3e16f4bd36fa8097d 100644 --- a/vendor/github.com/olivere/elastic/v7/scroll.go +++ b/vendor/github.com/olivere/elastic/v7/scroll.go @@ -32,18 +32,20 @@ type ScrollService struct { filterPath []string // list of filters used to reduce the response headers http.Header // custom request-level HTTP headers - indices []string - types []string - keepAlive string - body interface{} - ss *SearchSource - size *int - routing string - preference string - ignoreUnavailable *bool - allowNoIndices *bool - expandWildcards string - maxResponseSize int64 + indices []string + types []string + keepAlive string + body interface{} + ss *SearchSource + size *int + routing string + preference string + ignoreUnavailable *bool + ignoreThrottled *bool + allowNoIndices *bool + expandWildcards string + maxResponseSize int64 + restTotalHitsAsInt *bool mu sync.RWMutex scrollId string @@ -248,6 +250,13 @@ func (s *ScrollService) TrackTotalHits(trackTotalHits interface{}) *ScrollServic return s } +// RestTotalHitsAsInt indicates whether hits.total should be rendered as an +// integer or an object in the rest search response. +func (s *ScrollService) RestTotalHitsAsInt(enabled bool) *ScrollService { + s.restTotalHitsAsInt = &enabled + return s +} + // Routing is a list of specific routing values to control the shards // the search will be executed on. func (s *ScrollService) Routing(routings ...string) *ScrollService { @@ -272,6 +281,13 @@ func (s *ScrollService) IgnoreUnavailable(ignoreUnavailable bool) *ScrollService return s } +// IgnoreThrottled indicates whether specified concrete, expanded or aliased +// indices should be ignored when throttled. +func (s *ScrollService) IgnoreThrottled(ignoreThrottled bool) *ScrollService { + s.ignoreThrottled = &ignoreThrottled + return s +} + // AllowNoIndices indicates whether to ignore if a wildcard indices // expression resolves into no concrete indices. (This includes `_all` string // or when no indices have been specified). @@ -294,7 +310,6 @@ func (s *ScrollService) MaxResponseSize(maxResponseSize int64) *ScrollService { return s } - // NoStoredFields indicates that no stored fields should be loaded, resulting in only // id and type to be returned per field. func (s *ScrollService) NoStoredFields() *ScrollService { @@ -497,6 +512,12 @@ func (s *ScrollService) buildFirstURL() (string, url.Values, error) { if s.ignoreUnavailable != nil { params.Set("ignore_unavailable", fmt.Sprintf("%v", *s.ignoreUnavailable)) } + if s.ignoreThrottled != nil { + params.Set("ignore_throttled", fmt.Sprintf("%v", *s.ignoreThrottled)) + } + if v := s.restTotalHitsAsInt; v != nil { + params.Set("rest_total_hits_as_int", fmt.Sprint(*v)) + } return path, params, nil } @@ -597,6 +618,9 @@ func (s *ScrollService) buildNextURL() (string, url.Values, error) { } params.Set("filter_path", strings.Join(s.filterPath, ",")) } + if v := s.restTotalHitsAsInt; v != nil { + params.Set("rest_total_hits_as_int", fmt.Sprint(*v)) + } return path, params, nil } diff --git a/vendor/github.com/olivere/elastic/v7/search_queries_multi_match.go b/vendor/github.com/olivere/elastic/v7/search_queries_multi_match.go index ff1e2869f31987c874fe4d6655df7761925d77d2..afcd121614d2fdf507d184ae71634a679d79e299 100644 --- a/vendor/github.com/olivere/elastic/v7/search_queries_multi_match.go +++ b/vendor/github.com/olivere/elastic/v7/search_queries_multi_match.go @@ -61,40 +61,19 @@ func (q *MultiMatchQuery) FieldWithBoost(field string, boost float64) *MultiMatc // Type can be "best_fields", "boolean", "most_fields", "cross_fields", // "phrase", "phrase_prefix" or "bool_prefix" func (q *MultiMatchQuery) Type(typ string) *MultiMatchQuery { - var zero = float64(0.0) - var one = float64(1.0) - switch strings.ToLower(typ) { default: // best_fields / boolean q.typ = "best_fields" - if q.tieBreaker == nil { - q.tieBreaker = &zero - } case "most_fields": q.typ = "most_fields" - if q.tieBreaker == nil { - q.tieBreaker = &one - } case "cross_fields": q.typ = "cross_fields" - if q.tieBreaker == nil { - q.tieBreaker = &zero - } case "phrase": q.typ = "phrase" - if q.tieBreaker == nil { - q.tieBreaker = &zero - } case "phrase_prefix": q.typ = "phrase_prefix" - if q.tieBreaker == nil { - q.tieBreaker = &zero - } case "bool_prefix": q.typ = "bool_prefix" - if q.tieBreaker == nil { - q.tieBreaker = &zero - } } return q } diff --git a/vendor/github.com/olivere/elastic/v7/search_queries_pinned.go b/vendor/github.com/olivere/elastic/v7/search_queries_pinned.go new file mode 100644 index 0000000000000000000000000000000000000000..9fc3601e7cdcb2c4b59328c8009590b6f3c82192 --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/search_queries_pinned.go @@ -0,0 +1,61 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +// PinnedQuery is a query that promotes selected documents to rank higher than those matching a given query. +// +// For more details, see: +// https://www.elastic.co/guide/en/elasticsearch/reference/7.8/query-dsl-pinned-query.html +type PinnedQuery struct { + ids []string + organic Query +} + +// NewPinnedQuery creates and initializes a new pinned query. +func NewPinnedQuery() *PinnedQuery { + return &PinnedQuery{} +} + +// Ids sets an array of document IDs listed in the order they are to appear in results. +func (q *PinnedQuery) Ids(ids ...string) *PinnedQuery { + q.ids = ids + return q +} + +// Organic sets a choice of query used to rank documents which will be ranked below the "pinned" document ids. +func (q *PinnedQuery) Organic(query Query) *PinnedQuery { + q.organic = query + return q +} + +// Source returns the JSON serializable content for this query. +func (q *PinnedQuery) Source() (interface{}, error) { + // { + // "pinned": { + // "ids": [ "1", "4", "100" ], + // "organic": { + // "match": { + // "description": "iphone" + // } + // } + // } + // } + + query := make(map[string]interface{}) + params := make(map[string]interface{}) + query["pinned"] = params + if len(q.ids) > 0 { + params["ids"] = q.ids + } + if q.organic != nil { + src, err := q.organic.Source() + if err != nil { + return nil, err + } + params["organic"] = src + } + + return query, nil +} diff --git a/vendor/github.com/olivere/elastic/v7/xpack_async_search_delete.go b/vendor/github.com/olivere/elastic/v7/xpack_async_search_delete.go new file mode 100644 index 0000000000000000000000000000000000000000..0c323440ddcccc523e1a6daa2cd14e0f7f43a8c4 --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/xpack_async_search_delete.go @@ -0,0 +1,154 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" +) + +// XPackAsyncSearchDelete allows removing an asynchronous search result, +// previously being started with XPackAsyncSearchSubmit service. +// +// For more details, see the documentation at +// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/async-search.html +type XPackAsyncSearchDelete struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + // ID of asynchronous search as returned by XPackAsyncSearchSubmit.Do. + id string +} + +// NewXPackAsyncSearchDelete creates a new XPackAsyncSearchDelete. +func NewXPackAsyncSearchDelete(client *Client) *XPackAsyncSearchDelete { + return &XPackAsyncSearchDelete{ + client: client, + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *XPackAsyncSearchDelete) Pretty(pretty bool) *XPackAsyncSearchDelete { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *XPackAsyncSearchDelete) Human(human bool) *XPackAsyncSearchDelete { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *XPackAsyncSearchDelete) ErrorTrace(errorTrace bool) *XPackAsyncSearchDelete { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *XPackAsyncSearchDelete) FilterPath(filterPath ...string) *XPackAsyncSearchDelete { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *XPackAsyncSearchDelete) Header(name string, value string) *XPackAsyncSearchDelete { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *XPackAsyncSearchDelete) Headers(headers http.Header) *XPackAsyncSearchDelete { + s.headers = headers + return s +} + +// ID of the asynchronous search. +func (s *XPackAsyncSearchDelete) ID(id string) *XPackAsyncSearchDelete { + s.id = id + return s +} + +// buildURL builds the URL for the operation. +func (s *XPackAsyncSearchDelete) buildURL() (string, url.Values, error) { + path := fmt.Sprintf("/_async_search/%s", url.PathEscape(s.id)) + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *XPackAsyncSearchDelete) Validate() error { + var invalid []string + if s.id == "" { + invalid = append(invalid, "ID") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *XPackAsyncSearchDelete) Do(ctx context.Context) (*XPackAsyncSearchDeleteResponse, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "DELETE", + Path: path, + Params: params, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(XPackAsyncSearchDeleteResponse) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + return nil, err + } + return ret, nil +} + +// XPackAsyncSearchDeleteResponse is the outcome of calling XPackAsyncSearchDelete.Do. +type XPackAsyncSearchDeleteResponse struct { + Acknowledged bool `json:"acknowledged"` +} diff --git a/vendor/github.com/olivere/elastic/v7/xpack_async_search_get.go b/vendor/github.com/olivere/elastic/v7/xpack_async_search_get.go new file mode 100644 index 0000000000000000000000000000000000000000..d39d49268c51d0a5c1cda99cfb6342a0c5bb99c4 --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/xpack_async_search_get.go @@ -0,0 +1,178 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strings" +) + +// XPackAsyncSearchGet allows retrieving an asynchronous search result, +// previously being started with XPackAsyncSearchSubmit service. +// +// For more details, see the documentation at +// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/async-search.html +type XPackAsyncSearchGet struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + // ID of asynchronous search as returned by XPackAsyncSearchSubmit.Do. + id string + // waitForCompletionTimeout is the duration the call should wait for a result + // before timing out. The default is 1 second. + waitForCompletionTimeout string + // keepAlive asks Elasticsearch to keep the ID and its results even + // after the search has been completed. + keepAlive string +} + +// NewXPackAsyncSearchGet creates a new XPackAsyncSearchGet. +func NewXPackAsyncSearchGet(client *Client) *XPackAsyncSearchGet { + return &XPackAsyncSearchGet{ + client: client, + } +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *XPackAsyncSearchGet) Pretty(pretty bool) *XPackAsyncSearchGet { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *XPackAsyncSearchGet) Human(human bool) *XPackAsyncSearchGet { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *XPackAsyncSearchGet) ErrorTrace(errorTrace bool) *XPackAsyncSearchGet { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *XPackAsyncSearchGet) FilterPath(filterPath ...string) *XPackAsyncSearchGet { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *XPackAsyncSearchGet) Header(name string, value string) *XPackAsyncSearchGet { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *XPackAsyncSearchGet) Headers(headers http.Header) *XPackAsyncSearchGet { + s.headers = headers + return s +} + +// ID of the asynchronous search. +func (s *XPackAsyncSearchGet) ID(id string) *XPackAsyncSearchGet { + s.id = id + return s +} + +// WaitForCompletionTimeout specifies the time the service waits for retrieving +// a complete result. If the timeout expires, you'll get the current results which +// might not be complete. +func (s *XPackAsyncSearchGet) WaitForCompletionTimeout(waitForCompletionTimeout string) *XPackAsyncSearchGet { + s.waitForCompletionTimeout = waitForCompletionTimeout + return s +} + +// KeepAlive is the time the search results are kept by Elasticsearch before +// being garbage collected. +func (s *XPackAsyncSearchGet) KeepAlive(keepAlive string) *XPackAsyncSearchGet { + s.keepAlive = keepAlive + return s +} + +// buildURL builds the URL for the operation. +func (s *XPackAsyncSearchGet) buildURL() (string, url.Values, error) { + path := fmt.Sprintf("/_async_search/%s", url.PathEscape(s.id)) + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.waitForCompletionTimeout != "" { + params.Set("wait_for_completion_timeout", s.waitForCompletionTimeout) + } + if s.keepAlive != "" { + params.Set("keep_alive", s.keepAlive) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *XPackAsyncSearchGet) Validate() error { + var invalid []string + if s.id == "" { + invalid = append(invalid, "ID") + } + if len(invalid) > 0 { + return fmt.Errorf("missing required fields: %v", invalid) + } + return nil +} + +// Do executes the operation. +func (s *XPackAsyncSearchGet) Do(ctx context.Context) (*XPackAsyncSearchResult, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Get HTTP response + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "GET", + Path: path, + Params: params, + Headers: s.headers, + }) + if err != nil { + return nil, err + } + + // Return operation response + ret := new(XPackAsyncSearchResult) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + ret.Header = res.Header + return nil, err + } + ret.Header = res.Header + return ret, nil +} diff --git a/vendor/github.com/olivere/elastic/v7/xpack_async_search_submit.go b/vendor/github.com/olivere/elastic/v7/xpack_async_search_submit.go new file mode 100644 index 0000000000000000000000000000000000000000..f2c13b69d09a263d53f4ab57ad2aad774721fc44 --- /dev/null +++ b/vendor/github.com/olivere/elastic/v7/xpack_async_search_submit.go @@ -0,0 +1,718 @@ +// Copyright 2012-present Oliver Eilhard. All rights reserved. +// Use of this source code is governed by a MIT-license. +// See http://olivere.mit-license.org/license.txt for details. + +package elastic + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + "reflect" + "strings" + + "github.com/olivere/elastic/v7/uritemplates" +) + +// XPackAsyncSearchSubmit is an XPack API for asynchronously +// searching for documents in Elasticsearch. +// +// For more details, see the documentation at +// https://www.elastic.co/guide/en/elasticsearch/reference/7.9/async-search.html +type XPackAsyncSearchSubmit struct { + client *Client + + pretty *bool // pretty format the returned JSON response + human *bool // return human readable values for statistics + errorTrace *bool // include the stack trace of returned errors + filterPath []string // list of filters used to reduce the response + headers http.Header // custom request-level HTTP headers + + searchSource *SearchSource // q + source interface{} + searchType string // search_type + index []string + typ []string + routing string // routing + preference string // preference + requestCache *bool // request_cache + ignoreUnavailable *bool // ignore_unavailable + ignoreThrottled *bool // ignore_throttled + allowNoIndices *bool // allow_no_indices + expandWildcards string // expand_wildcards + lenient *bool // lenient + maxResponseSize int64 + allowPartialSearchResults *bool // allow_partial_search_results + typedKeys *bool // typed_keys + seqNoPrimaryTerm *bool // seq_no_primary_term + batchedReduceSize *int // batched_reduce_size + maxConcurrentShardRequests *int // max_concurrent_shard_requests + preFilterShardSize *int // pre_filter_shard_size + restTotalHitsAsInt *bool // rest_total_hits_as_int + + ccsMinimizeRoundtrips *bool // ccs_minimize_roundtrips + + waitForCompletionTimeout string // e.g. "1s" + keepOnCompletion *bool + keepAlive string // e.g. "1h" +} + +// NewXPackAsyncSearchSubmit creates a new service for asynchronously +// searching in Elasticsearch. +func NewXPackAsyncSearchSubmit(client *Client) *XPackAsyncSearchSubmit { + builder := &XPackAsyncSearchSubmit{ + client: client, + searchSource: NewSearchSource(), + } + return builder +} + +// Pretty tells Elasticsearch whether to return a formatted JSON response. +func (s *XPackAsyncSearchSubmit) Pretty(pretty bool) *XPackAsyncSearchSubmit { + s.pretty = &pretty + return s +} + +// Human specifies whether human readable values should be returned in +// the JSON response, e.g. "7.5mb". +func (s *XPackAsyncSearchSubmit) Human(human bool) *XPackAsyncSearchSubmit { + s.human = &human + return s +} + +// ErrorTrace specifies whether to include the stack trace of returned errors. +func (s *XPackAsyncSearchSubmit) ErrorTrace(errorTrace bool) *XPackAsyncSearchSubmit { + s.errorTrace = &errorTrace + return s +} + +// FilterPath specifies a list of filters used to reduce the response. +func (s *XPackAsyncSearchSubmit) FilterPath(filterPath ...string) *XPackAsyncSearchSubmit { + s.filterPath = filterPath + return s +} + +// Header adds a header to the request. +func (s *XPackAsyncSearchSubmit) Header(name string, value string) *XPackAsyncSearchSubmit { + if s.headers == nil { + s.headers = http.Header{} + } + s.headers.Add(name, value) + return s +} + +// Headers specifies the headers of the request. +func (s *XPackAsyncSearchSubmit) Headers(headers http.Header) *XPackAsyncSearchSubmit { + s.headers = headers + return s +} + +// SearchSource sets the search source builder to use with this service. +func (s *XPackAsyncSearchSubmit) SearchSource(searchSource *SearchSource) *XPackAsyncSearchSubmit { + s.searchSource = searchSource + if s.searchSource == nil { + s.searchSource = NewSearchSource() + } + return s +} + +// Source allows the user to set the request body manually without using +// any of the structs and interfaces in Elastic. +func (s *XPackAsyncSearchSubmit) Source(source interface{}) *XPackAsyncSearchSubmit { + s.source = source + return s +} + +// Index sets the names of the indices to use for search. +func (s *XPackAsyncSearchSubmit) Index(index ...string) *XPackAsyncSearchSubmit { + s.index = append(s.index, index...) + return s +} + +// Type adds search restrictions for a list of types. +// +// Deprecated: Types are in the process of being removed. Instead of using a type, prefer to +// filter on a field on the document. +func (s *XPackAsyncSearchSubmit) Type(typ ...string) *XPackAsyncSearchSubmit { + s.typ = append(s.typ, typ...) + return s +} + +// Timeout sets the timeout to use, e.g. "1s" or "1000ms". +func (s *XPackAsyncSearchSubmit) Timeout(timeout string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Timeout(timeout) + return s +} + +// Profile sets the Profile API flag on the search source. +// When enabled, a search executed by this service will return query +// profiling data. +func (s *XPackAsyncSearchSubmit) Profile(profile bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Profile(profile) + return s +} + +// Collapse adds field collapsing. +func (s *XPackAsyncSearchSubmit) Collapse(collapse *CollapseBuilder) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Collapse(collapse) + return s +} + +// TimeoutInMillis sets the timeout in milliseconds. +func (s *XPackAsyncSearchSubmit) TimeoutInMillis(timeoutInMillis int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.TimeoutInMillis(timeoutInMillis) + return s +} + +// TerminateAfter specifies the maximum number of documents to collect for +// each shard, upon reaching which the query execution will terminate early. +func (s *XPackAsyncSearchSubmit) TerminateAfter(terminateAfter int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.TerminateAfter(terminateAfter) + return s +} + +// SearchType sets the search operation type. Valid values are: +// "dfs_query_then_fetch" and "query_then_fetch". +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/search-request-search-type.html +// for details. +func (s *XPackAsyncSearchSubmit) SearchType(searchType string) *XPackAsyncSearchSubmit { + s.searchType = searchType + return s +} + +// Routing is a list of specific routing values to control the shards +// the search will be executed on. +func (s *XPackAsyncSearchSubmit) Routing(routings ...string) *XPackAsyncSearchSubmit { + s.routing = strings.Join(routings, ",") + return s +} + +// Preference sets the preference to execute the search. Defaults to +// randomize across shards ("random"). Can be set to "_local" to prefer +// local shards, "_primary" to execute on primary shards only, +// or a custom value which guarantees that the same order will be used +// across different requests. +func (s *XPackAsyncSearchSubmit) Preference(preference string) *XPackAsyncSearchSubmit { + s.preference = preference + return s +} + +// RequestCache indicates whether the cache should be used for this +// request or not, defaults to index level setting. +func (s *XPackAsyncSearchSubmit) RequestCache(requestCache bool) *XPackAsyncSearchSubmit { + s.requestCache = &requestCache + return s +} + +// Query sets the query to perform, e.g. MatchAllQuery. +func (s *XPackAsyncSearchSubmit) Query(query Query) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Query(query) + return s +} + +// PostFilter will be executed after the query has been executed and +// only affects the search hits, not the aggregations. +// This filter is always executed as the last filtering mechanism. +func (s *XPackAsyncSearchSubmit) PostFilter(postFilter Query) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.PostFilter(postFilter) + return s +} + +// FetchSource indicates whether the response should contain the stored +// _source for every hit. +func (s *XPackAsyncSearchSubmit) FetchSource(fetchSource bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.FetchSource(fetchSource) + return s +} + +// FetchSourceContext indicates how the _source should be fetched. +func (s *XPackAsyncSearchSubmit) FetchSourceContext(fetchSourceContext *FetchSourceContext) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.FetchSourceContext(fetchSourceContext) + return s +} + +// Highlight adds highlighting to the search. +func (s *XPackAsyncSearchSubmit) Highlight(highlight *Highlight) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Highlight(highlight) + return s +} + +// GlobalSuggestText defines the global text to use with all suggesters. +// This avoids repetition. +func (s *XPackAsyncSearchSubmit) GlobalSuggestText(globalText string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.GlobalSuggestText(globalText) + return s +} + +// Suggester adds a suggester to the search. +func (s *XPackAsyncSearchSubmit) Suggester(suggester Suggester) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Suggester(suggester) + return s +} + +// Aggregation adds an aggreation to perform as part of the search. +func (s *XPackAsyncSearchSubmit) Aggregation(name string, aggregation Aggregation) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Aggregation(name, aggregation) + return s +} + +// MinScore sets the minimum score below which docs will be filtered out. +func (s *XPackAsyncSearchSubmit) MinScore(minScore float64) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.MinScore(minScore) + return s +} + +// From index to start the search from. Defaults to 0. +func (s *XPackAsyncSearchSubmit) From(from int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.From(from) + return s +} + +// Size is the number of search hits to return. Defaults to 10. +func (s *XPackAsyncSearchSubmit) Size(size int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Size(size) + return s +} + +// Explain indicates whether each search hit should be returned with +// an explanation of the hit (ranking). +func (s *XPackAsyncSearchSubmit) Explain(explain bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Explain(explain) + return s +} + +// Version indicates whether each search hit should be returned with +// a version associated to it. +func (s *XPackAsyncSearchSubmit) Version(version bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Version(version) + return s +} + +// Sort adds a sort order. +func (s *XPackAsyncSearchSubmit) Sort(field string, ascending bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Sort(field, ascending) + return s +} + +// SortWithInfo adds a sort order. +func (s *XPackAsyncSearchSubmit) SortWithInfo(info SortInfo) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.SortWithInfo(info) + return s +} + +// SortBy adds a sort order. +func (s *XPackAsyncSearchSubmit) SortBy(sorter ...Sorter) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.SortBy(sorter...) + return s +} + +// DocvalueField adds a single field to load from the field data cache +// and return as part of the search. +func (s *XPackAsyncSearchSubmit) DocvalueField(docvalueField string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DocvalueField(docvalueField) + return s +} + +// DocvalueFieldWithFormat adds a single field to load from the field data cache +// and return as part of the search. +func (s *XPackAsyncSearchSubmit) DocvalueFieldWithFormat(docvalueField DocvalueField) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DocvalueFieldWithFormat(docvalueField) + return s +} + +// DocvalueFields adds one or more fields to load from the field data cache +// and return as part of the search. +func (s *XPackAsyncSearchSubmit) DocvalueFields(docvalueFields ...string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DocvalueFields(docvalueFields...) + return s +} + +// DocvalueFieldsWithFormat adds one or more fields to load from the field data cache +// and return as part of the search. +func (s *XPackAsyncSearchSubmit) DocvalueFieldsWithFormat(docvalueFields ...DocvalueField) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DocvalueFieldsWithFormat(docvalueFields...) + return s +} + +// NoStoredFields indicates that no stored fields should be loaded, resulting in only +// id and type to be returned per field. +func (s *XPackAsyncSearchSubmit) NoStoredFields() *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.NoStoredFields() + return s +} + +// StoredField adds a single field to load and return (note, must be stored) as +// part of the search request. If none are specified, the source of the +// document will be returned. +func (s *XPackAsyncSearchSubmit) StoredField(fieldName string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.StoredField(fieldName) + return s +} + +// StoredFields sets the fields to load and return as part of the search request. +// If none are specified, the source of the document will be returned. +func (s *XPackAsyncSearchSubmit) StoredFields(fields ...string) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.StoredFields(fields...) + return s +} + +// TrackScores is applied when sorting and controls if scores will be +// tracked as well. Defaults to false. +func (s *XPackAsyncSearchSubmit) TrackScores(trackScores bool) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.TrackScores(trackScores) + return s +} + +// TrackTotalHits controls if the total hit count for the query should be tracked. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.1/search-request-track-total-hits.html +// for details. +func (s *XPackAsyncSearchSubmit) TrackTotalHits(trackTotalHits interface{}) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.TrackTotalHits(trackTotalHits) + return s +} + +// SearchAfter allows a different form of pagination by using a live cursor, +// using the results of the previous page to help the retrieval of the next. +// +// See https://www.elastic.co/guide/en/elasticsearch/reference/7.0/search-request-search-after.html +func (s *XPackAsyncSearchSubmit) SearchAfter(sortValues ...interface{}) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.SearchAfter(sortValues...) + return s +} + +// DefaultRescoreWindowSize sets the rescore window size for rescores +// that don't specify their window. +func (s *XPackAsyncSearchSubmit) DefaultRescoreWindowSize(defaultRescoreWindowSize int) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.DefaultRescoreWindowSize(defaultRescoreWindowSize) + return s +} + +// Rescorer adds a rescorer to the search. +func (s *XPackAsyncSearchSubmit) Rescorer(rescore *Rescore) *XPackAsyncSearchSubmit { + s.searchSource = s.searchSource.Rescorer(rescore) + return s +} + +// IgnoreUnavailable indicates whether the specified concrete indices +// should be ignored when unavailable (missing or closed). +func (s *XPackAsyncSearchSubmit) IgnoreUnavailable(ignoreUnavailable bool) *XPackAsyncSearchSubmit { + s.ignoreUnavailable = &ignoreUnavailable + return s +} + +// IgnoreThrottled indicates whether specified concrete, expanded or aliased +// indices should be ignored when throttled. +func (s *XPackAsyncSearchSubmit) IgnoreThrottled(ignoreThrottled bool) *XPackAsyncSearchSubmit { + s.ignoreThrottled = &ignoreThrottled + return s +} + +// AllowNoIndices indicates whether to ignore if a wildcard indices +// expression resolves into no concrete indices. (This includes `_all` string +// or when no indices have been specified). +func (s *XPackAsyncSearchSubmit) AllowNoIndices(allowNoIndices bool) *XPackAsyncSearchSubmit { + s.allowNoIndices = &allowNoIndices + return s +} + +// ExpandWildcards indicates whether to expand wildcard expression to +// concrete indices that are open, closed or both. +func (s *XPackAsyncSearchSubmit) ExpandWildcards(expandWildcards string) *XPackAsyncSearchSubmit { + s.expandWildcards = expandWildcards + return s +} + +// Lenient specifies whether format-based query failures (such as providing +// text to a numeric field) should be ignored. +func (s *XPackAsyncSearchSubmit) Lenient(lenient bool) *XPackAsyncSearchSubmit { + s.lenient = &lenient + return s +} + +// MaxResponseSize sets an upper limit on the response body size that we accept, +// to guard against OOM situations. +func (s *XPackAsyncSearchSubmit) MaxResponseSize(maxResponseSize int64) *XPackAsyncSearchSubmit { + s.maxResponseSize = maxResponseSize + return s +} + +// AllowPartialSearchResults indicates if an error should be returned if +// there is a partial search failure or timeout. +func (s *XPackAsyncSearchSubmit) AllowPartialSearchResults(enabled bool) *XPackAsyncSearchSubmit { + s.allowPartialSearchResults = &enabled + return s +} + +// TypedKeys specifies whether aggregation and suggester names should be +// prefixed by their respective types in the response. +func (s *XPackAsyncSearchSubmit) TypedKeys(enabled bool) *XPackAsyncSearchSubmit { + s.typedKeys = &enabled + return s +} + +// SeqNoPrimaryTerm specifies whether to return sequence number and +// primary term of the last modification of each hit. +func (s *XPackAsyncSearchSubmit) SeqNoPrimaryTerm(enabled bool) *XPackAsyncSearchSubmit { + s.seqNoPrimaryTerm = &enabled + return s +} + +// BatchedReduceSize specifies the number of shard results that should be reduced +// at once on the coordinating node. This value should be used as a protection +// mechanism to reduce the memory overhead per search request if the potential +// number of shards in the request can be large. +func (s *XPackAsyncSearchSubmit) BatchedReduceSize(size int) *XPackAsyncSearchSubmit { + s.batchedReduceSize = &size + return s +} + +// MaxConcurrentShardRequests specifies the number of concurrent shard requests +// this search executes concurrently. This value should be used to limit the +// impact of the search on the cluster in order to limit the number of +// concurrent shard requests. +func (s *XPackAsyncSearchSubmit) MaxConcurrentShardRequests(max int) *XPackAsyncSearchSubmit { + s.maxConcurrentShardRequests = &max + return s +} + +// PreFilterShardSize specifies a threshold that enforces a pre-filter roundtrip +// to prefilter search shards based on query rewriting if the number of shards +// the search request expands to exceeds the threshold. This filter roundtrip +// can limit the number of shards significantly if for instance a shard can +// not match any documents based on it's rewrite method i.e. if date filters are +// mandatory to match but the shard bounds and the query are disjoint. +func (s *XPackAsyncSearchSubmit) PreFilterShardSize(threshold int) *XPackAsyncSearchSubmit { + s.preFilterShardSize = &threshold + return s +} + +// RestTotalHitsAsInt indicates whether hits.total should be rendered as an +// integer or an object in the rest search response. +func (s *XPackAsyncSearchSubmit) RestTotalHitsAsInt(enabled bool) *XPackAsyncSearchSubmit { + s.restTotalHitsAsInt = &enabled + return s +} + +// CCSMinimizeRoundtrips indicates whether network round-trips should be minimized +// as part of cross-cluster search requests execution. +func (s *XPackAsyncSearchSubmit) CCSMinimizeRoundtrips(enabled bool) *XPackAsyncSearchSubmit { + s.ccsMinimizeRoundtrips = &enabled + return s +} + +// WaitForCompletionTimeout is suitable for DoAsync only. It specifies the +// timeout for the Search to wait for completion before returning an ID to +// return the results asynchronously. In other words: If the search takes +// longer than this value (default is 1 second), then you need to call +// GetAsync to retrieve its final results. +func (s *XPackAsyncSearchSubmit) WaitForCompletionTimeout(timeout string) *XPackAsyncSearchSubmit { + s.waitForCompletionTimeout = timeout + return s +} + +// KeepOnCompletion is suitable for DoAsync only. It indicates whether the +// asynchronous search ID and its results should be kept even after the +// search (and its results) are completed and retrieved. +func (s *XPackAsyncSearchSubmit) KeepOnCompletion(keepOnCompletion bool) *XPackAsyncSearchSubmit { + s.keepOnCompletion = &keepOnCompletion + return s +} + +// KeepAlive can only be used with DoAsync. If set, KeepAlive specifies the +// duration after which search ID and its results are removed from the +// Elasticsearch cluster and hence can no longer be retrieved with GetAsync. +func (s *XPackAsyncSearchSubmit) KeepAlive(keepAlive string) *XPackAsyncSearchSubmit { + s.keepAlive = keepAlive + return s +} + +// buildURL builds the URL for the operation. +func (s *XPackAsyncSearchSubmit) buildURL() (string, url.Values, error) { + var err error + var path string + + if len(s.index) > 0 && len(s.typ) > 0 { + path, err = uritemplates.Expand("/{index}/{type}/_async_search", map[string]string{ + "index": strings.Join(s.index, ","), + "type": strings.Join(s.typ, ","), + }) + } else if len(s.index) > 0 { + path, err = uritemplates.Expand("/{index}/_async_search", map[string]string{ + "index": strings.Join(s.index, ","), + }) + } else if len(s.typ) > 0 { + path, err = uritemplates.Expand("/_all/{type}/_async_search", map[string]string{ + "type": strings.Join(s.typ, ","), + }) + } else { + path = "/_async_search" + } + if err != nil { + return "", url.Values{}, err + } + + // Add query string parameters + params := url.Values{} + if v := s.pretty; v != nil { + params.Set("pretty", fmt.Sprint(*v)) + } + if v := s.human; v != nil { + params.Set("human", fmt.Sprint(*v)) + } + if v := s.errorTrace; v != nil { + params.Set("error_trace", fmt.Sprint(*v)) + } + if len(s.filterPath) > 0 { + params.Set("filter_path", strings.Join(s.filterPath, ",")) + } + if s.searchType != "" { + params.Set("search_type", s.searchType) + } + if s.routing != "" { + params.Set("routing", s.routing) + } + if s.preference != "" { + params.Set("preference", s.preference) + } + if v := s.requestCache; v != nil { + params.Set("request_cache", fmt.Sprint(*v)) + } + if v := s.allowNoIndices; v != nil { + params.Set("allow_no_indices", fmt.Sprint(*v)) + } + if s.expandWildcards != "" { + params.Set("expand_wildcards", s.expandWildcards) + } + if v := s.lenient; v != nil { + params.Set("lenient", fmt.Sprint(*v)) + } + if v := s.ignoreUnavailable; v != nil { + params.Set("ignore_unavailable", fmt.Sprint(*v)) + } + if v := s.ignoreThrottled; v != nil { + params.Set("ignore_throttled", fmt.Sprint(*v)) + } + if s.seqNoPrimaryTerm != nil { + params.Set("seq_no_primary_term", fmt.Sprint(*s.seqNoPrimaryTerm)) + } + if v := s.allowPartialSearchResults; v != nil { + params.Set("allow_partial_search_results", fmt.Sprint(*v)) + } + if v := s.typedKeys; v != nil { + params.Set("typed_keys", fmt.Sprint(*v)) + } + if v := s.batchedReduceSize; v != nil { + params.Set("batched_reduce_size", fmt.Sprint(*v)) + } + if v := s.maxConcurrentShardRequests; v != nil { + params.Set("max_concurrent_shard_requests", fmt.Sprint(*v)) + } + if v := s.preFilterShardSize; v != nil { + params.Set("pre_filter_shard_size", fmt.Sprint(*v)) + } + if v := s.restTotalHitsAsInt; v != nil { + params.Set("rest_total_hits_as_int", fmt.Sprint(*v)) + } + if v := s.ccsMinimizeRoundtrips; v != nil { + params.Set("ccs_minimize_roundtrips", fmt.Sprint(*v)) + } + if s.waitForCompletionTimeout != "" { + params.Set("wait_for_completion_timeout", s.waitForCompletionTimeout) + } + if v := s.keepOnCompletion; v != nil { + params.Set("keep_on_completion", fmt.Sprint(*v)) + } + if s.keepAlive != "" { + params.Set("keep_alive", s.keepAlive) + } + return path, params, nil +} + +// Validate checks if the operation is valid. +func (s *XPackAsyncSearchSubmit) Validate() error { + return nil +} + +// Do executes the search and returns a XPackAsyncSearchResult. +func (s *XPackAsyncSearchSubmit) Do(ctx context.Context) (*XPackAsyncSearchResult, error) { + // Check pre-conditions + if err := s.Validate(); err != nil { + return nil, err + } + + // Get URL for request + path, params, err := s.buildURL() + if err != nil { + return nil, err + } + + // Perform request + var body interface{} + if s.source != nil { + body = s.source + } else { + src, err := s.searchSource.Source() + if err != nil { + return nil, err + } + body = src + } + res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ + Method: "POST", + Path: path, + Params: params, + Body: body, + Headers: s.headers, + MaxResponseSize: s.maxResponseSize, + }) + if err != nil { + return nil, err + } + + // Return search results + ret := new(XPackAsyncSearchResult) + if err := s.client.decoder.Decode(res.Body, ret); err != nil { + ret.Header = res.Header + return nil, err + } + ret.Header = res.Header + return ret, nil +} + +// XPackAsyncSearchResult is the outcome of starting an asynchronous search +// or retrieving a search result with XPackAsyncSearchGet. +type XPackAsyncSearchResult struct { + Header http.Header `json:"-"` + ID string `json:"id,omitempty"` + IsRunning bool `json:"is_running"` + IsPartial bool `json:"is_partial"` + StartTimeMillis int64 `json:"start_time_in_millis,omitempty"` + ExpirationTimeMillis int64 `json:"expiration_time_in_millis,omitempty"` + Response *SearchResult `json:"response,omitempty"` + Error *ErrorDetails `json:"error,omitempty"` +} + +// Each is a utility function to iterate over all hits. It saves you from +// checking for nil values. Notice that Each will ignore errors in +// serializing JSON and hits with empty/nil _source will get an empty +// value +func (r *XPackAsyncSearchResult) Each(typ reflect.Type) []interface{} { + if r == nil || r.Response == nil || r.Response.Hits == nil || r.Response.Hits.Hits == nil || len(r.Response.Hits.Hits) == 0 { + return nil + } + var slice []interface{} + for _, hit := range r.Response.Hits.Hits { + v := reflect.New(typ).Elem() + if hit.Source == nil { + slice = append(slice, v.Interface()) + continue + } + if err := json.Unmarshal(hit.Source, v.Addr().Interface()); err == nil { + slice = append(slice, v.Interface()) + } + } + return slice +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 5c8f4563157328be2adb34ae7269174a9d347947..64376c9b09f568038afccb5beb0dada52556bd9a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,10 +1,11 @@ -# github.com/mailru/easyjson v0.7.1 +# github.com/josharian/intern v1.0.0 +github.com/josharian/intern +# github.com/mailru/easyjson v0.7.6 github.com/mailru/easyjson -github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter -# github.com/olivere/elastic/v7 v7.0.19 -## explicit +github.com/mailru/easyjson/buffer +# github.com/olivere/elastic/v7 v7.0.22 github.com/olivere/elastic/v7 github.com/olivere/elastic/v7/config github.com/olivere/elastic/v7/uritemplates