Skip to content

Commit f3429a6

Browse files
committed
Refactors Meta Header
- Extracts meta header related code into a module - Adds more tests for specific situations when http libraries haven't been loaded by the time the meta header methods are called Related to #1224
1 parent 44283d4 commit f3429a6

File tree

3 files changed

+166
-76
lines changed

3 files changed

+166
-76
lines changed

elasticsearch-transport/lib/elasticsearch/transport/client.rb

Lines changed: 4 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
# under the License.
1717

1818
require 'base64'
19+
require 'elasticsearch/transport/meta_header'
1920

2021
module Elasticsearch
2122
module Transport
@@ -25,6 +26,7 @@ module Transport
2526
# See {file:README.md README} for usage and code examples.
2627
#
2728
class Client
29+
include MetaHeader
2830
DEFAULT_TRANSPORT_CLASS = Transport::HTTP::Faraday
2931

3032
DEFAULT_LOGGER = lambda do
@@ -165,13 +167,13 @@ def initialize(arguments={}, &block)
165167
@transport_class = @arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
166168
@transport = if @transport_class == Transport::HTTP::Faraday
167169
@arguments[:adapter] ||= __auto_detect_adapter
168-
set_meta_header
170+
set_meta_header # from include MetaHeader
169171
@transport_class.new(hosts: @seeds, options: @arguments) do |faraday|
170172
faraday.adapter(@arguments[:adapter])
171173
block&.call faraday
172174
end
173175
else
174-
set_meta_header
176+
set_meta_header # from include MetaHeader
175177
@transport_class.new(hosts: @seeds, options: @arguments)
176178
end
177179
end
@@ -206,78 +208,6 @@ def add_header(header)
206208
)
207209
end
208210

209-
def set_meta_header
210-
return if @arguments[:enable_meta_header] == false
211-
212-
service, version = meta_header_service_version
213-
214-
meta_headers = {
215-
service.to_sym => version,
216-
rb: RUBY_VERSION,
217-
t: Elasticsearch::Transport::VERSION
218-
}
219-
meta_headers.merge!(meta_header_engine) if meta_header_engine
220-
meta_headers.merge!(meta_header_adapter) if meta_header_adapter
221-
222-
add_header({ 'x-elastic-client-meta' => meta_headers.map { |k, v| "#{k}=#{v}" }.join(',') })
223-
end
224-
225-
def meta_header_service_version
226-
if defined?(Elastic::META_HEADER_SERVICE_VERSION)
227-
Elastic::META_HEADER_SERVICE_VERSION
228-
elsif defined?(Elasticsearch::VERSION)
229-
[:es, client_meta_version(Elasticsearch::VERSION)]
230-
else
231-
[:es, client_meta_version(Elasticsearch::Transport::VERSION)]
232-
end
233-
end
234-
235-
def client_meta_version(version)
236-
regexp = /^([0-9]+\.[0-9]+\.[0-9]+)(\.?[a-z0-9.-]+)?$/
237-
match = version.match(regexp)
238-
return "#{match[1]}p" if (match[2])
239-
240-
version
241-
end
242-
243-
def meta_header_engine
244-
case RUBY_ENGINE
245-
when 'ruby'
246-
{}
247-
when 'jruby'
248-
{ jv: ENV_JAVA['java.version'], jr: JRUBY_VERSION }
249-
when 'rbx'
250-
{ rbx: RUBY_VERSION }
251-
else
252-
{ RUBY_ENGINE.to_sym => RUBY_VERSION }
253-
end
254-
end
255-
256-
def meta_header_adapter
257-
if @transport_class == Transport::HTTP::Faraday
258-
{fd: Faraday::VERSION}.merge(
259-
case @arguments[:adapter]
260-
when :patron
261-
{pt: Patron::VERSION}
262-
when :net_http
263-
{nh: defined?(Net::HTTP::VERSION) ? Net::HTTP::VERSION : Net::HTTP::HTTPVersion}
264-
when :typhoeus
265-
{ty: Typhoeus::VERSION}
266-
when :httpclient
267-
{hc: HTTPClient::VERSION}
268-
when :net_http_persistent
269-
{np: Net::HTTP::Persistent::VERSION}
270-
else
271-
{}
272-
end
273-
)
274-
elsif defined?(Transport::HTTP::Curb) && @transport_class == Transport::HTTP::Curb
275-
{cl: Curl::CURB_VERSION}
276-
elsif defined?(Transport::HTTP::Manticore) && @transport_class == Transport::HTTP::Manticore
277-
{mc: Manticore::VERSION}
278-
end
279-
end
280-
281211
def extract_cloud_creds(arguments)
282212
return unless arguments[:cloud_id] && !arguments[:cloud_id].empty?
283213

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Licensed to Elasticsearch B.V. under one or more contributor
2+
# license agreements. See the NOTICE file distributed with
3+
# this work for additional information regarding copyright
4+
# ownership. Elasticsearch B.V. licenses this file to you under
5+
# the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
require 'base64'
19+
20+
module Elasticsearch
21+
module Transport
22+
23+
# Methods for the Elastic meta header used by Cloud.
24+
# X-Elastic-Client-Meta HTTP header which is used by Elastic Cloud and can be disabled when
25+
# instantiating the Client with the :enable_meta_header parameter set to `false`.
26+
#
27+
module MetaHeader
28+
def set_meta_header
29+
return if @arguments[:enable_meta_header] == false
30+
31+
service, version = meta_header_service_version
32+
33+
meta_headers = {
34+
service.to_sym => version,
35+
rb: RUBY_VERSION,
36+
t: Elasticsearch::Transport::VERSION
37+
}
38+
meta_headers.merge!(meta_header_engine) if meta_header_engine
39+
meta_headers.merge!(meta_header_adapter) if meta_header_adapter
40+
41+
add_header({ 'x-elastic-client-meta' => meta_headers.map { |k, v| "#{k}=#{v}" }.join(',') })
42+
end
43+
44+
def meta_header_service_version
45+
if defined?(Elastic::META_HEADER_SERVICE_VERSION)
46+
Elastic::META_HEADER_SERVICE_VERSION
47+
elsif defined?(Elasticsearch::VERSION)
48+
[:es, client_meta_version(Elasticsearch::VERSION)]
49+
else
50+
[:es, client_meta_version(Elasticsearch::Transport::VERSION)]
51+
end
52+
end
53+
54+
# We return the current version if it's a release, but if it's a pre/alpha/beta release we
55+
# return <VERSION_NUMBER>p
56+
#
57+
def client_meta_version(version)
58+
regexp = /^([0-9]+\.[0-9]+\.[0-9]+)(\.?[a-z0-9.-]+)?$/
59+
match = version.match(regexp)
60+
return "#{match[1]}p" if (match[2])
61+
62+
version
63+
end
64+
65+
def meta_header_engine
66+
case RUBY_ENGINE
67+
when 'ruby'
68+
{}
69+
when 'jruby'
70+
{ jv: ENV_JAVA['java.version'], jr: JRUBY_VERSION }
71+
when 'rbx'
72+
{ rbx: RUBY_VERSION }
73+
else
74+
{ RUBY_ENGINE.to_sym => RUBY_VERSION }
75+
end
76+
end
77+
78+
# This function tries to define the version for the Faraday adapter. If it hasn't been loaded
79+
# by the time we're calling this method, it's going to report the adapter (if we know it) but
80+
# return 0 as the version. It won't report anything when using a custom adapter we don't
81+
# identify.
82+
#
83+
# Returns a Hash<adapter_alias, version>
84+
#
85+
def meta_header_adapter
86+
if @transport_class == Transport::HTTP::Faraday
87+
version = '0'
88+
adapter_version = case @arguments[:adapter]
89+
when :patron
90+
version = Patron::VERSION if defined?(::Patron::VERSION)
91+
{pt: version}
92+
when :net_http
93+
version = if defined?(Net::HTTP::VERSION)
94+
Net::HTTP::VERSION
95+
elsif defined?(Net::HTTP::HTTPVersion)
96+
Net::HTTP::HTTPVersion
97+
end
98+
{nh: version}
99+
when :typhoeus
100+
version = Typhoeus::VERSION if defined?(::Typhoeus::VERSION)
101+
{ty: version}
102+
when :httpclient
103+
version = HTTPClient::VERSION if defined?(HTTPClient::VERSION)
104+
{hc: version}
105+
when :net_http_persistent
106+
version = Net::HTTP::Persistent::VERSION if defined?(Net::HTTP::Persistent::VERSION)
107+
{np: version}
108+
else
109+
{}
110+
end
111+
{fd: Faraday::VERSION}.merge(adapter_version)
112+
elsif defined?(Transport::HTTP::Curb) && @transport_class == Transport::HTTP::Curb
113+
{cl: Curl::CURB_VERSION}
114+
elsif defined?(Transport::HTTP::Manticore) && @transport_class == Transport::HTTP::Manticore
115+
{mc: Manticore::VERSION}
116+
end
117+
end
118+
end
119+
end
120+
end

elasticsearch-transport/spec/elasticsearch/transport/meta_header_spec.rb

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
end
3333
end
3434

35-
context 'client_meta_version_' do
35+
context 'client_meta_version' do
3636
let(:version) { ['7.1.0-alpha', '7.11.0.pre.1', '8.0.0-beta', '8.0.0.beta.2']}
3737

3838
it 'converts the version to X.X.Xp' do
@@ -108,6 +108,14 @@ def meta_version
108108
context 'using net/http/persistent' do
109109
let(:adapter) { :net_http_persistent }
110110

111+
it 'sets adapter in the meta header version to 0 when not loaded' do
112+
fork {
113+
expect(headers['x-elastic-client-meta']).to match(regexp)
114+
meta = "#{meta_header},np=0"
115+
expect(headers).to include('x-elastic-client-meta' => meta)
116+
}
117+
end unless jruby?
118+
111119
it 'sets adapter in the meta header' do
112120
require 'net/http/persistent'
113121
expect(headers['x-elastic-client-meta']).to match(regexp)
@@ -119,6 +127,14 @@ def meta_version
119127
context 'using httpclient' do
120128
let(:adapter) { :httpclient }
121129

130+
it 'sets adapter in the meta header version to 0 when not loaded' do
131+
fork {
132+
expect(headers['x-elastic-client-meta']).to match(regexp)
133+
meta = "#{meta_header},hc=0"
134+
expect(headers).to include('x-elastic-client-meta' => meta)
135+
}
136+
end unless jruby?
137+
122138
it 'sets adapter in the meta header' do
123139
require 'httpclient'
124140
expect(headers['x-elastic-client-meta']).to match(regexp)
@@ -130,6 +146,14 @@ def meta_version
130146
context 'using typhoeus' do
131147
let(:adapter) { :typhoeus }
132148

149+
it 'sets adapter in the meta header version to 0 when not loaded' do
150+
fork {
151+
expect(headers['x-elastic-client-meta']).to match(regexp)
152+
meta = "#{meta_header},ty=0"
153+
expect(headers).to include('x-elastic-client-meta' => meta)
154+
}
155+
end unless jruby?
156+
133157
it 'sets adapter in the meta header' do
134158
require 'typhoeus'
135159
expect(headers['x-elastic-client-meta']).to match(regexp)
@@ -138,9 +162,19 @@ def meta_version
138162
end
139163
end
140164

141-
unless defined?(JRUBY_VERSION)
165+
unless jruby?
142166
let(:adapter) { :patron }
143167

168+
context 'using patron without requiring it' do
169+
it 'sets adapter in the meta header version to 0 when not loaded' do
170+
fork {
171+
expect(headers['x-elastic-client-meta']).to match(regexp)
172+
meta = "#{meta_header},pt=0"
173+
expect(headers).to include('x-elastic-client-meta' => meta)
174+
}
175+
end
176+
end
177+
144178
context 'using patron' do
145179
it 'sets adapter in the meta header' do
146180
require 'patron'
@@ -154,6 +188,12 @@ def meta_version
154188
context 'using other' do
155189
let(:adapter) { :some_other_adapter }
156190

191+
it 'sets adapter in the meta header without requiring' do
192+
Faraday::Adapter.register_middleware some_other_adapter: Faraday::Adapter::NetHttpPersistent
193+
expect(headers['x-elastic-client-meta']).to match(regexp)
194+
expect(headers).to include('x-elastic-client-meta' => meta_header)
195+
end
196+
157197
it 'sets adapter in the meta header' do
158198
require 'net/http/persistent'
159199
Faraday::Adapter.register_middleware some_other_adapter: Faraday::Adapter::NetHttpPersistent

0 commit comments

Comments
 (0)