diff --git a/.gitignore b/.gitignore index 0304fc07c3e..67e5cbbb905 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ target/ tools/venv/ venv/ .vscode/* +exec/java-exec/src/main/resources/webapp/ diff --git a/contrib/format-hdf5/src/main/java/org/apache/drill/exec/store/hdf5/HDF5FormatConfig.java b/contrib/format-hdf5/src/main/java/org/apache/drill/exec/store/hdf5/HDF5FormatConfig.java index c5bd202d98f..664c707f4b5 100644 --- a/contrib/format-hdf5/src/main/java/org/apache/drill/exec/store/hdf5/HDF5FormatConfig.java +++ b/contrib/format-hdf5/src/main/java/org/apache/drill/exec/store/hdf5/HDF5FormatConfig.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; @@ -32,6 +33,7 @@ import java.util.Objects; @JsonTypeName(HDF5FormatPlugin.DEFAULT_NAME) +@JsonInclude(Include.NON_DEFAULT) public class HDF5FormatConfig implements FormatPluginConfig { private final List extensions; @@ -42,24 +44,28 @@ public class HDF5FormatConfig implements FormatPluginConfig { public HDF5FormatConfig( @JsonProperty("extensions") List extensions, @JsonProperty("defaultPath") String defaultPath, - @JsonProperty("showPreview") boolean showPreview) { + @JsonProperty("showPreview") Boolean showPreview) { this.extensions = extensions == null ? Collections.singletonList("h5") : ImmutableList.copyOf(extensions); this.defaultPath = defaultPath; - this.showPreview = showPreview; + this.showPreview = showPreview != null && showPreview; } - @JsonInclude(JsonInclude.Include.NON_DEFAULT) + @JsonProperty("extensions") public List getExtensions() { return extensions; } + @JsonProperty("defaultPath") public String getDefaultPath() { return defaultPath; } - public boolean showPreview() { return showPreview; } + @JsonProperty("showPreview") + public boolean showPreview() { + return showPreview; + } @Override public boolean equals(Object obj) { @@ -71,8 +77,8 @@ public boolean equals(Object obj) { } HDF5FormatConfig other = (HDF5FormatConfig) obj; return Objects.equals(extensions, other.getExtensions()) && - Objects.equals(defaultPath, other.defaultPath) && - Objects.equals(showPreview, other.showPreview); + Objects.equals(defaultPath, other.defaultPath) && + Objects.equals(showPreview, other.showPreview); } @Override @@ -83,9 +89,9 @@ public int hashCode() { @Override public String toString() { return new PlanStringBuilder(this) - .field("extensions", extensions) - .field("default path", defaultPath) - .field("show preview", showPreview) - .toString(); + .field("extensions", extensions) + .field("default path", defaultPath) + .field("show preview", showPreview) + .toString(); } } diff --git a/contrib/format-hdf5/src/test/java/org/apache/drill/exec/store/hdf5/TestHDF5Format.java b/contrib/format-hdf5/src/test/java/org/apache/drill/exec/store/hdf5/TestHDF5Format.java index 9e1e04d9a94..49dfa93b8ce 100644 --- a/contrib/format-hdf5/src/test/java/org/apache/drill/exec/store/hdf5/TestHDF5Format.java +++ b/contrib/format-hdf5/src/test/java/org/apache/drill/exec/store/hdf5/TestHDF5Format.java @@ -18,19 +18,21 @@ package org.apache.drill.exec.store.hdf5; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.drill.categories.RowSetTest; +import org.apache.drill.common.logical.FormatPluginConfig; import org.apache.drill.common.types.TypeProtos; import org.apache.drill.common.types.TypeProtos.DataMode; import org.apache.drill.common.types.TypeProtos.MinorType; +import org.apache.drill.exec.physical.rowSet.RowSet; +import org.apache.drill.exec.physical.rowSet.RowSetBuilder; +import org.apache.drill.exec.record.metadata.SchemaBuilder; import org.apache.drill.exec.record.metadata.TupleMetadata; import org.apache.drill.exec.rpc.RpcException; +import org.apache.drill.test.ClusterFixture; import org.apache.drill.test.ClusterFixtureBuilder; import org.apache.drill.test.ClusterTest; -import org.apache.drill.exec.physical.rowSet.RowSet; -import org.apache.drill.exec.physical.rowSet.RowSetBuilder; -import org.apache.drill.test.ClusterFixture; import org.apache.drill.test.rowSet.RowSetComparison; -import org.apache.drill.exec.record.metadata.SchemaBuilder; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; @@ -40,8 +42,9 @@ import java.util.Arrays; import java.util.List; -import static org.junit.Assert.assertEquals; import static org.apache.drill.test.QueryTestUtil.generateCompressedFile; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; @Category(RowSetTest.class) public class TestHDF5Format extends ClusterTest { @@ -920,4 +923,65 @@ public void testInlineSchema() throws Exception { new RowSetComparison(expected).unorderedVerifyAndClearAll(results); } + + @Test + public void testSerializeAndDeserialize() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + HDF5FormatConfig config = new HDF5FormatConfig( + Arrays.asList("h5", "hdf5"), + "/data/group1", + true + ); + + String json = mapper.writeValueAsString(config); + assertTrue("JSON should contain type field", json.contains("\"type\"")); + assertTrue("JSON should contain hdf5 type value", json.contains("\"hdf5\"")); + assertTrue("JSON should contain extensions", json.contains("\"extensions\"")); + assertTrue("JSON should contain h5 extension", json.contains("\"h5\"")); + assertTrue("JSON should contain hdf5 extension", json.contains("\"hdf5\"")); + assertTrue("JSON should contain defaultPath", json.contains("\"defaultPath\"")); + assertTrue("JSON should contain /data/group1", json.contains("/data/group1")); + assertTrue("JSON should contain showPreview", json.contains("\"showPreview\"")); + assertTrue("JSON should contain true for showPreview", json.contains("true")); + + HDF5FormatConfig deserialized = mapper.readValue(json, HDF5FormatConfig.class); + + assertEquals("Round-tripped config should equal original", config, deserialized); + assertEquals("Extensions should match", config.getExtensions(), deserialized.getExtensions()); + assertEquals("Default path should match", config.getDefaultPath(), deserialized.getDefaultPath()); + assertEquals("Show preview should match", config.showPreview(), deserialized.showPreview()); + } + + @Test + public void testSerializeDefaults() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + + HDF5FormatConfig config = new HDF5FormatConfig(null, null, null); + String json = mapper.writeValueAsString(config); + + // With @JsonInclude(NON_DEFAULT), default-valued fields may be omitted. + // The type field should always be present. + assertTrue("JSON should contain type field", json.contains("\"type\"")); + assertTrue("JSON should contain hdf5 type value", json.contains("\"hdf5\"")); + HDF5FormatConfig deserialized = mapper.readValue(json, HDF5FormatConfig.class); + assertEquals("Round-tripped default config should equal original", config, deserialized); + } + + @Test + public void testDeserializeViaBaseType() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerSubtypes(HDF5FormatConfig.class); + + HDF5FormatConfig config = new HDF5FormatConfig(Arrays.asList("h5", "hdf5"), + "/data/group1", + true); + + String json = mapper.writeValueAsString(config); + + // Deserialize using the base interface to verify type info works + FormatPluginConfig deserialized = mapper.readValue(json, FormatPluginConfig.class); + + assertTrue("Deserialized should be HDF5FormatConfig", deserialized instanceof HDF5FormatConfig); + assertEquals("Round-tripped config via base type should equal original", config, deserialized); + } }