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	"net/url"
11
12	"gopkg.in/olivere/elastic.v2/uritemplates"
13)
14
15// IndicesPutTemplateService creates or updates index mappings.
16// See http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.4/indices-templates.html.
17type IndicesPutTemplateService struct {
18	client        *Client
19	pretty        bool
20	name          string
21	order         interface{}
22	create        *bool
23	timeout       string
24	masterTimeout string
25	flatSettings  *bool
26	bodyJson      interface{}
27	bodyString    string
28}
29
30// NewIndicesPutTemplateService creates a new IndicesPutTemplateService.
31func NewIndicesPutTemplateService(client *Client) *IndicesPutTemplateService {
32	return &IndicesPutTemplateService{
33		client: client,
34	}
35}
36
37// Name is the name of the index template.
38func (s *IndicesPutTemplateService) Name(name string) *IndicesPutTemplateService {
39	s.name = name
40	return s
41}
42
43// Timeout is an explicit operation timeout.
44func (s *IndicesPutTemplateService) Timeout(timeout string) *IndicesPutTemplateService {
45	s.timeout = timeout
46	return s
47}
48
49// MasterTimeout specifies the timeout for connection to master.
50func (s *IndicesPutTemplateService) MasterTimeout(masterTimeout string) *IndicesPutTemplateService {
51	s.masterTimeout = masterTimeout
52	return s
53}
54
55// FlatSettings indicates whether to return settings in flat format (default: false).
56func (s *IndicesPutTemplateService) FlatSettings(flatSettings bool) *IndicesPutTemplateService {
57	s.flatSettings = &flatSettings
58	return s
59}
60
61// Order is the order for this template when merging multiple matching ones
62// (higher numbers are merged later, overriding the lower numbers).
63func (s *IndicesPutTemplateService) Order(order interface{}) *IndicesPutTemplateService {
64	s.order = order
65	return s
66}
67
68// Create indicates whether the index template should only be added if
69// new or can also replace an existing one.
70func (s *IndicesPutTemplateService) Create(create bool) *IndicesPutTemplateService {
71	s.create = &create
72	return s
73}
74
75// Pretty indicates that the JSON response be indented and human readable.
76func (s *IndicesPutTemplateService) Pretty(pretty bool) *IndicesPutTemplateService {
77	s.pretty = pretty
78	return s
79}
80
81// BodyJson is documented as: The template definition.
82func (s *IndicesPutTemplateService) BodyJson(body interface{}) *IndicesPutTemplateService {
83	s.bodyJson = body
84	return s
85}
86
87// BodyString is documented as: The template definition.
88func (s *IndicesPutTemplateService) BodyString(body string) *IndicesPutTemplateService {
89	s.bodyString = body
90	return s
91}
92
93// buildURL builds the URL for the operation.
94func (s *IndicesPutTemplateService) buildURL() (string, url.Values, error) {
95	// Build URL
96	path, err := uritemplates.Expand("/_template/{name}", map[string]string{
97		"name": s.name,
98	})
99	if err != nil {
100		return "", url.Values{}, err
101	}
102
103	// Add query string parameters
104	params := url.Values{}
105	if s.pretty {
106		params.Set("pretty", "1")
107	}
108	if s.order != nil {
109		params.Set("order", fmt.Sprintf("%v", s.order))
110	}
111	if s.create != nil {
112		params.Set("create", fmt.Sprintf("%v", *s.create))
113	}
114	if s.timeout != "" {
115		params.Set("timeout", s.timeout)
116	}
117	if s.masterTimeout != "" {
118		params.Set("master_timeout", s.masterTimeout)
119	}
120	if s.flatSettings != nil {
121		params.Set("flat_settings", fmt.Sprintf("%v", *s.flatSettings))
122	}
123	return path, params, nil
124}
125
126// Validate checks if the operation is valid.
127func (s *IndicesPutTemplateService) Validate() error {
128	var invalid []string
129	if s.name == "" {
130		invalid = append(invalid, "Name")
131	}
132	if s.bodyString == "" && s.bodyJson == nil {
133		invalid = append(invalid, "BodyJson")
134	}
135	if len(invalid) > 0 {
136		return fmt.Errorf("missing required fields: %v", invalid)
137	}
138	return nil
139}
140
141// Do executes the operation.
142func (s *IndicesPutTemplateService) Do() (*IndicesPutTemplateResponse, error) {
143	// Check pre-conditions
144	if err := s.Validate(); err != nil {
145		return nil, err
146	}
147
148	// Get URL for request
149	path, params, err := s.buildURL()
150	if err != nil {
151		return nil, err
152	}
153
154	// Setup HTTP request body
155	var body interface{}
156	if s.bodyJson != nil {
157		body = s.bodyJson
158	} else {
159		body = s.bodyString
160	}
161
162	// Get HTTP response
163	res, err := s.client.PerformRequest("PUT", path, params, body)
164	if err != nil {
165		return nil, err
166	}
167
168	// Return operation response
169	ret := new(IndicesPutTemplateResponse)
170	if err := json.Unmarshal(res.Body, ret); err != nil {
171		return nil, err
172	}
173	return ret, nil
174}
175
176// IndicesPutTemplateResponse is the response of IndicesPutTemplateService.Do.
177type IndicesPutTemplateResponse struct {
178	Acknowledged bool `json:"acknowledged,omitempty"`
179}
180