-
Notifications
You must be signed in to change notification settings - Fork 25.3k
Cluster Allocation Explain API Throws IAE #130389
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
base: main
Are you sure you want to change the base?
Cluster Allocation Explain API Throws IAE #130389
Conversation
Throws an Illegal Argument Exception when a non-integer value is passed as the `shard` parameter. The legacy behaviour of allowing strings to be passed, providing they are strings containing integers, is maintained.
Merging test fix into main
a6a4efe
to
2a697ef
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments.
Is this ready for a full review? If yes, please mark it as ready and not draft.
@@ -31,7 +31,29 @@ public class ClusterAllocationExplainRequest extends MasterNodeRequest<ClusterAl | |||
private static final ObjectParser<ClusterAllocationExplainRequest, Void> PARSER = new ObjectParser<>("cluster/allocation/explain"); | |||
static { | |||
PARSER.declareString(ClusterAllocationExplainRequest::setIndex, new ParseField("index")); | |||
PARSER.declareInt(ClusterAllocationExplainRequest::setShard, new ParseField("shard")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not clear to me what the problem with declareInt
is. Is this where the lenience is and it would silently accept and convert a float?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, declareInt
implicitly allows floats, doubles, and stringified floats and doubles, to be passed where an integer parameter is expected. I have removed that explicit behaviour, and then added test cases
String text = xContentParser.text(); | ||
try { | ||
// Only accept if the string is a valid integer representation | ||
if (text.matches("[-+]?\\d+")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you need the regex? wouldn't relying on parseInt
be enough?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could also simplify these if/else statements. If you return or throw as the last and only statement of your if, you don't need the else and can just "do the else" after the if statement.
@@ -47,6 +48,11 @@ public boolean allowSystemIndexAccessByDefault() { | |||
return true; | |||
} | |||
|
|||
@Override | |||
public Set<String> supportedCapabilities() { | |||
return Set.of("shard_parameter_non_integer_validation"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏼
@@ -84,18 +158,32 @@ | |||
- match: { acknowledged: true } | |||
|
|||
- do: | |||
catch: /x_content_parse_exception/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should expose this exception. It's rather cryptic and internal. I think something like bad request
would be more fitting. this could be its error.type. One example I found skimming through the yaml tests is in resources/rest-api-spec/test/cluster.desired_nodes/10_basic.yml
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's exposed as this exception. Happy to proven wrong, but from memory I asked about this and it gets converted somewhere to a BAD_REQUEST
and this is a 4XX
error. I'd be aligned with changing this errors, but this is the current, prod functionality and that has, by definition, been accepted.
Example test from https://github.com/elastic/elasticsearch/pull/129342/files
"cluster shard allocation explanation test with numerical index parameter in the body":
- do:
indices.create:
index: test
- match: { acknowledged: true }
- do:
catch: /x_content_parse_exception/
cluster.allocation_explain:
body: { "index": 0, "shard": 0, "primary": true }
You should also add the area label for allocation ( |
Have done! |
Hi @joshua-adams-1, I've created a changelog YAML for you. |
Ahaha forgot to publish it, whoops! |
Pinging @elastic/es-distributed-coordination (Team:Distributed Coordination) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid I don't think we should do this, at least not as proposed here. The behaviour of declareInt
encodes the way that we parse integer parameters across the entire Elasticsearch API surface. It'd be super-weird to make just this one API be stricter about this parsing.
That's not to say that I think it's a good thing to accept (and truncate) non-integer arguments in our APIs in general, just that I would prefer consistency across the whole API surface. If we're going to fix this, we should fix it everywhere.
Moreover this is a breaking change. We can't justify adopting this change in a minor release since it's not fixing a bug (or at least not a bug which is serious enough to warrant a breaking change in a minor release). Instead, let's mark declareInt
with an @UpdateForV10
marker and come back to this lenience when we prepare for the next major release.
@DaveCTurner Happy to mark it for V10. Who would be the owner of this change? Us, or core infra? |
I think it'd be core/infra really, the parsing code falls under |
Throws an Illegal Argument Exception when a non-integer value is passed as the
shard
parameter. The legacy behaviour of allowing strings to be passed, providing they are strings containing integers, is maintained. This is a prerequisite PR to #129342