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

Core: Use unknown report type for forward-compatibility #7145

Merged
merged 1 commit into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
public interface ReportMetricsRequest extends RESTRequest {

enum ReportType {
UNKNOWN,
SCAN_REPORT,
COMMIT_REPORT;

Expand All @@ -38,7 +39,7 @@ static ReportType fromString(String reportType) {
try {
return ReportType.valueOf(reportType.toUpperCase(Locale.ENGLISH));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(String.format("Invalid report type: %s", reportType), e);
return UNKNOWN;
}
}
}
Expand All @@ -54,16 +55,20 @@ default void validate() {
}

static ReportMetricsRequest of(MetricsReport report) {
ReportType reportType = null;
ReportType reportType = ReportType.UNKNOWN;
if (report instanceof ScanReport) {
reportType = ReportType.SCAN_REPORT;
} else if (report instanceof CommitReport) {
reportType = ReportType.COMMIT_REPORT;
}

Preconditions.checkArgument(
null != reportType, "Unsupported report type: %s", report.getClass().getName());

return ImmutableReportMetricsRequest.builder().reportType(reportType).report(report).build();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we don't fallback to returning ReportMetricsRequest unknown() because should prefer the report that was passed in to this method in L57

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this for cases where an unknown metrics report is passed by a user rather than by Iceberg? I guess that makes sense, but I wouldn't expect it to happen.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wouldn't expect it to happen either, but I think it's more correct to pass-through whatever the report was in the first place (rather than defaulting to an unknown impl).

}

static ReportMetricsRequest unknown() {
return ImmutableReportMetricsRequest.builder()
.reportType(ReportType.UNKNOWN)
.report(new MetricsReport() {})
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ public static ReportMetricsRequest fromJson(JsonNode json) {
.build();
}

throw new IllegalArgumentException(String.format("Cannot build metrics request from %s", json));
return ReportMetricsRequest.unknown();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,34 @@ public void missingFields() {

@Test
public void invalidReportType() {
Assertions.assertThatThrownBy(
() -> ReportMetricsRequestParser.fromJson("{\"report-type\":\"invalid\"}"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid report type: invalid");
Assertions.assertThat(
ReportMetricsRequestParser.fromJson("{\"report-type\":\"invalid\"}").reportType())
.isEqualTo(ReportMetricsRequest.unknown().reportType());

Assertions.assertThatThrownBy(
() ->
ReportMetricsRequestParser.fromJson(
Assertions.assertThat(
ReportMetricsRequestParser.fromJson(
ReportMetricsRequestParser.toJson(
ReportMetricsRequest.of(new MetricsReport() {}))))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage(
"Unsupported report type: org.apache.iceberg.rest.requests.TestReportMetricsRequestParser$1");
ReportMetricsRequest.of(new MetricsReport() {})))
.reportType())
.isEqualTo(ReportMetricsRequest.unknown().reportType());

// this is simulating a newer client sending a request to server running an older version (not
// knowing the new report type). this should not fail parsing on the server
String json =
"{\n"
+ " \"report-type\" : \"new-report-type\",\n"
+ " \"table-name\" : \"roundTripTableName\",\n"
+ " \"snapshot-id\" : 23,\n"
+ " \"filter\" : true,\n"
+ " \"schema-id\" : 4,\n"
+ " \"projected-field-ids\" : [ 1, 2, 3 ],\n"
+ " \"projected-field-names\" : [ \"c1\", \"c2\", \"c3\" ],\n"
+ " \"metrics\" : { }\n"
+ "}";

ReportMetricsRequest request = ReportMetricsRequestParser.fromJson(json);
Assertions.assertThat(request.reportType())
.isEqualTo(ReportMetricsRequest.unknown().reportType());
}

@Test
Expand Down