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/url" 11 "strings" 12 13 "github.com/olivere/elastic/uritemplates" 14) 15 16// AliasesService returns the aliases associated with one or more indices, or the 17// indices associated with one or more aliases, or a combination of those filters. 18// See http://www.elastic.co/guide/en/elasticsearch/reference/6.7/indices-aliases.html. 19type AliasesService struct { 20 client *Client 21 index []string 22 alias []string 23 pretty bool 24} 25 26// NewAliasesService instantiates a new AliasesService. 27func NewAliasesService(client *Client) *AliasesService { 28 builder := &AliasesService{ 29 client: client, 30 } 31 return builder 32} 33 34// Pretty asks Elasticsearch to indent the returned JSON. 35func (s *AliasesService) Pretty(pretty bool) *AliasesService { 36 s.pretty = pretty 37 return s 38} 39 40// Index adds one or more indices. 41func (s *AliasesService) Index(index ...string) *AliasesService { 42 s.index = append(s.index, index...) 43 return s 44} 45 46// Alias adds one or more aliases. 47func (s *AliasesService) Alias(alias ...string) *AliasesService { 48 s.alias = append(s.alias, alias...) 49 return s 50} 51 52// buildURL builds the URL for the operation. 53func (s *AliasesService) buildURL() (string, url.Values, error) { 54 var err error 55 var path string 56 57 if len(s.index) > 0 { 58 path, err = uritemplates.Expand("/{index}/_alias/{alias}", map[string]string{ 59 "index": strings.Join(s.index, ","), 60 "alias": strings.Join(s.alias, ","), 61 }) 62 } else { 63 path, err = uritemplates.Expand("/_alias/{alias}", map[string]string{ 64 "alias": strings.Join(s.alias, ","), 65 }) 66 } 67 if err != nil { 68 return "", url.Values{}, err 69 } 70 path = strings.TrimSuffix(path, "/") 71 72 // Add query string parameters 73 params := url.Values{} 74 if s.pretty { 75 params.Set("pretty", fmt.Sprintf("%v", s.pretty)) 76 } 77 return path, params, nil 78} 79 80func (s *AliasesService) Do(ctx context.Context) (*AliasesResult, error) { 81 path, params, err := s.buildURL() 82 if err != nil { 83 return nil, err 84 } 85 86 // Get response 87 res, err := s.client.PerformRequest(ctx, PerformRequestOptions{ 88 Method: "GET", 89 Path: path, 90 Params: params, 91 }) 92 if err != nil { 93 return nil, err 94 } 95 96 // { 97 // "indexName" : { 98 // "aliases" : { 99 // "alias1" : { }, 100 // "alias2" : { } 101 // } 102 // }, 103 // "indexName2" : { 104 // ... 105 // }, 106 // } 107 indexMap := make(map[string]struct { 108 Aliases map[string]struct { 109 IsWriteIndex bool `json:"is_write_index"` 110 } `json:"aliases"` 111 }) 112 if err := s.client.decoder.Decode(res.Body, &indexMap); err != nil { 113 return nil, err 114 } 115 116 // Each (indexName, _) 117 ret := &AliasesResult{ 118 Indices: make(map[string]indexResult), 119 } 120 for indexName, indexData := range indexMap { 121 if indexData.Aliases == nil { 122 continue 123 } 124 125 indexOut, found := ret.Indices[indexName] 126 if !found { 127 indexOut = indexResult{Aliases: make([]aliasResult, 0)} 128 } 129 130 // { "aliases" : { ... } } 131 for aliasName, aliasData := range indexData.Aliases { 132 aliasRes := aliasResult{AliasName: aliasName, IsWriteIndex: aliasData.IsWriteIndex} 133 indexOut.Aliases = append(indexOut.Aliases, aliasRes) 134 } 135 136 ret.Indices[indexName] = indexOut 137 } 138 139 return ret, nil 140} 141 142// -- Result of an alias request. 143 144// AliasesResult is the outcome of calling AliasesService.Do. 145type AliasesResult struct { 146 Indices map[string]indexResult 147} 148 149type indexResult struct { 150 Aliases []aliasResult 151} 152 153type aliasResult struct { 154 AliasName string 155 IsWriteIndex bool 156} 157 158// IndicesByAlias returns all indices given a specific alias name. 159func (ar AliasesResult) IndicesByAlias(aliasName string) []string { 160 var indices []string 161 for indexName, indexInfo := range ar.Indices { 162 for _, aliasInfo := range indexInfo.Aliases { 163 if aliasInfo.AliasName == aliasName { 164 indices = append(indices, indexName) 165 } 166 } 167 } 168 return indices 169} 170 171// HasAlias returns true if the index has a specific alias. 172func (ir indexResult) HasAlias(aliasName string) bool { 173 for _, alias := range ir.Aliases { 174 if alias.AliasName == aliasName { 175 return true 176 } 177 } 178 return false 179} 180