1// Copyright 2012-2015 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	"encoding/json"
9	"fmt"
10	"log"
11	"net/url"
12	"strings"
13
14	"gopkg.in/olivere/elastic.v2/uritemplates"
15)
16
17var (
18	_ = fmt.Print
19	_ = log.Print
20	_ = strings.Index
21	_ = uritemplates.Expand
22	_ = url.Parse
23)
24
25// IndicesGetService retrieves information about one or more indices.
26// See http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-get-index.html.
27type IndicesGetService struct {
28	client            *Client
29	pretty            bool
30	index             []string
31	feature           []string
32	expandWildcards   string
33	local             *bool
34	ignoreUnavailable *bool
35	allowNoIndices    *bool
36}
37
38// NewIndicesGetService creates a new IndicesGetService.
39func NewIndicesGetService(client *Client) *IndicesGetService {
40	return &IndicesGetService{
41		client:  client,
42		index:   make([]string, 0),
43		feature: make([]string, 0),
44	}
45}
46
47// Index is a list of index names. Use _all to retrieve information about
48// all indices of a cluster.
49func (s *IndicesGetService) Index(index ...string) *IndicesGetService {
50	s.index = append(s.index, index...)
51	return s
52}
53
54// Feature is a list of features (e.g. _settings,_mappings,_warmers, and _aliases).
55func (s *IndicesGetService) Feature(feature ...string) *IndicesGetService {
56	s.feature = append(s.feature, feature...)
57	return s
58}
59
60// ExpandWildcards indicates whether wildcard expressions should
61// get expanded to open or closed indices (default: open).
62func (s *IndicesGetService) ExpandWildcards(expandWildcards string) *IndicesGetService {
63	s.expandWildcards = expandWildcards
64	return s
65}
66
67// Local indicates whether to return local information (do not retrieve
68// the state from master node (default: false)).
69func (s *IndicesGetService) Local(local bool) *IndicesGetService {
70	s.local = &local
71	return s
72}
73
74// IgnoreUnavailable indicates whether to ignore unavailable indexes (default: false).
75func (s *IndicesGetService) IgnoreUnavailable(ignoreUnavailable bool) *IndicesGetService {
76	s.ignoreUnavailable = &ignoreUnavailable
77	return s
78}
79
80// AllowNoIndices indicates whether to ignore if a wildcard expression
81// resolves to no concrete indices (default: false).
82func (s *IndicesGetService) AllowNoIndices(allowNoIndices bool) *IndicesGetService {
83	s.allowNoIndices = &allowNoIndices
84	return s
85}
86
87// Pretty indicates that the JSON response be indented and human readable.
88func (s *IndicesGetService) Pretty(pretty bool) *IndicesGetService {
89	s.pretty = pretty
90	return s
91}
92
93// buildURL builds the URL for the operation.
94func (s *IndicesGetService) buildURL() (string, url.Values, error) {
95	var err error
96	var path string
97	var index []string
98
99	if len(s.index) > 0 {
100		index = s.index
101	} else {
102		index = []string{"_all"}
103	}
104
105	if len(s.feature) > 0 {
106		// Build URL
107		path, err = uritemplates.Expand("/{index}/{feature}", map[string]string{
108			"index":   strings.Join(index, ","),
109			"feature": strings.Join(s.feature, ","),
110		})
111	} else {
112		// Build URL
113		path, err = uritemplates.Expand("/{index}", map[string]string{
114			"index": strings.Join(index, ","),
115		})
116	}
117	if err != nil {
118		return "", url.Values{}, err
119	}
120
121	// Add query string parameters
122	params := url.Values{}
123	if s.pretty {
124		params.Set("pretty", "1")
125	}
126	if s.expandWildcards != "" {
127		params.Set("expand_wildcards", s.expandWildcards)
128	}
129	if s.local != nil {
130		params.Set("local", fmt.Sprintf("%v", *s.local))
131	}
132	if s.ignoreUnavailable != nil {
133		params.Set("ignore_unavailable", fmt.Sprintf("%v", *s.ignoreUnavailable))
134	}
135	if s.allowNoIndices != nil {
136		params.Set("allow_no_indices", fmt.Sprintf("%v", *s.allowNoIndices))
137	}
138	return path, params, nil
139}
140
141// Validate checks if the operation is valid.
142func (s *IndicesGetService) Validate() error {
143	var invalid []string
144	if len(s.index) == 0 {
145		invalid = append(invalid, "Index")
146	}
147	if len(invalid) > 0 {
148		return fmt.Errorf("missing required fields: %v", invalid)
149	}
150	return nil
151}
152
153// Do executes the operation.
154func (s *IndicesGetService) Do() (map[string]*IndicesGetResponse, error) {
155	// Check pre-conditions
156	if err := s.Validate(); err != nil {
157		return nil, err
158	}
159
160	// Get URL for request
161	path, params, err := s.buildURL()
162	if err != nil {
163		return nil, err
164	}
165
166	// Get HTTP response
167	res, err := s.client.PerformRequest("GET", path, params, nil)
168	if err != nil {
169		return nil, err
170	}
171
172	// Return operation response
173	var ret map[string]*IndicesGetResponse
174	if err := json.Unmarshal(res.Body, &ret); err != nil {
175		return nil, err
176	}
177	return ret, nil
178}
179
180// IndicesGetResponse is part of the response of IndicesGetService.Do.
181type IndicesGetResponse struct {
182	Aliases  map[string]interface{} `json:"aliases"`
183	Mappings map[string]interface{} `json:"mappings"`
184	Settings map[string]interface{} `json:"settings"`
185	Warmers  map[string]interface{} `json:"warmers"`
186}
187