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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -197,4 +198,44 @@ private static class PojoItem
public String nullValueProperty = null;
public String emptyValueProperty = "";
}

@Test(groups = { "unit" })
public void defaultSerializerWritesInstantAsIso8601String() {
ObjectMapper mapper = Utils.getDocumentObjectMapper(Configs.getItemSerializationInclusionMode());
CosmosItemSerializer serializer = new DefaultCosmosItemSerializer(mapper);

Instant createdAt = Instant.parse("2023-07-22T09:46:40.123456789Z");
PojoItemWithInstant item = new PojoItemWithInstant();
item.createdAt = createdAt;

Map<String, Object> jsonMap = serializer.serialize(item);
ByteBuffer buffer = Utils.serializeJsonToByteBuffer(serializer, jsonMap, null, false);
String json = new String(buffer.array(), 0, buffer.limit(), StandardCharsets.UTF_8);

logger.info("Actual: {}", json);
assertThat(json).isEqualTo(
"{\"id\":\"SomeId\",\"createdAt\":\"" + createdAt + "\"}");
}

@Test(groups = { "unit" })
public void defaultSerializerRoundTripsInstant() {
ObjectMapper mapper = Utils.getDocumentObjectMapper(Configs.getItemSerializationInclusionMode());
CosmosItemSerializer serializer = new DefaultCosmosItemSerializer(mapper);

Instant createdAt = Instant.parse("2023-07-22T09:46:40.123456789Z");
PojoItemWithInstant item = new PojoItemWithInstant();
item.createdAt = createdAt;

Map<String, Object> jsonMap = serializer.serialize(item);
PojoItemWithInstant deserialized = serializer.deserialize(jsonMap, PojoItemWithInstant.class);

assertThat(deserialized.id).isEqualTo(item.id);
assertThat(deserialized.createdAt).isEqualTo(createdAt);
}

private static class PojoItemWithInstant
{
public String id = "SomeId";
public Instant createdAt;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import com.fasterxml.jackson.module.blackbird.BlackbirdModule;
import java.time.Instant;
import java.util.List;
import java.util.stream.Collectors;
import org.testng.annotations.Test;
Expand Down Expand Up @@ -165,4 +167,37 @@ public void serializationInclusionMode() {
.isEqualTo(
JsonInclude.Value.construct(JsonInclude.Include.NON_DEFAULT, JsonInclude.Include.NON_DEFAULT));
}

@Test(groups = { "unit" })
public void documentObjectMapperDoesNotWriteDatesAsTimestamps() {
assertThat(
Utils.getSimpleObjectMapper()
.getSerializationConfig()
.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS))
.isFalse();

assertThat(
Utils.getDocumentObjectMapper(null)
.getSerializationConfig()
.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS))
.isFalse();

assertThat(
Utils.getDocumentObjectMapper("Always")
.getSerializationConfig()
.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS))
.isFalse();
}

@Test(groups = { "unit" })
public void instantSerializesAsIso8601String() throws Exception {
Instant instant = Instant.parse("2023-07-22T09:46:40.123456789Z");

String json = Utils.getSimpleObjectMapper().writeValueAsString(instant);

assertThat(json).isEqualTo("\"" + instant.toString() + "\"");

Instant roundTripped = Utils.getSimpleObjectMapper().readValue(json, Instant.class);
assertThat(roundTripped).isEqualTo(instant);
}
}
1 change: 1 addition & 0 deletions sdk/cosmos/azure-cosmos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#### Features Added

#### Breaking Changes
* Fixed `java.time.Instant` (and other `java.time` types handled by `JavaTimeModule`) serializing as a numeric epoch timestamp instead of an ISO-8601 string when using the default `CosmosItemSerializer`. Items previously written with epoch-numeric date fields will now be written with ISO-8601 string values going forward; reading previously-stored epoch-numeric values back into `Instant` fields continues to work unaffected. - See PR [49720](https://github.com/Azure/azure-sdk-for-java/pull/49720).

#### Bugs Fixed
* Unified request-level consistency override behavior across transports: invalid attempts to upgrade the request consistency level above the account default are now silently ignored instead of returning `BadRequest` in some gateway paths. - See PR [49606](https://github.com/Azure/azure-sdk-for-java/pull/49606).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
Expand Down Expand Up @@ -152,6 +153,7 @@ private static ObjectMapper createAndInitializeObjectMapper(boolean allowDuplica
tryToLoadJacksonPerformanceLibrary(objectMapper);

objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

return objectMapper;
}
Expand Down
Loading