1// Copyright 2012-present Oliver Eilhard. All rights reserved. 2// Use of this source code is governed by a MIT-license. 3// See http://olivere.mit-license.org/license.txt for details. 4 5package elastic 6 7import ( 8 "context" 9 "fmt" 10 "net/http" 11 "net/url" 12 "strings" 13 14 "gopkg.in/olivere/elastic.v5/uritemplates" 15) 16 17// IndicesExistsService checks if an index or indices exist or not. 18// 19// See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/indices-exists.html 20// for details. 21type IndicesExistsService struct { 22 client *Client 23 pretty bool 24 index []string 25 ignoreUnavailable *bool 26 allowNoIndices *bool 27 expandWildcards string 28 local *bool 29} 30 31// NewIndicesExistsService creates and initializes a new IndicesExistsService. 32func NewIndicesExistsService(client *Client) *IndicesExistsService { 33 return &IndicesExistsService{ 34 client: client, 35 index: make([]string, 0), 36 } 37} 38 39// Index is a list of one or more indices to check. 40func (s *IndicesExistsService) Index(index []string) *IndicesExistsService { 41 s.index = index 42 return s 43} 44 45// AllowNoIndices indicates whether to ignore if a wildcard indices expression 46// resolves into no concrete indices. (This includes `_all` string or 47// when no indices have been specified). 48func (s *IndicesExistsService) AllowNoIndices(allowNoIndices bool) *IndicesExistsService { 49 s.allowNoIndices = &allowNoIndices 50 return s 51} 52 53// ExpandWildcards indicates whether to expand wildcard expression to 54// concrete indices that are open, closed or both. 55func (s *IndicesExistsService) ExpandWildcards(expandWildcards string) *IndicesExistsService { 56 s.expandWildcards = expandWildcards 57 return s 58} 59 60// Local, when set, returns local information and does not retrieve the state 61// from master node (default: false). 62func (s *IndicesExistsService) Local(local bool) *IndicesExistsService { 63 s.local = &local 64 return s 65} 66 67// IgnoreUnavailable indicates whether specified concrete indices should be 68// ignored when unavailable (missing or closed). 69func (s *IndicesExistsService) IgnoreUnavailable(ignoreUnavailable bool) *IndicesExistsService { 70 s.ignoreUnavailable = &ignoreUnavailable 71 return s 72} 73 74// Pretty indicates that the JSON response be indented and human readable. 75func (s *IndicesExistsService) Pretty(pretty bool) *IndicesExistsService { 76 s.pretty = pretty 77 return s 78} 79 80// buildURL builds the URL for the operation. 81func (s *IndicesExistsService) buildURL() (string, url.Values, error) { 82 // Build URL 83 path, err := uritemplates.Expand("/{index}", map[string]string{ 84 "index": strings.Join(s.index, ","), 85 }) 86 if err != nil { 87 return "", url.Values{}, err 88 } 89 90 // Add query string parameters 91 params := url.Values{} 92 if s.pretty { 93 params.Set("pretty", "1") 94 } 95 if s.local != nil { 96 params.Set("local", fmt.Sprintf("%v", *s.local)) 97 } 98 if s.ignoreUnavailable != nil { 99 params.Set("ignore_unavailable", fmt.Sprintf("%v", *s.ignoreUnavailable)) 100 } 101 if s.allowNoIndices != nil { 102 params.Set("allow_no_indices", fmt.Sprintf("%v", *s.allowNoIndices)) 103 } 104 if s.expandWildcards != "" { 105 params.Set("expand_wildcards", s.expandWildcards) 106 } 107 return path, params, nil 108} 109 110// Validate checks if the operation is valid. 111func (s *IndicesExistsService) Validate() error { 112 var invalid []string 113 if len(s.index) == 0 { 114 invalid = append(invalid, "Index") 115 } 116 if len(invalid) > 0 { 117 return fmt.Errorf("missing required fields: %v", invalid) 118 } 119 return nil 120} 121 122// Do executes the operation. 123func (s *IndicesExistsService) Do(ctx context.Context) (bool, error) { 124 // Check pre-conditions 125 if err := s.Validate(); err != nil { 126 return false, err 127 } 128 129 // Get URL for request 130 path, params, err := s.buildURL() 131 if err != nil { 132 return false, err 133 } 134 135 // Get HTTP response 136 res, err := s.client.PerformRequest(ctx, "HEAD", path, params, nil, 404) 137 if err != nil { 138 return false, err 139 } 140 141 // Return operation response 142 switch res.StatusCode { 143 case http.StatusOK: 144 return true, nil 145 case http.StatusNotFound: 146 return false, nil 147 default: 148 return false, fmt.Errorf("elastic: got HTTP code %d when it should have been either 200 or 404", res.StatusCode) 149 } 150} 151