Skip to content

Implement an interface for the elasticsearch client#2974

Merged
jalvz merged 2 commits intoelastic:masterfrom
jalvz:versioned-elasticsearch
Nov 29, 2019
Merged

Implement an interface for the elasticsearch client#2974
jalvz merged 2 commits intoelastic:masterfrom
jalvz:versioned-elasticsearch

Conversation

@jalvz
Copy link
Copy Markdown
Contributor

@jalvz jalvz commented Nov 27, 2019

The objective is to keep master and release branches as close as possible, facilitate backports over time, and isolate API breaking changes in one single file when they come around; allowing the rest of the code to be blissfully ignorant of the Elasticsearch API.

This presents a couple of minor drawbacks: requiring an extra dependency (2 versions of the client) and some code duplication.

While this is not pretty, in the face of pragmatism I think it is OK: the weight of the extra dependency is negligible, and the duplicated bits are trivial.

The resulting code is still concise IMO, and we will eventually have to duplicate some bits any ways.
We rather lay the ground for it now and maintain the rest of the code oblivious to elasticsearch versions.

Fixes #2967

@jalvz jalvz requested a review from simitt November 27, 2019 11:32
return nil, nil, err
}
// NewVersionedClient returns the right elasticsearch client for the current Stack version, as an interface
func NewVersionedClient(user, pwd string, addresses []string, transport http.RoundTripper) (Client, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion the main driver for this should be compatibility of APM Server with Elasticsearch, for the latest minor of the last major and the first minor of the next major version.
I don't see how this is achieved with this PR. The version.GetDefaultVersion() returns the defaultBeatVersion which will be the same for the running APM Server, independent of the Elasticsearch instances it is talking to.
In my opinion what would need to happen is that for every given ES address a request would be required to fetch the Elasticsearch version and then depending on that a client can be constructed. This would still open a couple of questions, like how to behave if the instances are running different versions, how to behave on upgrades, etc.

The second motivation for abstracting away the original elasticsearch client to keep backports to a minimum is not a strong motivation in my opinion. If the v7/v8 clients behave differently we will also need to implement both behaviours with this abstraction. I don't see a big difference effort wise, compared to changing the logic in the backport, except that the import would need to be updated for the version.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to mention that the actual logic to address that compatibility issue is out the scope of this PR, since it is not so urgent.
This PR lays out the ground for it, I created a follow up ticket #2975

@codecov-io
Copy link
Copy Markdown

codecov-io commented Nov 27, 2019

Codecov Report

Merging #2974 into master will decrease coverage by 0.44%.
The diff coverage is 59.04%.

@@            Coverage Diff             @@
##           master    #2974      +/-   ##
==========================================
- Coverage   78.74%   78.29%   -0.45%     
==========================================
  Files          84       85       +1     
  Lines        4380     4414      +34     
==========================================
+ Hits         3449     3456       +7     
- Misses        931      958      +27
Impacted Files Coverage Δ
sourcemap/store.go 91.3% <100%> (ø) ⬆️
elasticsearch/client.go 34% <36.17%> (-35.65%) ⬇️
elasticsearch/config.go 76.08% <76.08%> (ø)
sourcemap/es_store.go 85.89% <81.81%> (-1.01%) ⬇️

@jalvz
Copy link
Copy Markdown
Contributor Author

jalvz commented Nov 28, 2019

@simitt what changes are you requesting here?

@simitt
Copy link
Copy Markdown
Contributor

simitt commented Nov 28, 2019

I requested changes together with my PR review comment #2974 (comment). Haven't come around to another round of review yet.

// under the License.

package test
package estest
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the rename? The test package is already inside the elasticsearch path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was an easy way to avoid an unneeded import alias (eg f26d615#diff-2b990608de1ddbd3f6ec60d8b0e68f25R33)
It also seems to be conventional (eg. see httptest inside http I assume for the same reason https://golang.org/pkg/net/http/httptest/), but I can revert if you feel strong about it.

I pushed changes for the other comments

Addresses: addresses,
Transport: transport,
})
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newClient methods should be moved to client.go.

proxy func(*http.Request) (*url.URL, error)
dialer transport.Dialer
tlsDialer transport.Dialer
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proxy, dialer and tlsDialer are only used for creating the http.Transport. How about not introducing another struct but just a function httpTransport(config *Config) (*http.Transport, error)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it was also for addresses, but i changed it anyways

tlsDialer, err := transport.TLSDialer(dialer, tlsConfig, cfg.Timeout)
return dialer, tlsDialer, err
c, err := newV7Client(user, pwd, addresses, transport)
return clientV7{c}, err
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test for the versioned client? The easiest thing for now would probably be to expect a v8 client on master and a v7 one on 7.x.

@jalvz jalvz force-pushed the versioned-elasticsearch branch from d92ed4e to f04e7af Compare November 29, 2019 08:09
…rsion differences.

The objective is to keep master and release branches as close as possible, facilitate backports over time, and isolate API breaking changes in one single file when they come around; allowing the rest of the code to be blissfully ignorant of the Elasticsearch API.

Fixes elastic#2967
@jalvz jalvz force-pushed the versioned-elasticsearch branch from f04e7af to f503a47 Compare November 29, 2019 08:11
@jalvz jalvz merged commit 9dbfc0d into elastic:master Nov 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Abstract elasticsearch client versions

3 participants