summaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/olivere/elastic.v5/ping.go
blob: a97ddeceb4f6c0d88aa22eb1998d878979b9aece (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2012-present Oliver Eilhard. All rights reserved.
// Use of this source code is governed by a MIT-license.
// See http://olivere.mit-license.org/license.txt for details.

package elastic

import (
	"context"
	"encoding/json"
	"net/http"
	"net/url"
)

// PingService checks if an Elasticsearch server on a given URL is alive.
// When asked for, it can also return various information about the
// Elasticsearch server, e.g. the Elasticsearch version number.
//
// Ping simply starts a HTTP GET request to the URL of the server.
// If the server responds with HTTP Status code 200 OK, the server is alive.
type PingService struct {
	client       *Client
	url          string
	timeout      string
	httpHeadOnly bool
	pretty       bool
}

// PingResult is the result returned from querying the Elasticsearch server.
type PingResult struct {
	Name        string `json:"name"`
	ClusterName string `json:"cluster_name"`
	Version     struct {
		Number         string `json:"number"`
		BuildHash      string `json:"build_hash"`
		BuildTimestamp string `json:"build_timestamp"`
		BuildSnapshot  bool   `json:"build_snapshot"`
		LuceneVersion  string `json:"lucene_version"`
	} `json:"version"`
	TagLine string `json:"tagline"`
}

func NewPingService(client *Client) *PingService {
	return &PingService{
		client:       client,
		url:          DefaultURL,
		httpHeadOnly: false,
		pretty:       false,
	}
}

func (s *PingService) URL(url string) *PingService {
	s.url = url
	return s
}

func (s *PingService) Timeout(timeout string) *PingService {
	s.timeout = timeout
	return s
}

// HeadOnly makes the service to only return the status code in Do;
// the PingResult will be nil.
func (s *PingService) HttpHeadOnly(httpHeadOnly bool) *PingService {
	s.httpHeadOnly = httpHeadOnly
	return s
}

func (s *PingService) Pretty(pretty bool) *PingService {
	s.pretty = pretty
	return s
}

// Do returns the PingResult, the HTTP status code of the Elasticsearch
// server, and an error.
func (s *PingService) Do(ctx context.Context) (*PingResult, int, error) {
	s.client.mu.RLock()
	basicAuth := s.client.basicAuth
	basicAuthUsername := s.client.basicAuthUsername
	basicAuthPassword := s.client.basicAuthPassword
	s.client.mu.RUnlock()

	url_ := s.url + "/"

	params := make(url.Values)
	if s.timeout != "" {
		params.Set("timeout", s.timeout)
	}
	if s.pretty {
		params.Set("pretty", "1")
	}
	if len(params) > 0 {
		url_ += "?" + params.Encode()
	}

	var method string
	if s.httpHeadOnly {
		method = "HEAD"
	} else {
		method = "GET"
	}

	// Notice: This service must NOT use PerformRequest!
	req, err := NewRequest(method, url_)
	if err != nil {
		return nil, 0, err
	}

	if basicAuth {
		req.SetBasicAuth(basicAuthUsername, basicAuthPassword)
	}

	res, err := s.client.c.Do((*http.Request)(req).WithContext(ctx))
	if err != nil {
		return nil, 0, err
	}
	defer res.Body.Close()

	var ret *PingResult
	if !s.httpHeadOnly {
		ret = new(PingResult)
		if err := json.NewDecoder(res.Body).Decode(ret); err != nil {
			return nil, res.StatusCode, err
		}
	}

	return ret, res.StatusCode, nil
}