Skip to content

Commit 45f08e4

Browse files
authored
[Client] Incorporate metaheader into the client, use version from transport (#387) (#388)
* Incorporate metaheader into the client, use version from transport
1 parent 2695c1c commit 45f08e4

File tree

4 files changed

+156
-204
lines changed

4 files changed

+156
-204
lines changed

elasticsearch.go

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/elastic/go-elasticsearch/v8/internal/version"
3636

3737
"github.com/elastic/elastic-transport-go/v8/elastictransport"
38+
tpversion "github.com/elastic/elastic-transport-go/v8/elastictransport/version"
3839
)
3940

4041
const (
@@ -43,12 +44,17 @@ const (
4344
// Version returns the package version as a string.
4445
Version = version.Client
4546
unknownProduct = "the client noticed that the server is not Elasticsearch and we do not support this unknown product"
47+
48+
// HeaderClientMeta Key for the HTTP Header related to telemetry data sent with
49+
// each request to Elasticsearch.
50+
HeaderClientMeta = "x-elastic-client-meta"
4651
)
4752

4853
var (
4954
esCompatHeader = "ELASTIC_CLIENT_APIVERSIONING"
5055
userAgent string
5156
reGoVersion = regexp.MustCompile(`go(\d+\.\d+\..+)`)
57+
reMetaVersion = regexp.MustCompile("([0-9.]+)(.*)")
5258
)
5359

5460
func init() {
@@ -105,6 +111,7 @@ type Config struct {
105111
type Client struct {
106112
*esapi.API // Embeds the API methods
107113
Transport elastictransport.Interface
114+
metaHeader string
108115
compatibilityHeader bool
109116

110117
disableMetaHeader bool
@@ -216,6 +223,7 @@ func NewClient(cfg Config) (*Client, error) {
216223
client := &Client{
217224
Transport: tp,
218225
disableMetaHeader: cfg.DisableMetaHeader,
226+
metaHeader: initMetaHeader(tp),
219227
compatibilityHeader: cfg.EnableCompatibilityMode || compatibilityHeader,
220228
}
221229
client.API = esapi.New(client)
@@ -239,9 +247,9 @@ func (c *Client) Perform(req *http.Request) (*http.Response, error) {
239247
if !c.disableMetaHeader {
240248
existingMetaHeader := req.Header.Get(HeaderClientMeta)
241249
if existingMetaHeader != "" {
242-
req.Header.Set(HeaderClientMeta, strings.Join([]string{metaHeader, existingMetaHeader}, ","))
250+
req.Header.Set(HeaderClientMeta, strings.Join([]string{c.metaHeader, existingMetaHeader}, ","))
243251
} else {
244-
req.Header.Add(HeaderClientMeta, metaHeader)
252+
req.Header.Add(HeaderClientMeta, c.metaHeader)
245253
}
246254
} else {
247255
req.Header.Del(HeaderClientMeta)
@@ -392,3 +400,61 @@ func initUserAgent() string {
392400

393401
return b.String()
394402
}
403+
404+
func initMetaHeader(transport interface{}) string {
405+
var b strings.Builder
406+
var strippedGoVersion string
407+
var strippedEsVersion string
408+
var strippedTransportVersion string
409+
410+
strippedEsVersion = buildStrippedVersion(Version)
411+
strippedGoVersion = buildStrippedVersion(runtime.Version())
412+
413+
if _, ok := transport.(*elastictransport.Client); ok {
414+
strippedTransportVersion = buildStrippedVersion(tpversion.Transport)
415+
} else {
416+
strippedTransportVersion = strippedEsVersion
417+
}
418+
419+
var duos = [][]string{
420+
{
421+
"es",
422+
strippedEsVersion,
423+
},
424+
{
425+
"go",
426+
strippedGoVersion,
427+
},
428+
{
429+
"t",
430+
strippedTransportVersion,
431+
},
432+
{
433+
"hc",
434+
strippedGoVersion,
435+
},
436+
}
437+
438+
var arr []string
439+
for _, duo := range duos {
440+
arr = append(arr, strings.Join(duo, "="))
441+
}
442+
b.WriteString(strings.Join(arr, ","))
443+
444+
return b.String()
445+
}
446+
447+
func buildStrippedVersion(version string) string {
448+
v := reMetaVersion.FindStringSubmatch(version)
449+
450+
if len(v) == 3 && !strings.Contains(version, "devel") {
451+
switch {
452+
case v[2] != "":
453+
return v[1] + "p"
454+
default:
455+
return v[1]
456+
}
457+
}
458+
459+
return "0.0p"
460+
}

elasticsearch_internal_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/elastic/elastic-transport-go/v8/elastictransport"
4040
)
4141

42+
var metaHeaderReValidation = regexp.MustCompile(`^[a-z]{1,}=[a-z0-9\.\-]{1,}(?:,[a-z]{1,}=[a-z0-9\.\-]+)*$`)
4243
var called bool
4344

4445
type mockTransp struct {
@@ -650,3 +651,90 @@ func TestCompatibilityHeader(t *testing.T) {
650651
})
651652
}
652653
}
654+
655+
func TestBuildStrippedVersion(t *testing.T) {
656+
type args struct {
657+
version string
658+
}
659+
tests := []struct {
660+
name string
661+
args args
662+
want string
663+
}{
664+
{
665+
name: "Standard Go version",
666+
args: args{version: "go1.16"},
667+
want: "1.16",
668+
},
669+
{
670+
name: "Rc Go version",
671+
args: args{
672+
version: "go1.16rc1",
673+
},
674+
want: "1.16p",
675+
},
676+
{
677+
name: "Beta Go version (go1.16beta1 example)",
678+
args: args{
679+
version: "devel +2ff33f5e44 Thu Dec 17 16:03:19 2020 +0000",
680+
},
681+
want: "0.0p",
682+
},
683+
{
684+
name: "Random mostly good Go version",
685+
args: args{
686+
version: "1.16",
687+
},
688+
want: "1.16",
689+
},
690+
{
691+
name: "Client package version",
692+
args: args{
693+
version: "8.0.0",
694+
},
695+
want: "8.0.0",
696+
},
697+
{
698+
name: "Client pre release version",
699+
args: args{
700+
version: "8.0.0-SNAPSHOT",
701+
},
702+
want: "8.0.0p",
703+
},
704+
}
705+
for _, tt := range tests {
706+
t.Run(tt.name, func(t *testing.T) {
707+
if got := buildStrippedVersion(tt.args.version); got != tt.want {
708+
t.Errorf("buildStrippedVersion() = %v, want %v", got, tt.want)
709+
}
710+
})
711+
}
712+
}
713+
714+
func TestMetaHeader(t *testing.T) {
715+
t.Run("MetaHeader with elastictransport", func(t *testing.T) {
716+
tp, _ := elastictransport.New(elastictransport.Config{
717+
URLs: []*url.URL{{Scheme: "http", Host: "foo"}},
718+
Transport: &mockTransp{
719+
RoundTripFunc: func(request *http.Request) (*http.Response, error) {
720+
h := request.Header.Get(HeaderClientMeta)
721+
if !metaHeaderReValidation.MatchString(h) {
722+
t.Errorf("expected client metaheader to validate regexp, got: %s", h)
723+
}
724+
725+
return &http.Response{
726+
Header: http.Header{"X-Elastic-Product": []string{"Elasticsearch"}},
727+
StatusCode: http.StatusOK,
728+
Status: "OK",
729+
Body: ioutil.NopCloser(strings.NewReader("")),
730+
}, nil
731+
},
732+
},
733+
})
734+
735+
c, _ := NewDefaultClient()
736+
c.Transport = tp
737+
738+
_, _ = c.Info()
739+
})
740+
}

metaheader.go

Lines changed: 0 additions & 88 deletions
This file was deleted.

0 commit comments

Comments
 (0)