1package elastic
2
3import (
4	"context"
5	"fmt"
6	"net/http"
7	"net/url"
8	"strings"
9
10	"github.com/olivere/elastic/uritemplates"
11)
12
13// TasksGetTaskService retrieves the state of a task in the cluster. It is part of the Task Management API
14// documented at http://www.elastic.co/guide/en/elasticsearch/reference/5.2/tasks-list.html.
15//
16// It is supported as of Elasticsearch 2.3.0.
17type TasksGetTaskService struct {
18	client *Client
19
20	pretty     *bool       // pretty format the returned JSON response
21	human      *bool       // return human readable values for statistics
22	errorTrace *bool       // include the stack trace of returned errors
23	filterPath []string    // list of filters used to reduce the response
24	headers    http.Header // custom request-level HTTP headers
25
26	taskId            string
27	waitForCompletion *bool
28}
29
30// NewTasksGetTaskService creates a new TasksGetTaskService.
31func NewTasksGetTaskService(client *Client) *TasksGetTaskService {
32	return &TasksGetTaskService{
33		client: client,
34	}
35}
36
37// Pretty tells Elasticsearch whether to return a formatted JSON response.
38func (s *TasksGetTaskService) Pretty(pretty bool) *TasksGetTaskService {
39	s.pretty = &pretty
40	return s
41}
42
43// Human specifies whether human readable values should be returned in
44// the JSON response, e.g. "7.5mb".
45func (s *TasksGetTaskService) Human(human bool) *TasksGetTaskService {
46	s.human = &human
47	return s
48}
49
50// ErrorTrace specifies whether to include the stack trace of returned errors.
51func (s *TasksGetTaskService) ErrorTrace(errorTrace bool) *TasksGetTaskService {
52	s.errorTrace = &errorTrace
53	return s
54}
55
56// FilterPath specifies a list of filters used to reduce the response.
57func (s *TasksGetTaskService) FilterPath(filterPath ...string) *TasksGetTaskService {
58	s.filterPath = filterPath
59	return s
60}
61
62// Header adds a header to the request.
63func (s *TasksGetTaskService) Header(name string, value string) *TasksGetTaskService {
64	if s.headers == nil {
65		s.headers = http.Header{}
66	}
67	s.headers.Add(name, value)
68	return s
69}
70
71// Headers specifies the headers of the request.
72func (s *TasksGetTaskService) Headers(headers http.Header) *TasksGetTaskService {
73	s.headers = headers
74	return s
75}
76
77// TaskId specifies the task to return. Notice that the caller is responsible
78// for using the correct format, i.e. node_id:task_number, as specified in
79// the REST API.
80func (s *TasksGetTaskService) TaskId(taskId string) *TasksGetTaskService {
81	s.taskId = taskId
82	return s
83}
84
85// TaskIdFromNodeAndId indicates to return the task on the given node with specified id.
86func (s *TasksGetTaskService) TaskIdFromNodeAndId(nodeId string, id int64) *TasksGetTaskService {
87	s.taskId = fmt.Sprintf("%s:%d", nodeId, id)
88	return s
89}
90
91// WaitForCompletion indicates whether to wait for the matching tasks
92// to complete (default: false).
93func (s *TasksGetTaskService) WaitForCompletion(waitForCompletion bool) *TasksGetTaskService {
94	s.waitForCompletion = &waitForCompletion
95	return s
96}
97
98// buildURL builds the URL for the operation.
99func (s *TasksGetTaskService) buildURL() (string, url.Values, error) {
100	// Build URL
101	path, err := uritemplates.Expand("/_tasks/{task_id}", map[string]string{
102		"task_id": s.taskId,
103	})
104	if err != nil {
105		return "", url.Values{}, err
106	}
107
108	// Add query string parameters
109	params := url.Values{}
110	if v := s.pretty; v != nil {
111		params.Set("pretty", fmt.Sprint(*v))
112	}
113	if v := s.human; v != nil {
114		params.Set("human", fmt.Sprint(*v))
115	}
116	if v := s.errorTrace; v != nil {
117		params.Set("error_trace", fmt.Sprint(*v))
118	}
119	if len(s.filterPath) > 0 {
120		params.Set("filter_path", strings.Join(s.filterPath, ","))
121	}
122	if s.waitForCompletion != nil {
123		params.Set("wait_for_completion", fmt.Sprintf("%v", *s.waitForCompletion))
124	}
125	return path, params, nil
126}
127
128// Validate checks if the operation is valid.
129func (s *TasksGetTaskService) Validate() error {
130	return nil
131}
132
133// Do executes the operation.
134func (s *TasksGetTaskService) Do(ctx context.Context) (*TasksGetTaskResponse, error) {
135	// Check pre-conditions
136	if err := s.Validate(); err != nil {
137		return nil, err
138	}
139
140	// Get URL for request
141	path, params, err := s.buildURL()
142	if err != nil {
143		return nil, err
144	}
145
146	// Get HTTP response
147	res, err := s.client.PerformRequest(ctx, PerformRequestOptions{
148		Method:  "GET",
149		Path:    path,
150		Params:  params,
151		Headers: s.headers,
152	})
153	if err != nil {
154		return nil, err
155	}
156
157	// Return operation response
158	ret := new(TasksGetTaskResponse)
159	if err := s.client.decoder.Decode(res.Body, ret); err != nil {
160		return nil, err
161	}
162	ret.Header = res.Header
163	return ret, nil
164}
165
166type TasksGetTaskResponse struct {
167	Header    http.Header `json:"-"`
168	Completed bool        `json:"completed"`
169	Task      *TaskInfo   `json:"task,omitempty"`
170}
171