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

[Connector API] Null request body should result in 400 status code when body is required #109965

Merged
merged 5 commits into from
Jun 25, 2024

Conversation

jedrazb
Copy link
Member

@jedrazb jedrazb commented Jun 20, 2024

Problem

Subset of Connector APIs handlers assumes that the request body is always provided. The body parameter is marked as required in the API spec (used to generate clients), but there is nothing stopping a user from sending a request without body.

If body is not provided for a request where body is expected, we are failing with a 500 error, as the server fails at processing the body that is null. This is not a good way to handle such scenario.

Changes

Looking at other API endpoint(1, 2, 3) I took inspiration and followed their pattern to gracefully handle missing body param. If body is not provided for a request that expects a body, we return informative message and 400 status code. See example:

{
    "error": {
        "root_cause": [
            {
                "type": "parse_exception",
                "reason": "request body is required"
            }
        ],
        "type": "parse_exception",
        "reason": "request body is required"
    },
    "status": 400
}

I'm using request.contentParser() - empty body would cause an exception that would be propagated as a 400 status code in the API response (like above).

I removed a bunch of unnecessary fromXContentBytes functions, in favour of keeping it simpler.

I adapted all Connector API endpoints that require the body.

Testing

  • I tried adding yaml e2e tests for those scenarios but I'm getting errors from api spec if I intentionally skip body parameter in the request (so can't test this scenario there)
  • No effects on existing logic, so no tests changed
  • Verified locally that this works as expected

@jedrazb jedrazb changed the title [Connector API] Gracefully handle empty request body with 400 response code [Connector API] Empty request body should result in 400 status code when required Jun 20, 2024
@jedrazb jedrazb marked this pull request as ready for review June 20, 2024 11:33
@elasticsearchmachine elasticsearchmachine added the Team:SearchOrg Meta label for the Search Org (Enterprise Search) label Jun 20, 2024
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/ent-search-eng (Team:SearchOrg)

@jedrazb
Copy link
Member Author

jedrazb commented Jun 20, 2024

@elasticmachine merge upstream

Copy link
Member

@seanstory seanstory left a comment

Choose a reason for hiding this comment

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

I tried adding yaml e2e tests for those scenarios but I'm getting errors from api spec if I intentionally skip body parameter in the request (so can't test this scenario there)

Would unit tests work, instead of yaml tests?

It's not clear to me (a novice) why these changes fix the issue you describe, so without test changes, I have to just take your word for it that this makes a difference. And i do trust you, but I don't trust that we won't see regressions if we don't have a way to test this.

try (XContentParser parser = restRequest.contentParser()) {
UpdateConnectorConfigurationAction.Request request = UpdateConnectorConfigurationAction.Request.fromXContent(
parser,
restRequest.param("connector_id")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
restRequest.param("connector_id")
restRequest.param(CONNECTOR_ID_PARAM)

try (XContentParser parser = restRequest.contentParser()) {
UpdateConnectorApiKeyIdAction.Request request = UpdateConnectorApiKeyIdAction.Request.fromXContent(
parser,
restRequest.param("connector_id")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
restRequest.param("connector_id")
restRequest.param(CONNECTOR_ID_PARAM)

import java.util.List;

import static org.elasticsearch.rest.RestRequest.Method.PUT;

@ServerlessScope(Scope.PUBLIC)
public class RestUpdateConnectorErrorAction extends BaseRestHandler {

private static final String CONNECTOR_ID_PARAM = "connector_id";
Copy link
Member

Choose a reason for hiding this comment

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

Is it conventional to define these types of constants in each action? Seems like we could re-use one constant somewhere.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sounds like a refactoring, I filed the issue to look into this https://github.com/elastic/search-team/issues/7790 this PR got quite big already

try (XContentParser parser = restRequest.contentParser()) {
UpdateConnectorErrorAction.Request request = UpdateConnectorErrorAction.Request.fromXContent(
parser,
restRequest.param("connector_id")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
restRequest.param("connector_id")
restRequest.param(CONNECTOR_ID_PARAM)

Copy link
Member Author

@jedrazb jedrazb Jun 24, 2024

Choose a reason for hiding this comment

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

Thank you for flagging! I forgot to run the replace-all within the module

@jedrazb
Copy link
Member Author

jedrazb commented Jun 24, 2024

Would unit tests work

Let me look into this!

@jedrazb
Copy link
Member Author

jedrazb commented Jun 24, 2024

It's not clear to me (a novice) why these changes fix the issue you describe, so without test changes, I have to just take your word for it that this makes a difference.

@seanstory You are totally right saying that, I included unit tests for all endpoints that I modified. That required adding some new files (resulting in a lot of additions), but the changes are pretty straightforward

@jedrazb jedrazb requested a review from seanstory June 24, 2024 15:42
@jedrazb
Copy link
Member Author

jedrazb commented Jun 24, 2024

@elasticmachine merge upstream

Copy link
Member

@seanstory seanstory left a comment

Choose a reason for hiding this comment

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

nice!

@jedrazb
Copy link
Member Author

jedrazb commented Jun 25, 2024

@elasticmachine merge upstream

@jedrazb jedrazb changed the title [Connector API] Empty request body should result in 400 status code when required [Connector API] Null request body should result in 400 status code when body is required Jun 25, 2024
@jedrazb jedrazb merged commit 8c2b7bd into elastic:main Jun 25, 2024
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>non-issue :SearchOrg/Extract&Transform Label for the Search E&T team Team:Search - Extract & Transform Team:SearchOrg Meta label for the Search Org (Enterprise Search) v8.15.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants