-
Notifications
You must be signed in to change notification settings - Fork 8.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use new elasticsearch-js client in Elasticsearch service #35508
Comments
Pinging @elastic/kibana-platform |
cc @delvedor |
Hello! Thank you for opening this :) You can find the entire breaking changes list here, it contains some code examples as well. Please feel free to ask any question if you have doubts! |
Ideas that have been discussed in various meetings, posting here so we don't lose them:
|
I think we should do both of those ideas. We should replace the implementation of callWithRequest/callWithInternalUser with the new client, which shouldn't break compatibility with existing code at all. Then we should expose the new client interface the way we want to expose it without functions in front of it. This way new code can use the client directly, existing code can migrate away from callWith* independently of their new platform migration, and really old code that is barely touched can just keep using the old stuff. |
It depends™. You can easily adapt the surface API, but the errors will be different, see the breaking changes document. I'm working on a module that makes compatible the surface API of the new client with the legacy one. I'm wondering if remap also the errors would be useful. |
I think having our abstraction on top of a client is still useful - we can follow our own update cycle, introduce custom logic in front of the client library, prevent monkey patching of the internals etc.
On the one hand, we can test the client library in real-world conditions. On the other hand, we have to implement a compatibility layer, that also requires some time to implement and cover with tests. @delvedor how hard would it be to finish work on https://github.com/elastic/elasticsearch-js-compatibility-mode/blob/master/index.js? Probably it makes sense for New platform elasticsearch service to expose 2 types of clients:
|
The new client has an API that allows you to extend it, and add new and custom APIs to it. doc. client.extend('customSearch', ({ makeRequest }) => {
return function customSearch (params, options) {
// your custom logic
makeRequest({ ... }) // send the request to Elasticsearch
}
})
client.customSearch({ ... }) Regarding wrapping the client with your already existing code, I tried to tackle that in #27051, but I wasn't happy with the solution since I ended up with a mixed old and new code, which was quite confusing. My suggestion would be to keep two separate clients, the legacy with its own wrapper, and the new one without any wrapper (or a very thin wrapper around it).
On the other hand, have two separate clients in this way probably may taker a longer time to finish the migration, but I still think that it's better, since the final result will be cleaner and less hacky.
It should be ready, but I cannot be sure it works in all cases until we try it in a codebase that is using the old client extensively. |
We have decided to punt on this a bit.
|
@joshdover I'm curious about your second point "once Platform Migration work is complete". When is this the case? We would like to already use the new client today in the package manager to for example load ILM policies. The new client has nice API's for this (https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/api-reference.html#_ilm_putlifecycle) but couldn't find it in the legacy one. We could work around this by writing the request ourself but would be nicer to directly use the new client. Is this possible? |
@ruflin At the very earliest, I think this could get prioritized in 3-5 months when the Platform team is not 100% focused on supporting plugin migrations to the Platform. The Platform migration is the top priority for the entire Kibana project and a blocker for 8.0 so we just can't justify spending time on much else right now. We also don't want to rush adding it now and not doing it in the right way. In the meantime, I suggest using the |
Sounds like a good reason to me, thanks for weighing in! 👍 |
This
Correct me if I'm wrong, but plugins leverage
My +1 for the newer version: autocomplete, type-safety, easier supported method discoverability.
I cannot find any usages in the existing code-base. Is it still a relevant API? @elastic/kibana-security
I agree with Josh. It might require even RFC to get input from a broad audience.
Let's not repeat the same mistake that has been done in the
interface ElasticSearchServiceStart {
getInternalClient: () => Client,
getScopedClient: (request) => Client,
} Client and ScopedClient aren't interchangeable. It's easy to make a mistake making a call on the wrong client. We will have to add an explicit type
+1 |
Based on experience and some discussion I've seen on Slack, my understanding is that I'm not entirely sure about how they compare in terms of tradeoffs. In terms of downsides, @kobelb mentioned this possible downside to using
I also found this PR (https://github.com/elastic/kibana/pull/68331/files) which highlights a mistake that's easy to make and difficult to discover when using |
It is. const client = new Client();
// request(params: TransportRequestParams, options?: TransportRequestOptions): Promise<ApiResponse>;
client.transport.request(/* */); Also note that the new ES client is supposed to have an exhaustive list of ES endpoint/commands. So I'm not even sure we would really have any need of using this, but I did not do an audit of current usages of custom plugins in our codebase. Does anyone have a better vision than me on that. @kobelb maybe? |
Maybe it's okay? Since it's meant to be used for development purposes only when you need to play around with a new experimental endpoint. When an endpoint officially supported, we bump the library version and use type-safe library API instead. |
That SGTM. I feel like we can wait and see if we really need to implement plugin support for the new client, as |
@delvedor Can new https://github.com/elastic/elasticsearch-js client work in browser env? I see this in the official repo https://github.com/elastic/bower-elasticsearch-js#submit-issues-pull-requests-etc-to-elasticsearch-js @elastic/kibana-app-arch Is there a specific reason why we need to use
Can we get rid of it on the client side? Data plugin proxies request to the server-side where the new ES client will be available anyway. |
@restrry the legacy client was compatible with the browser environment, the new one is not. The new client does support the entire Elasticsearch API surface, unless an API is not defined in the json spec here and here. |
We want to remove any usages of the legacy browser APIs. That effort is tracked here: #55139. Once that is completed we can get rid of the dependency altogether. |
This seems reasonable to me. I do think we should be minimizing the use of |
Monitoring uses it to configure connection to the custom index
This option has been introduced in #9583 to inform a user that request to ES has failed due to expired credentials and they need to log in again.
I'm surprised that we haven't got any issues reported so far. We need to decide whether we want to support this in KP at all. As I can see we aren't going to support use-cases with Security settings in Kibana and ES. So the next question is whether we want to support auth via intermediate proxy between Kibana and ES. That would require handling 401 errors on the platform level:
try {
// call route handler
} catch (e) {
this.log.error(e);
if(is401Error(e)) {
const wwwAuthHeader = get(error, 'body.error.header[WWW-Authenticate]') || 'Basic realm="Authorization Required"'
return response.unauthorized({ headers: {
'WWW-Authenticate': wwwAuthHeader
}});
}
return hapiResponseAdapter.toInternalError();
} |
The elasticsearch-js client library we've been using for years is now deprecated, and the new node library has been published: https://github.com/elastic/elasticsearch-js
We should move our server-side Elasticsearch service over to use this new client. We might still need to use the legacy client at the same time for certain pieces of functionality that we can't easily switch over yet, but there should be no problem using them at the same time.
Since most code is consuming ES through
callWithRequest
orcallWithInternalUser
, swapping out the underlying client should be doable without significant changes in plugins.Once this initial issue is wrapped up, we can then expose the new client directly and deprecate the
callWithRequest
andcallWithInternalUser
abstractions.Subtasks
/legacy/
subfolder and prefix them withLegacy
- Move and rename legacy elasticsearch client #69797 Rename legacy ES mock accessors #70432x-opaque-id
forwarding for the new clientThe text was updated successfully, but these errors were encountered: