indices_put_alias.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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. package elastic
  5. import (
  6. "context"
  7. "fmt"
  8. "net/url"
  9. "strings"
  10. )
  11. // -- Actions --
  12. // AliasAction is an action to apply to an alias, e.g. "add" or "remove".
  13. type AliasAction interface {
  14. Source() (interface{}, error)
  15. }
  16. // AliasAddAction is an action to add to an alias.
  17. type AliasAddAction struct {
  18. index []string // index name(s)
  19. alias string // alias name
  20. filter Query
  21. routing string
  22. searchRouting string
  23. indexRouting string
  24. }
  25. // NewAliasAddAction returns an action to add an alias.
  26. func NewAliasAddAction(alias string) *AliasAddAction {
  27. return &AliasAddAction{
  28. alias: alias,
  29. }
  30. }
  31. // Index associates one or more indices to the alias.
  32. func (a *AliasAddAction) Index(index ...string) *AliasAddAction {
  33. a.index = append(a.index, index...)
  34. return a
  35. }
  36. func (a *AliasAddAction) removeBlankIndexNames() {
  37. var indices []string
  38. for _, index := range a.index {
  39. if len(index) > 0 {
  40. indices = append(indices, index)
  41. }
  42. }
  43. a.index = indices
  44. }
  45. // Filter associates a filter to the alias.
  46. func (a *AliasAddAction) Filter(filter Query) *AliasAddAction {
  47. a.filter = filter
  48. return a
  49. }
  50. // Routing associates a routing value to the alias.
  51. // This basically sets index and search routing to the same value.
  52. func (a *AliasAddAction) Routing(routing string) *AliasAddAction {
  53. a.routing = routing
  54. return a
  55. }
  56. // IndexRouting associates an index routing value to the alias.
  57. func (a *AliasAddAction) IndexRouting(routing string) *AliasAddAction {
  58. a.indexRouting = routing
  59. return a
  60. }
  61. // SearchRouting associates a search routing value to the alias.
  62. func (a *AliasAddAction) SearchRouting(routing ...string) *AliasAddAction {
  63. a.searchRouting = strings.Join(routing, ",")
  64. return a
  65. }
  66. // Validate checks if the operation is valid.
  67. func (a *AliasAddAction) Validate() error {
  68. var invalid []string
  69. if len(a.alias) == 0 {
  70. invalid = append(invalid, "Alias")
  71. }
  72. if len(a.index) == 0 {
  73. invalid = append(invalid, "Index")
  74. }
  75. if len(invalid) > 0 {
  76. return fmt.Errorf("missing required fields: %v", invalid)
  77. }
  78. return nil
  79. }
  80. // Source returns the JSON-serializable data.
  81. func (a *AliasAddAction) Source() (interface{}, error) {
  82. a.removeBlankIndexNames()
  83. if err := a.Validate(); err != nil {
  84. return nil, err
  85. }
  86. src := make(map[string]interface{})
  87. act := make(map[string]interface{})
  88. src["add"] = act
  89. act["alias"] = a.alias
  90. switch len(a.index) {
  91. case 1:
  92. act["index"] = a.index[0]
  93. default:
  94. act["indices"] = a.index
  95. }
  96. if a.filter != nil {
  97. f, err := a.filter.Source()
  98. if err != nil {
  99. return nil, err
  100. }
  101. act["filter"] = f
  102. }
  103. if len(a.routing) > 0 {
  104. act["routing"] = a.routing
  105. }
  106. if len(a.indexRouting) > 0 {
  107. act["index_routing"] = a.indexRouting
  108. }
  109. if len(a.searchRouting) > 0 {
  110. act["search_routing"] = a.searchRouting
  111. }
  112. return src, nil
  113. }
  114. // AliasRemoveAction is an action to remove an alias.
  115. type AliasRemoveAction struct {
  116. index []string // index name(s)
  117. alias string // alias name
  118. }
  119. // NewAliasRemoveAction returns an action to remove an alias.
  120. func NewAliasRemoveAction(alias string) *AliasRemoveAction {
  121. return &AliasRemoveAction{
  122. alias: alias,
  123. }
  124. }
  125. // Index associates one or more indices to the alias.
  126. func (a *AliasRemoveAction) Index(index ...string) *AliasRemoveAction {
  127. a.index = append(a.index, index...)
  128. return a
  129. }
  130. func (a *AliasRemoveAction) removeBlankIndexNames() {
  131. var indices []string
  132. for _, index := range a.index {
  133. if len(index) > 0 {
  134. indices = append(indices, index)
  135. }
  136. }
  137. a.index = indices
  138. }
  139. // Validate checks if the operation is valid.
  140. func (a *AliasRemoveAction) Validate() error {
  141. var invalid []string
  142. if len(a.alias) == 0 {
  143. invalid = append(invalid, "Alias")
  144. }
  145. if len(a.index) == 0 {
  146. invalid = append(invalid, "Index")
  147. }
  148. if len(invalid) > 0 {
  149. return fmt.Errorf("missing required fields: %v", invalid)
  150. }
  151. return nil
  152. }
  153. // Source returns the JSON-serializable data.
  154. func (a *AliasRemoveAction) Source() (interface{}, error) {
  155. a.removeBlankIndexNames()
  156. if err := a.Validate(); err != nil {
  157. return nil, err
  158. }
  159. src := make(map[string]interface{})
  160. act := make(map[string]interface{})
  161. src["remove"] = act
  162. act["alias"] = a.alias
  163. switch len(a.index) {
  164. case 1:
  165. act["index"] = a.index[0]
  166. default:
  167. act["indices"] = a.index
  168. }
  169. return src, nil
  170. }
  171. // -- Service --
  172. // AliasService enables users to add or remove an alias.
  173. // See https://www.elastic.co/guide/en/elasticsearch/reference/5.2/indices-aliases.html
  174. // for details.
  175. type AliasService struct {
  176. client *Client
  177. actions []AliasAction
  178. pretty bool
  179. }
  180. // NewAliasService implements a service to manage aliases.
  181. func NewAliasService(client *Client) *AliasService {
  182. builder := &AliasService{
  183. client: client,
  184. }
  185. return builder
  186. }
  187. // Pretty asks Elasticsearch to indent the HTTP response.
  188. func (s *AliasService) Pretty(pretty bool) *AliasService {
  189. s.pretty = pretty
  190. return s
  191. }
  192. // Add adds an alias to an index.
  193. func (s *AliasService) Add(indexName string, aliasName string) *AliasService {
  194. action := NewAliasAddAction(aliasName).Index(indexName)
  195. s.actions = append(s.actions, action)
  196. return s
  197. }
  198. // Add adds an alias to an index and associates a filter to the alias.
  199. func (s *AliasService) AddWithFilter(indexName string, aliasName string, filter Query) *AliasService {
  200. action := NewAliasAddAction(aliasName).Index(indexName).Filter(filter)
  201. s.actions = append(s.actions, action)
  202. return s
  203. }
  204. // Remove removes an alias.
  205. func (s *AliasService) Remove(indexName string, aliasName string) *AliasService {
  206. action := NewAliasRemoveAction(aliasName).Index(indexName)
  207. s.actions = append(s.actions, action)
  208. return s
  209. }
  210. // Action accepts one or more AliasAction instances which can be
  211. // of type AliasAddAction or AliasRemoveAction.
  212. func (s *AliasService) Action(action ...AliasAction) *AliasService {
  213. s.actions = append(s.actions, action...)
  214. return s
  215. }
  216. // buildURL builds the URL for the operation.
  217. func (s *AliasService) buildURL() (string, url.Values, error) {
  218. path := "/_aliases"
  219. // Add query string parameters
  220. params := url.Values{}
  221. if s.pretty {
  222. params.Set("pretty", fmt.Sprintf("%v", s.pretty))
  223. }
  224. return path, params, nil
  225. }
  226. // Do executes the command.
  227. func (s *AliasService) Do(ctx context.Context) (*AliasResult, error) {
  228. path, params, err := s.buildURL()
  229. if err != nil {
  230. return nil, err
  231. }
  232. // Body with actions
  233. body := make(map[string]interface{})
  234. var actions []interface{}
  235. for _, action := range s.actions {
  236. src, err := action.Source()
  237. if err != nil {
  238. return nil, err
  239. }
  240. actions = append(actions, src)
  241. }
  242. body["actions"] = actions
  243. // Get response
  244. res, err := s.client.PerformRequest(ctx, "POST", path, params, body)
  245. if err != nil {
  246. return nil, err
  247. }
  248. // Return results
  249. ret := new(AliasResult)
  250. if err := s.client.decoder.Decode(res.Body, ret); err != nil {
  251. return nil, err
  252. }
  253. return ret, nil
  254. }
  255. // -- Result of an alias request.
  256. // AliasResult is the outcome of calling Do on AliasService.
  257. type AliasResult struct {
  258. Acknowledged bool `json:"acknowledged"`
  259. }