Repository navigation
make 0.13 tasks API backwards compatible with 0.12 (#6333) - #6334
Conversation
Also changed runnerStatusCode to runnerStatus to keep things consistent
|
Thanks @surekhasaharan. Would you please add a unit test for this? |
gianm
left a comment
There was a problem hiding this comment.
@surekhasaharan The purpose of fixing #6333 would be to make 0.13 compatible with how previous releases would have behaved. Please double-check that this new behavior is consistent with how 0.12 would have behaved. I think in that release, the task status API /druid/indexer/v1/task/ID/status would return the status code enum under "status" and the completeTasks API would return it under "statusCode". In master, both are "statusCode".
So I am suggesting we should make them inconsistent (with each other) once again, but consistent with how 0.12 behaved, to preserve API compatibility.
It might be a good idea to emit both "status" and "statusCode" so we can make them consistent in the future (by deprecating one?).
Revert to statusCode and runnerStatusCode
|
@surekhasaharan the integration test errors look legitimate, could you please check them? |
| @@ -49,6 +51,7 @@ public TaskStatusPlus( | |||
| @JsonProperty("createdTime") DateTime createdTime, | |||
| @JsonProperty("queueInsertionTime") DateTime queueInsertionTime, | |||
| @JsonProperty("statusCode") @Nullable TaskState state, | |||
There was a problem hiding this comment.
Suggest renaming the variable from state to statusCode and getState() to getStatusCode() to match the JsonProperty name
| // TaskStorage API doesn't yet allow it. | ||
| DateTimes.EPOCH, | ||
| taskInfo.getStatus().getStatusCode(), | ||
| taskInfo.getStatus().getStatusCode(), |
There was a problem hiding this comment.
Let's add a new constructor for TaskStatusPlus without the @JsonCreator annotation that only has "statusCode" which automatically fills in the deprecated "status" parameter with the same value
There was a problem hiding this comment.
yes, that's a good suggestion, should we make the existing constructor private as well
There was a problem hiding this comment.
Nah that's fine, I don't think it can be private anyway since it's the @JsonCreator
| @JsonProperty("createdTime") DateTime createdTime, | ||
| @JsonProperty("queueInsertionTime") DateTime queueInsertionTime, | ||
| @JsonProperty("statusCode") @Nullable TaskState state, | ||
| @Deprecated @JsonProperty("status") @Nullable TaskState status, // present for backwards compatibility |
There was a problem hiding this comment.
For deserialization safety, can you add something here like:
- if "status" is null and "statusCode" is not null, set both to the value of "statusCode"
- If "statusCode" is null and "status" is not null, set both to the value of "status"
- if both are non-null, but have different values, log an error
I don't think there should be a situation where new code would be trying to deserialize an old TaskStatusPlus if the rolling upgrade sequence is followed, but I think it'd be good to handle that situation
| @JsonProperty("createdTime") DateTime createdTime, | ||
| @JsonProperty("queueInsertionTime") DateTime queueInsertionTime, | ||
| @JsonProperty("statusCode") @Nullable TaskState state, | ||
| @JsonProperty("statusCode") @Nullable TaskState statusCode, |
There was a problem hiding this comment.
This constructor isn't @JsonCreator so let's get rid of the @JsonProperty annotations here
There was a problem hiding this comment.
right, will remove the annotations.
| this.status = status; | ||
| //checks for deserialization safety | ||
| if (statusCode != null && status == null) { | ||
| this.state = statusCode; |
There was a problem hiding this comment.
let's rename state to statusCode
| this.state = state; | ||
| //checks for deserialization safety | ||
| if (statusCode != null && status == null) { | ||
| this.state = statusCode; |
There was a problem hiding this comment.
let's change state to statusCode
| this.status = status; | ||
| } else { | ||
| if (statusCode != null && status != null && statusCode != status) { | ||
| log.error("statusCode[%s] and status[%s] must be same", statusCode, status); |
There was a problem hiding this comment.
Is there any case that we can allow this mismatch? If so, it would be better log.warn(). Otherwise, it would be better to throw an exception.
There was a problem hiding this comment.
I do not think there can be a mismatch, added a RuntimeException.
There was a problem hiding this comment.
Looks that this logging is now duplicate with the below exception. I think it's fine to remove it.
| private final TaskState state; | ||
| private final TaskState statusCode; | ||
| @Deprecated | ||
| private final TaskState status; |
There was a problem hiding this comment.
Do we need to keep both variables? Or, we can just keep statusCode only and make getStatus() return statusCode as well?
There was a problem hiding this comment.
I think both variables are required with @JsonProperty, else the serialization/deserialization can fail. for eg if status is present in the json, then deserialization fails.
There was a problem hiding this comment.
I mean, we can only keep statusCode in this class but the @JsonCreator can have both status and statusCode as its params. Also this class needs to have both getStatus() and getStatusCode() annotated with @JsonProperty. Then, serialization and deserialization would work. In serialization, both status and statusCode would be in the serialized JSON because we have both both getStatus() and getStatusCode() methods. In deserialization, this class can read either status or statusCode (or both) since the constructor accepts both params.
| } | ||
|
|
||
| @Test | ||
| public void testJsonAttributes() throws IOException |
jihoonson
left a comment
There was a problem hiding this comment.
@surekhasaharan thanks for the quick fix. Please check my last comment.
| } else { | ||
| if (statusCode != null && status != null && statusCode != status) { | ||
| log.error("statusCode[%s] and status[%s] must be same", statusCode, status); | ||
| throw new RuntimeException("statusCode and status must match"); |
There was a problem hiding this comment.
Please add what statusCode and status were in this exception too.
| this.status = status; | ||
| } else { | ||
| if (statusCode != null && status != null && statusCode != status) { | ||
| log.error("statusCode[%s] and status[%s] must be same", statusCode, status); |
There was a problem hiding this comment.
Looks that this logging is now duplicate with the below exception. I think it's fine to remove it.
jihoonson
left a comment
There was a problem hiding this comment.
@surekhasaharan thanks!
…che#6334) * Replace statusCode with status (apache#6333) Also changed runnerStatusCode to runnerStatus to keep things consistent * Add unit test * Add status param to TaskStatusPlus Revert to statusCode and runnerStatusCode * Add additional status member to TaskStatusPlus * Change TaskResponseObject to match overlord's response object * Address PR comments * address comments * Add runtime exception after logging error * Remove (deprecated)status member variable from TaskStatusPlus * Minor change
/druid/indexer/v1/task/ID/statusAPI in 0.12 returnsIn master it got changed to
which breaks the backwards compatibility, so this PR would add both
statusandstatusCodeto the response, for example