Skip to content
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

kibanaResponseFactory should support entirely custom responses #65045

Closed
gmmorris opened this issue May 4, 2020 · 8 comments
Closed

kibanaResponseFactory should support entirely custom responses #65045

gmmorris opened this issue May 4, 2020 · 8 comments
Labels
enhancement New value added to drive a business result Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc

Comments

@gmmorris
Copy link
Contributor

gmmorris commented May 4, 2020

Our Acceptance Tests rely on fixtures which simulate 3rd party services that we need to interact with, such as the public Slack or Pageduty APIs.

These APIs implement http responses which are different than a standard Kibana response and at times that means that I need my plugin to respond with an http error code and some custom body.

I was hoping that kibanaResponseFactory.customError and kibanaResponseFactory.custom will be enough, but there are various assumptions baked in (such as an error response code receiving an Error type with a message prop - assumptions which aren’t true in the Slack or Pageduty APIs.

After discussing this on Slack with @rudolf and @restrry we agreed that there should probably be a way (either via a new API or by relaxing kibanaResponseFactory.custom) to allow a response with an error code (such as 429) and an entirely custom object (that isn’t an Error type as currently required).

@gmmorris gmmorris added the Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc label May 4, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@rudolf
Copy link
Contributor

rudolf commented May 5, 2020

It's ugly and undocumented, but at least as a workaround returning a Buffer or Stream body will skip the validation and error wrapping.

return response.custom({
  body: Buffer.from('ok'),
  statusCode: 429,
})

// Special case for when we are proxying requests and want to enable streaming back error responses opaquely.
if (Buffer.isBuffer(payload) || payload instanceof stream.Readable) {
const response = this.responseToolkit
.response(kibanaResponse.payload)
.code(kibanaResponse.status);
setHeaders(response, kibanaResponse.options.headers);
return response;
}

@pgayvallet pgayvallet added the enhancement New value added to drive a business result label May 6, 2020
gmmorris added a commit that referenced this issue May 6, 2020
…4888)

This PR migrates the vast majority of Alerting legacy code to the Kibana Platform.

This includes:

1. Removed legacy Task Manager
2. Migrates Fixture plugins in Alerting, Triggers UI and Task Manager Perf

This does not includes:

1. The PagerDuty simulator due to a lack of support for custom responses in the platform. issue opened. #65045
2. The Webhooks simulator due to a lack of support for custom authorisation. Requires investigation.
gmmorris added a commit to gmmorris/kibana that referenced this issue May 6, 2020
…astic#64888)

This PR migrates the vast majority of Alerting legacy code to the Kibana Platform.

This includes:

1. Removed legacy Task Manager
2. Migrates Fixture plugins in Alerting, Triggers UI and Task Manager Perf

This does not includes:

1. The PagerDuty simulator due to a lack of support for custom responses in the platform. issue opened. elastic#65045
2. The Webhooks simulator due to a lack of support for custom authorisation. Requires investigation.
# Conflicts:
#	renovate.json5
#	x-pack/index.js
gmmorris added a commit that referenced this issue May 6, 2020
…4888) (#65430)

This PR migrates the vast majority of Alerting legacy code to the Kibana Platform.

This includes:

1. Removed legacy Task Manager
2. Migrates Fixture plugins in Alerting, Triggers UI and Task Manager Perf

This does not includes:

1. The PagerDuty simulator due to a lack of support for custom responses in the platform. issue opened. #65045
2. The Webhooks simulator due to a lack of support for custom authorisation. Requires investigation.
@pgayvallet
Copy link
Contributor

Follow-up of rudolf's snippet is:

// we use for BWC with Boom payload for error responses - {error: string, message: string, statusCode: string}
const error = new Boom('', {
statusCode: kibanaResponse.status,
});
error.output.payload.message = getErrorMessage(payload);
const attributes = getErrorAttributes(payload);
if (attributes) {
error.output.payload.attributes = attributes;
}
const headers = kibanaResponse.options.headers;
if (headers) {
// Hapi typings for header accept only strings, although string[] is a valid value
error.output.headers = headers as any;
}

We would need a way to opt-out from this conversion.

Maybe a new option on CustomHttpResponseOptions + HttpResponseOptions, such as convertErrors? that would default to true?

@mshustov
Copy link
Contributor

mshustov commented May 11, 2020

Maybe a new option on CustomHttpResponseOptions + HttpResponseOptions, such as convertErrors? that would default to true?

We will have to maintain it in the long term. We are going to formalize error response in the future #57296 but this case requires full freedom to customize error format. I don't think we want to give such a possibility to any plugin.
Probably we shouldn't provide such API in whole Kibana, but extend test utils somehow? Or adopt alerting plugin tests to use another HTTP server (Hapi?) instead of relying on Kibana API?

@pgayvallet
Copy link
Contributor

I don't think we want to give such a possibility to any plugin.

For standard use cases, I agree 100%.

But in some cases, we might need it? In example, a plugin used as a proxy to any arbitrary API/endpoint and forwarding responses as-is to the client-side is something that should not be permitted?

@rudolf
Copy link
Contributor

rudolf commented May 11, 2020

Alerting's use case is just for testing and I think that could easily be converted not to use Core API's but rather a standalone hapi server for instance. However, the Console app needs to proxy requests to Elasticsearch and should return responses in the original error format. We could "wrap" these errors in Core and let the frontend unwrap the errors to expose the real ES error. But there's a balance between enforcing consistent error responses and the complexity of having to work around it for valid use cases.

I lean towards promoting strong conventions, but having some escape hatches for the few cases that might come up where it makes sense to break the convention.

@joshdover
Copy link
Contributor

joshdover commented May 11, 2020

I generally agree, these tests should use a different HTTP server API than Core.

For the proxying use case I think we should provide proxying out-of-the-box directly, rather than adding an escape hatch. Not that I'm 100% against an escape hatch, I'd just rather not add it unless we really need it and there's other good reasons to introduce proxying as a first-class feature.

Should we close this issue if we're in agreement on these tests being ported to a different HTTP server API?

@mshustov
Copy link
Contributor

Closed. The recommended solution for this particular use-case is to switch to another HTTP server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New value added to drive a business result Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc
Projects
None yet
Development

No branches or pull requests

6 participants