indices_rollover.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  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. "encoding/json"
  8. "fmt"
  9. "net/url"
  10. "gopkg.in/olivere/elastic.v5/uritemplates"
  11. )
  12. // IndicesRolloverService rolls an alias over to a new index when the
  13. // existing index is considered to be too large or too old.
  14. //
  15. // It is documented at
  16. // https://www.elastic.co/guide/en/elasticsearch/reference/5.2/indices-rollover-index.html.
  17. type IndicesRolloverService struct {
  18. client *Client
  19. pretty bool
  20. dryRun bool
  21. newIndex string
  22. alias string
  23. masterTimeout string
  24. timeout string
  25. waitForActiveShards string
  26. conditions map[string]interface{}
  27. settings map[string]interface{}
  28. mappings map[string]interface{}
  29. bodyJson interface{}
  30. bodyString string
  31. }
  32. // NewIndicesRolloverService creates a new IndicesRolloverService.
  33. func NewIndicesRolloverService(client *Client) *IndicesRolloverService {
  34. return &IndicesRolloverService{
  35. client: client,
  36. conditions: make(map[string]interface{}),
  37. settings: make(map[string]interface{}),
  38. mappings: make(map[string]interface{}),
  39. }
  40. }
  41. // Alias is the name of the alias to rollover.
  42. func (s *IndicesRolloverService) Alias(alias string) *IndicesRolloverService {
  43. s.alias = alias
  44. return s
  45. }
  46. // NewIndex is the name of the rollover index.
  47. func (s *IndicesRolloverService) NewIndex(newIndex string) *IndicesRolloverService {
  48. s.newIndex = newIndex
  49. return s
  50. }
  51. // MasterTimeout specifies the timeout for connection to master.
  52. func (s *IndicesRolloverService) MasterTimeout(masterTimeout string) *IndicesRolloverService {
  53. s.masterTimeout = masterTimeout
  54. return s
  55. }
  56. // Timeout sets an explicit operation timeout.
  57. func (s *IndicesRolloverService) Timeout(timeout string) *IndicesRolloverService {
  58. s.timeout = timeout
  59. return s
  60. }
  61. // WaitForActiveShards sets the number of active shards to wait for on the
  62. // newly created rollover index before the operation returns.
  63. func (s *IndicesRolloverService) WaitForActiveShards(waitForActiveShards string) *IndicesRolloverService {
  64. s.waitForActiveShards = waitForActiveShards
  65. return s
  66. }
  67. // Pretty indicates that the JSON response be indented and human readable.
  68. func (s *IndicesRolloverService) Pretty(pretty bool) *IndicesRolloverService {
  69. s.pretty = pretty
  70. return s
  71. }
  72. // DryRun, when set, specifies that only conditions are checked without
  73. // performing the actual rollover.
  74. func (s *IndicesRolloverService) DryRun(dryRun bool) *IndicesRolloverService {
  75. s.dryRun = dryRun
  76. return s
  77. }
  78. // Conditions allows to specify all conditions as a dictionary.
  79. func (s *IndicesRolloverService) Conditions(conditions map[string]interface{}) *IndicesRolloverService {
  80. s.conditions = conditions
  81. return s
  82. }
  83. // AddCondition adds a condition to the rollover decision.
  84. func (s *IndicesRolloverService) AddCondition(name string, value interface{}) *IndicesRolloverService {
  85. s.conditions[name] = value
  86. return s
  87. }
  88. // AddMaxIndexAgeCondition adds a condition to set the max index age.
  89. func (s *IndicesRolloverService) AddMaxIndexAgeCondition(time string) *IndicesRolloverService {
  90. s.conditions["max_age"] = time
  91. return s
  92. }
  93. // AddMaxIndexDocsCondition adds a condition to set the max documents in the index.
  94. func (s *IndicesRolloverService) AddMaxIndexDocsCondition(docs int64) *IndicesRolloverService {
  95. s.conditions["max_docs"] = docs
  96. return s
  97. }
  98. // Settings adds the index settings.
  99. func (s *IndicesRolloverService) Settings(settings map[string]interface{}) *IndicesRolloverService {
  100. s.settings = settings
  101. return s
  102. }
  103. // AddSetting adds an index setting.
  104. func (s *IndicesRolloverService) AddSetting(name string, value interface{}) *IndicesRolloverService {
  105. s.settings[name] = value
  106. return s
  107. }
  108. // Mappings adds the index mappings.
  109. func (s *IndicesRolloverService) Mappings(mappings map[string]interface{}) *IndicesRolloverService {
  110. s.mappings = mappings
  111. return s
  112. }
  113. // AddMapping adds a mapping for the given type.
  114. func (s *IndicesRolloverService) AddMapping(typ string, mapping interface{}) *IndicesRolloverService {
  115. s.mappings[typ] = mapping
  116. return s
  117. }
  118. // BodyJson sets the conditions that needs to be met for executing rollover,
  119. // specified as a serializable JSON instance which is sent as the body of
  120. // the request.
  121. func (s *IndicesRolloverService) BodyJson(body interface{}) *IndicesRolloverService {
  122. s.bodyJson = body
  123. return s
  124. }
  125. // BodyString sets the conditions that needs to be met for executing rollover,
  126. // specified as a string which is sent as the body of the request.
  127. func (s *IndicesRolloverService) BodyString(body string) *IndicesRolloverService {
  128. s.bodyString = body
  129. return s
  130. }
  131. // getBody returns the body of the request, if not explicitly set via
  132. // BodyJson or BodyString.
  133. func (s *IndicesRolloverService) getBody() interface{} {
  134. body := make(map[string]interface{})
  135. if len(s.conditions) > 0 {
  136. body["conditions"] = s.conditions
  137. }
  138. if len(s.settings) > 0 {
  139. body["settings"] = s.settings
  140. }
  141. if len(s.mappings) > 0 {
  142. body["mappings"] = s.mappings
  143. }
  144. return body
  145. }
  146. // buildURL builds the URL for the operation.
  147. func (s *IndicesRolloverService) buildURL() (string, url.Values, error) {
  148. // Build URL
  149. var err error
  150. var path string
  151. if s.newIndex != "" {
  152. path, err = uritemplates.Expand("/{alias}/_rollover/{new_index}", map[string]string{
  153. "alias": s.alias,
  154. "new_index": s.newIndex,
  155. })
  156. } else {
  157. path, err = uritemplates.Expand("/{alias}/_rollover", map[string]string{
  158. "alias": s.alias,
  159. })
  160. }
  161. if err != nil {
  162. return "", url.Values{}, err
  163. }
  164. // Add query string parameters
  165. params := url.Values{}
  166. if s.pretty {
  167. params.Set("pretty", "1")
  168. }
  169. if s.dryRun {
  170. params.Set("dry_run", "1")
  171. }
  172. if s.masterTimeout != "" {
  173. params.Set("master_timeout", s.masterTimeout)
  174. }
  175. if s.timeout != "" {
  176. params.Set("timeout", s.timeout)
  177. }
  178. if s.waitForActiveShards != "" {
  179. params.Set("wait_for_active_shards", s.waitForActiveShards)
  180. }
  181. return path, params, nil
  182. }
  183. // Validate checks if the operation is valid.
  184. func (s *IndicesRolloverService) Validate() error {
  185. var invalid []string
  186. if s.alias == "" {
  187. invalid = append(invalid, "Alias")
  188. }
  189. if len(invalid) > 0 {
  190. return fmt.Errorf("missing required fields: %v", invalid)
  191. }
  192. return nil
  193. }
  194. // Do executes the operation.
  195. func (s *IndicesRolloverService) Do(ctx context.Context) (*IndicesRolloverResponse, error) {
  196. // Check pre-conditions
  197. if err := s.Validate(); err != nil {
  198. return nil, err
  199. }
  200. // Get URL for request
  201. path, params, err := s.buildURL()
  202. if err != nil {
  203. return nil, err
  204. }
  205. // Setup HTTP request body
  206. var body interface{}
  207. if s.bodyJson != nil {
  208. body = s.bodyJson
  209. } else if s.bodyString != "" {
  210. body = s.bodyString
  211. } else {
  212. body = s.getBody()
  213. }
  214. // Get HTTP response
  215. res, err := s.client.PerformRequest(ctx, "POST", path, params, body)
  216. if err != nil {
  217. return nil, err
  218. }
  219. // Return operation response
  220. ret := new(IndicesRolloverResponse)
  221. if err := json.Unmarshal(res.Body, ret); err != nil {
  222. return nil, err
  223. }
  224. return ret, nil
  225. }
  226. // IndicesRolloverResponse is the response of IndicesRolloverService.Do.
  227. type IndicesRolloverResponse struct {
  228. OldIndex string `json:"old_index"`
  229. NewIndex string `json:"new_index"`
  230. RolledOver bool `json:"rolled_over"`
  231. DryRun bool `json:"dry_run"`
  232. Acknowledged bool `json:"acknowledged"`
  233. ShardsAcknowledged bool `json:"shards_acknowledged"`
  234. Conditions map[string]bool `json:"conditions"`
  235. }