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	"gopkg.in/olivere/elastic.v5/uritemplates"
14)
15
16// IndicesPutSettingsService changes specific index level settings in
17// real time.
18//
19// See the documentation at
20// https://www.elastic.co/guide/en/elasticsearch/reference/5.2/indices-update-settings.html.
21type IndicesPutSettingsService struct {
22	client            *Client
23	pretty            bool
24	index             []string
25	allowNoIndices    *bool
26	expandWildcards   string
27	flatSettings      *bool
28	ignoreUnavailable *bool
29	masterTimeout     string
30	bodyJson          interface{}
31	bodyString        string
32}
33
34// NewIndicesPutSettingsService creates a new IndicesPutSettingsService.
35func NewIndicesPutSettingsService(client *Client) *IndicesPutSettingsService {
36	return &IndicesPutSettingsService{
37		client: client,
38		index:  make([]string, 0),
39	}
40}
41
42// Index is a list of index names the mapping should be added to
43// (supports wildcards); use `_all` or omit to add the mapping on all indices.
44func (s *IndicesPutSettingsService) Index(indices ...string) *IndicesPutSettingsService {
45	s.index = append(s.index, indices...)
46	return s
47}
48
49// AllowNoIndices indicates whether to ignore if a wildcard indices
50// expression resolves into no concrete indices. (This includes `_all`
51// string or when no indices have been specified).
52func (s *IndicesPutSettingsService) AllowNoIndices(allowNoIndices bool) *IndicesPutSettingsService {
53	s.allowNoIndices = &allowNoIndices
54	return s
55}
56
57// ExpandWildcards specifies whether to expand wildcard expression to
58// concrete indices that are open, closed or both.
59func (s *IndicesPutSettingsService) ExpandWildcards(expandWildcards string) *IndicesPutSettingsService {
60	s.expandWildcards = expandWildcards
61	return s
62}
63
64// FlatSettings indicates whether to return settings in flat format (default: false).
65func (s *IndicesPutSettingsService) FlatSettings(flatSettings bool) *IndicesPutSettingsService {
66	s.flatSettings = &flatSettings
67	return s
68}
69
70// IgnoreUnavailable specifies whether specified concrete indices should be
71// ignored when unavailable (missing or closed).
72func (s *IndicesPutSettingsService) IgnoreUnavailable(ignoreUnavailable bool) *IndicesPutSettingsService {
73	s.ignoreUnavailable = &ignoreUnavailable
74	return s
75}
76
77// MasterTimeout is the timeout for connection to master.
78func (s *IndicesPutSettingsService) MasterTimeout(masterTimeout string) *IndicesPutSettingsService {
79	s.masterTimeout = masterTimeout
80	return s
81}
82
83// Pretty indicates that the JSON response be indented and human readable.
84func (s *IndicesPutSettingsService) Pretty(pretty bool) *IndicesPutSettingsService {
85	s.pretty = pretty
86	return s
87}
88
89// BodyJson is documented as: The index settings to be updated.
90func (s *IndicesPutSettingsService) BodyJson(body interface{}) *IndicesPutSettingsService {
91	s.bodyJson = body
92	return s
93}
94
95// BodyString is documented as: The index settings to be updated.
96func (s *IndicesPutSettingsService) BodyString(body string) *IndicesPutSettingsService {
97	s.bodyString = body
98	return s
99}
100
101// buildURL builds the URL for the operation.
102func (s *IndicesPutSettingsService) buildURL() (string, url.Values, error) {
103	// Build URL
104	var err error
105	var path string
106
107	if len(s.index) > 0 {
108		path, err = uritemplates.Expand("/{index}/_settings", map[string]string{
109			"index": strings.Join(s.index, ","),
110		})
111	} else {
112		path = "/_settings"
113	}
114	if err != nil {
115		return "", url.Values{}, err
116	}
117
118	// Add query string parameters
119	params := url.Values{}
120	if s.pretty {
121		params.Set("pretty", "1")
122	}
123	if s.allowNoIndices != nil {
124		params.Set("allow_no_indices", fmt.Sprintf("%v", *s.allowNoIndices))
125	}
126	if s.expandWildcards != "" {
127		params.Set("expand_wildcards", s.expandWildcards)
128	}
129	if s.flatSettings != nil {
130		params.Set("flat_settings", fmt.Sprintf("%v", *s.flatSettings))
131	}
132	if s.ignoreUnavailable != nil {
133		params.Set("ignore_unavailable", fmt.Sprintf("%v", *s.ignoreUnavailable))
134	}
135	if s.masterTimeout != "" {
136		params.Set("master_timeout", s.masterTimeout)
137	}
138	return path, params, nil
139}
140
141// Validate checks if the operation is valid.
142func (s *IndicesPutSettingsService) Validate() error {
143	return nil
144}
145
146// Do executes the operation.
147func (s *IndicesPutSettingsService) Do(ctx context.Context) (*IndicesPutSettingsResponse, error) {
148	// Check pre-conditions
149	if err := s.Validate(); err != nil {
150		return nil, err
151	}
152
153	// Get URL for request
154	path, params, err := s.buildURL()
155	if err != nil {
156		return nil, err
157	}
158
159	// Setup HTTP request body
160	var body interface{}
161	if s.bodyJson != nil {
162		body = s.bodyJson
163	} else {
164		body = s.bodyString
165	}
166
167	// Get HTTP response
168	res, err := s.client.PerformRequest(ctx, "PUT", path, params, body)
169	if err != nil {
170		return nil, err
171	}
172
173	// Return operation response
174	ret := new(IndicesPutSettingsResponse)
175	if err := s.client.decoder.Decode(res.Body, ret); err != nil {
176		return nil, err
177	}
178	return ret, nil
179}
180
181// IndicesPutSettingsResponse is the response of IndicesPutSettingsService.Do.
182type IndicesPutSettingsResponse struct {
183	Acknowledged bool `json:"acknowledged"`
184}
185