Skip to content

make 0.13 tasks API backwards compatible with 0.12 (#6333) - #6334

Merged
gianm merged 18 commits into
apache:masterfrom
surekhasaharan:rename-status
Oct 1, 2018
Merged

gianm merged 18 commits into
apache:masterfrom
surekhasaharan:rename-status

Conversation

@surekhasaharan

@surekhasaharan surekhasaharan commented Sep 15, 2018 •

Copy link
Copy Markdown

/druid/indexer/v1/task/ID/status API in 0.12 returns

{
	"task": "index_wikipedia_2018-09-17T20:48:21.335Z",
	"status": {
		"id": "index_wikipedia_2018-09-17T20:48:21.335Z",
		"status": "RUNNING",
		"duration": -1
	}
}

In master it got changed to

{
	"task": "index_test1_2018-09-17T20:28:55.785Z",
	"status": {
		"id": "index_test1_2018-09-17T20:28:55.785Z",
		"type": "index",
		"createdTime": "2018-09-17T20:28:55.786Z",
		"queueInsertionTime": "1970-01-01T00:00:00.000Z",
		"statusCode": "FAILED",
		"runnerStatusCode": "WAITING",
		"duration": 32373,
		"location": {
			"host": null,
			"port": -1,
			"tlsPort": -1
		},
		"dataSource": "test1",
		"errorMsg": null
	}
}

which breaks the backwards compatibility, so this PR would add both status and statusCode to the response, for example

{
	"task": "index_test1_2018-09-17T20:28:55.785Z",
	"status": {
		"id": "index_test1_2018-09-17T20:28:55.785Z",
		"type": "index",
		"createdTime": "2018-09-17T20:28:55.786Z",
		"queueInsertionTime": "1970-01-01T00:00:00.000Z",
		"statusCode": "FAILED",
		"status": "FAILED",
		"runnerStatusCode": "WAITING",
		"duration": 32373,
		"location": {
			"host": null,
			"port": -1,
			"tlsPort": -1
		},
		"dataSource": "test1",
		"errorMsg": null
	}
}

Also changed runnerStatusCode to runnerStatus to keep things consistent
@jihoonson

Copy link
Copy Markdown
Contributor

Thanks @surekhasaharan. Would you please add a unit test for this?

@fjy fjy added this to the 0.13.0 milestone Sep 16, 2018
jon-wei
jon-wei previously approved these changes Sep 17, 2018

@gianm gianm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@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?).

@surekhasaharan surekhasaharan changed the title Replace statusCode with status (#6333) make 0.13 tasks API backwards compatible with 0.12 (#6333) Sep 17, 2018
@gianm

gianm commented Sep 18, 2018

Copy link
Copy Markdown
Contributor

@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,

@jon-wei jon-wei Sep 20, 2018 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggest renaming the variable from state to statusCode and getState() to getStatusCode() to match the JsonProperty name

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

done

// TaskStorage API doesn't yet allow it.
DateTimes.EPOCH,
taskInfo.getStatus().getStatusCode(),
taskInfo.getStatus().getStatusCode(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

yes, that's a good suggestion, should we make the existing constructor private as well

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

added the checks

@JsonProperty("createdTime") DateTime createdTime,
@JsonProperty("queueInsertionTime") DateTime queueInsertionTime,
@JsonProperty("statusCode") @Nullable TaskState state,
@JsonProperty("statusCode") @Nullable TaskState statusCode,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This constructor isn't @JsonCreator so let's get rid of the @JsonProperty annotations here

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

right, will remove the annotations.

this.status = status;
//checks for deserialization safety
if (statusCode != null && status == null) {
this.state = statusCode;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

let's rename state to statusCode

this.state = state;
//checks for deserialization safety
if (statusCode != null && status == null) {
this.state = statusCode;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

let's change state to statusCode

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

ok

@jon-wei
jon-wei dismissed their stale review September 21, 2018 19:11

new changes

this.status = status;
} else {
if (statusCode != null && status != null && statusCode != status) {
log.error("statusCode[%s] and status[%s] must be same", statusCode, status);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I do not think there can be a mismatch, added a RuntimeException.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks that this logging is now duplicate with the below exception. I think it's fine to remove it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

sure

private final TaskState state;
private final TaskState statusCode;
@Deprecated
private final TaskState status;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we need to keep both variables? Or, we can just keep statusCode only and make getStatus() return statusCode as well?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

ok, yes that can work

}

@Test
public void testJsonAttributes() throws IOException

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks!!

@jihoonson jihoonson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@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");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add what statusCode and status were in this exception too.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

okay

this.status = status;
} else {
if (statusCode != null && status != null && statusCode != status) {
log.error("statusCode[%s] and status[%s] must be same", statusCode, status);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks that this logging is now duplicate with the below exception. I think it's fine to remove it.

@jihoonson jihoonson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@surekhasaharan thanks!

@gianm
gianm merged commit 42e5385 into apache:master Oct 1, 2018
@surekhasaharan
surekhasaharan deleted the rename-status branch October 1, 2018 22:40
riovic918data pushed a commit to riovic918data/druid that referenced this pull request Jun 12, 2026
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants