Skip to content
Open
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
11 changes: 11 additions & 0 deletions databricks-sdk-java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,16 @@
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Google Protocol Buffers -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.25.1</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.25.1</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.databricks.sdk.core.serialization;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.google.protobuf.Duration;
import com.google.protobuf.util.Durations;
import java.io.IOException;

public class DurationDeserializer extends JsonDeserializer<Duration> {
@Override
public Duration deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String durationStr = p.getValueAsString();
if (durationStr == null || durationStr.isEmpty()) {
return null;
}
try {
return Durations.parse(durationStr); // Parses duration format like "3.000s"
} catch (Exception e) {
throw new IOException("Failed to parse duration: " + durationStr, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.databricks.sdk.core.serialization;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.protobuf.Duration;
import com.google.protobuf.util.Durations;
import java.io.IOException;

public class DurationSerializer extends JsonSerializer<Duration> {
@Override
public void serialize(Duration value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
if (value != null) {
String durationStr = Durations.toString(value); // Converts to "3.000s"
gen.writeString(durationStr);
} else {
gen.writeNull();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.databricks.sdk.core.serialization;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.google.protobuf.FieldMask;
import com.google.protobuf.util.FieldMaskUtil;
import java.io.IOException;

public class FieldMaskDeserializer extends JsonDeserializer<FieldMask> {
@Override
public FieldMask deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String fieldMaskStr = p.getValueAsString();
if (fieldMaskStr == null || fieldMaskStr.isEmpty()) {
return null;
}
try {
return FieldMaskUtil.fromJsonString(fieldMaskStr); // Parses JSON string format
} catch (Exception e) {
throw new IOException("Failed to parse field mask: " + fieldMaskStr, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.databricks.sdk.core.serialization;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.protobuf.FieldMask;
import com.google.protobuf.util.FieldMaskUtil;
import java.io.IOException;

public class FieldMaskSerializer extends JsonSerializer<FieldMask> {
@Override
public void serialize(FieldMask value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
if (value != null) {
String fieldMaskStr = FieldMaskUtil.toJsonString(value); // Converts to JSON string format
gen.writeString(fieldMaskStr);
} else {
gen.writeNull();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.databricks.sdk.core.serialization;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.google.protobuf.Timestamp;
import com.google.protobuf.util.Timestamps;
import java.io.IOException;

public class TimestampDeserializer extends JsonDeserializer<Timestamp> {
@Override
public Timestamp deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String timestampStr = p.getValueAsString();
if (timestampStr == null || timestampStr.isEmpty()) {
return null;
}
try {
return Timestamps.parse(timestampStr); // Parses RFC 3339 format
} catch (Exception e) {
throw new IOException("Failed to parse timestamp: " + timestampStr, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.databricks.sdk.core.serialization;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.protobuf.Timestamp;
import com.google.protobuf.util.Timestamps;
import java.io.IOException;

public class TimestampSerializer extends JsonSerializer<Timestamp> {
@Override
public void serialize(Timestamp value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
if (value != null) {
String timestampStr = Timestamps.toString(value); // Converts to RFC 3339 format
gen.writeString(timestampStr);
} else {
gen.writeNull();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.databricks.sdk.core.serialization;

import static org.junit.jupiter.api.Assertions.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.protobuf.Duration;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public class DurationDeserializerTest {
private static class TestClass {
@JsonDeserialize(using = DurationDeserializer.class)
private Duration duration;

public Duration getDuration() {
return duration;
}
}

@ParameterizedTest
@MethodSource("durationDeserializationTestCases")
public void testDurationDeserialization(String inputJson, Duration expectedDuration)
throws Exception {
ObjectMapper mapper = new ObjectMapper();
TestClass obj = mapper.readValue(inputJson, TestClass.class);
assertEquals(expectedDuration, obj.getDuration());
}

static Stream<Arguments> durationDeserializationTestCases() {
return Stream.of(
// Duration with seconds and nanos
Copy link
Contributor

@parthban-db parthban-db Jun 20, 2025

Choose a reason for hiding this comment

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

Do Java tests comments also end with a period?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If its a full sentence, but not for short phrases.

Arguments.of(
"{\"duration\":\"3.500s\"}",
Duration.newBuilder().setSeconds(3).setNanos(500000000).build()),
// Duration with only seconds
Arguments.of("{\"duration\":\"5s\"}", Duration.newBuilder().setSeconds(5).build()),
// Duration with only nanos
Arguments.of(
"{\"duration\":\"0.123456789s\"}", Duration.newBuilder().setNanos(123456789).build()),
// Null duration
Arguments.of("{\"duration\":null}", null));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.databricks.sdk.core.serialization;

import static org.junit.jupiter.api.Assertions.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.protobuf.Duration;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public class DurationSerializerTest {

private static class TestClass {
@JsonSerialize(using = DurationSerializer.class)
private Duration duration;

public TestClass(Duration duration) {
this.duration = duration;
}
}

@ParameterizedTest
@MethodSource("durationSerializationTestCases")
public void testDurationSerialization(Duration duration, String expectedJson) throws Exception {
TestClass testObject = new TestClass(duration);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(testObject);
assertEquals(expectedJson, json);
}

static Stream<Arguments> durationSerializationTestCases() {
return Stream.of(
// Duration of 3 seconds
Arguments.of(Duration.newBuilder().setSeconds(3).build(), "{\"duration\":\"3s\"}"),
// Duration of 3.5 seconds (3 seconds + 500000000 nanoseconds)
Arguments.of(
Duration.newBuilder().setSeconds(3).setNanos(500000000).build(),
"{\"duration\":\"3.500s\"}"),
// Duration of 0 seconds
Arguments.of(Duration.newBuilder().setSeconds(0).build(), "{\"duration\":\"0s\"}"),
// Duration with only nanos
Arguments.of(
Duration.newBuilder().setNanos(123456789).build(), "{\"duration\":\"0.123456789s\"}"),
// Null duration
Arguments.of(null, "{\"duration\":null}"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.databricks.sdk.core.serialization;

import static org.junit.jupiter.api.Assertions.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.google.protobuf.FieldMask;
import com.google.protobuf.util.FieldMaskUtil;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public class FieldMaskDeserializerTest {
private static class TestClass {
@JsonDeserialize(using = FieldMaskDeserializer.class)
private FieldMask fieldMask;

public FieldMask getFieldMask() {
return fieldMask;
}
}

@ParameterizedTest
@MethodSource("fieldMaskDeserializationTestCases")
public void testFieldMaskDeserialization(String inputJson, List<String> expectedFieldPaths)
throws Exception {
ObjectMapper mapper = new ObjectMapper();
TestClass obj = mapper.readValue(inputJson, TestClass.class);

if (expectedFieldPaths == null) {
assertNull(obj.getFieldMask());
} else {
FieldMask expected = FieldMaskUtil.fromStringList(expectedFieldPaths);
assertEquals(expected, obj.getFieldMask());
}
}

static Stream<Arguments> fieldMaskDeserializationTestCases() {
return Stream.of(
// Simple field mask
Arguments.of("{\"fieldMask\":\"foo,bar.baz\"}", Arrays.asList("foo", "bar.baz")),
// Single field
Arguments.of("{\"fieldMask\":\"name\"}", Arrays.asList("name")),
// Nested fields
Arguments.of(
"{\"fieldMask\":\"user.profile.email,user.profile.name\"}",
Arrays.asList("user.profile.email", "user.profile.name")),
// Null field mask
Arguments.of("{\"fieldMask\":null}", null));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.databricks.sdk.core.serialization;

import static org.junit.jupiter.api.Assertions.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.protobuf.FieldMask;
import com.google.protobuf.util.FieldMaskUtil;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

public class FieldMaskSerializerTest {
private static class TestClass {
@JsonSerialize(using = FieldMaskSerializer.class)
private FieldMask fieldMask;

public TestClass(FieldMask fieldMask) {
this.fieldMask = fieldMask;
}
}

@ParameterizedTest
@MethodSource("fieldMaskSerializationTestCases")
public void testFieldMaskSerialization(List<String> fieldPaths, String expectedJson)
throws Exception {
FieldMask fieldMask = null;
if (fieldPaths != null) {
fieldMask = FieldMaskUtil.fromStringList(fieldPaths);
}

TestClass testObject = new TestClass(fieldMask);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(testObject);
assertEquals(expectedJson, json);
}

static Stream<Arguments> fieldMaskSerializationTestCases() {
return Stream.of(
// Simple field mask
Arguments.of(Arrays.asList("foo", "bar.baz"), "{\"fieldMask\":\"foo,bar.baz\"}"),
// Single field
Arguments.of(Arrays.asList("name"), "{\"fieldMask\":\"name\"}"),
// Nested fields
Arguments.of(
Arrays.asList("user.profile.email", "user.profile.name"),
"{\"fieldMask\":\"user.profile.email,user.profile.name\"}"),
// Null field mask
Arguments.of(null, "{\"fieldMask\":null}"));
}
}
Loading
Loading