Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f4bfb98
Builder for DataConverter
GreyTeardrop Mar 30, 2021
fc52b53
Merge branch 'master' into dataconverter-builder
GreyTeardrop Apr 2, 2021
cf749ba
Merge branch 'master' into dataconverter-builder
GreyTeardrop Apr 5, 2021
b9c1620
Merge branch 'master' into dataconverter-builder
GreyTeardrop Apr 6, 2021
1510f8c
No direct dependency on PayloadConverter internals
GreyTeardrop Apr 7, 2021
905d535
Merge branch 'master' into dataconverter-builder
GreyTeardrop Apr 7, 2021
0fda8e4
Revert PayloadConverters changes
GreyTeardrop Apr 9, 2021
122126e
Revert DataConverter changes
GreyTeardrop Apr 9, 2021
e45c853
Merge branch 'master' into dataconverter-builder
GreyTeardrop Apr 9, 2021
979d0b0
Call DefaultDataConverter constructor from tests
GreyTeardrop Apr 9, 2021
72d6448
Merge branch 'master' into dataconverter-builder
GreyTeardrop Apr 9, 2021
663388d
Switch to factory & builder-like method
GreyTeardrop Apr 10, 2021
3b8a7c1
Merge branch 'master' into dataconverter-builder
GreyTeardrop Apr 10, 2021
e7bd1e7
Merge branch 'master' into dataconverter-builder
vkoby Apr 15, 2021
fca1870
Merge branch 'master' into dataconverter-builder
vkoby Apr 15, 2021
ea7379e
Merge branch 'master' into dataconverter-builder
GreyTeardrop Apr 16, 2021
3151689
Merge branch 'master' into dataconverter-builder
mfateev Apr 27, 2021
fe09726
Merge branch 'master' into dataconverter-builder
mfateev May 4, 2021
934d3cc
Merge branch 'master' into dataconverter-builder
GreyTeardrop May 7, 2021
c35d89c
Merge branch 'master' into dataconverter-builder
GreyTeardrop May 7, 2021
9d4e839
Merge branch 'master' into dataconverter-builder
vkoby May 7, 2021
8e02b93
Merge branch 'master' into dataconverter-builder
GreyTeardrop May 11, 2021
b983b72
Merge branch 'master' into dataconverter-builder
vkoby May 11, 2021
058d62c
Merge branch 'master' into dataconverter-builder
GreyTeardrop May 12, 2021
fa71a0b
Merge branch 'master' into dataconverter-builder
GreyTeardrop May 12, 2021
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 @@ -26,6 +26,7 @@
import io.temporal.api.common.v1.Payloads;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand All @@ -39,16 +40,16 @@
*/
public class DefaultDataConverter implements DataConverter {

private static final AtomicReference<DataConverter> defaultDataConverterInstance =
new AtomicReference<>(
// Order is important as the first converter that can convert the payload is used
new DefaultDataConverter(
new NullPayloadConverter(),
new ByteArrayPayloadConverter(),
new ProtobufJsonPayloadConverter(),
new JacksonJsonPayloadConverter()));
// Order is important as the first converter that can convert the payload is used
private static final PayloadConverter[] DEFAULT_PAYLOAD_CONVERTERS = {
new NullPayloadConverter(),
new ByteArrayPayloadConverter(),
new ProtobufJsonPayloadConverter(),
new JacksonJsonPayloadConverter()
};

private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
private static final AtomicReference<DataConverter> defaultDataConverterInstance =
new AtomicReference<>(newDefaultInstance());

private final Map<String, PayloadConverter> converterMap = new ConcurrentHashMap<>();

Expand All @@ -70,16 +71,44 @@ public static void setDefaultDataConverter(DataConverter converter) {
defaultDataConverterInstance.set(converter);
}

/**
* Creates a new instance of {@code DefaultDataConverter} populated with the default list of
* payload converters.
*/
public static DefaultDataConverter newDefaultInstance() {
return new DefaultDataConverter(DEFAULT_PAYLOAD_CONVERTERS);
}

/**
* Creates instance from ordered array of converters. When converting an object to payload the
* array of converters is iterated from the beginning until one of the converters succesfully
* array of converters is iterated from the beginning until one of the converters successfully
* converts the value.
*/
public DefaultDataConverter(PayloadConverter... converters) {
for (PayloadConverter converter : converters) {
this.converters.add(converter);
this.converterMap.put(converter.getEncodingType(), converter);
Collections.addAll(this.converters, converters);
updateConverterMap();
}

/**
* Modifies this {@code DefaultDataConverter} by overriding some of its {@link PayloadConverter}s.
* Every payload converter from {@code overrideConverters} either replaces existing payload
* converter with the same encoding type, or is added to the end of payload converters list.
*/
public DefaultDataConverter withPayloadConverterOverrides(
PayloadConverter... overrideConverters) {
for (PayloadConverter overrideConverter : overrideConverters) {
PayloadConverter existingConverter = converterMap.get(overrideConverter.getEncodingType());
if (existingConverter != null) {
int existingConverterIndex = converters.indexOf(existingConverter);
converters.set(existingConverterIndex, overrideConverter);
} else {
converters.add(overrideConverter);
}
}

updateConverterMap();

return this;
}

@Override
Expand Down Expand Up @@ -154,4 +183,11 @@ public <T> T fromPayloads(
}
return fromPayload(content.get().getPayloads(index), parameterType, genericParameterType);
}

private void updateConverterMap() {
converterMap.clear();
for (PayloadConverter converter : converters) {
converterMap.put(converter.getEncodingType(), converter);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@

import static org.junit.Assert.assertEquals;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.protobuf.util.JsonFormat;
import io.temporal.api.common.v1.Payloads;
import io.temporal.api.common.v1.WorkflowExecution;
import java.time.Instant;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import org.junit.Test;
Expand All @@ -43,6 +49,21 @@ public void testProtoJson() {
assertEquals(execution, converted);
}

@Test
public void testCustomJson() {
ObjectMapper objectMapper =
new ObjectMapper()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true)
.registerModule(new JavaTimeModule());
DataConverter converter =
DefaultDataConverter.newDefaultInstance()
.withPayloadConverterOverrides(new JacksonJsonPayloadConverter(objectMapper));
TestPayload payload = new TestPayload(1L, Instant.now(), "myPayload");
Optional<Payloads> data = converter.toPayloads(payload);
TestPayload converted = converter.fromPayloads(0, data, TestPayload.class, TestPayload.class);
assertEquals(payload, converted);
}

@Test
public void testProto() {
DataConverter converter = new DefaultDataConverter(new ProtobufPayloadConverter());
Expand All @@ -56,4 +77,92 @@ public void testProto() {
converter.fromPayloads(0, data, WorkflowExecution.class, WorkflowExecution.class);
assertEquals(execution, converted);
}

@Test
public void testCustomProto() {
DataConverter converter =
DefaultDataConverter.newDefaultInstance()
.withPayloadConverterOverrides(
new ProtobufJsonPayloadConverter(
JsonFormat.printer().printingEnumsAsInts(), JsonFormat.parser()));
WorkflowExecution execution =
WorkflowExecution.newBuilder()
.setWorkflowId(UUID.randomUUID().toString())
.setRunId(UUID.randomUUID().toString())
.build();
Optional<Payloads> data = converter.toPayloads(execution);
WorkflowExecution converted =
converter.fromPayloads(0, data, WorkflowExecution.class, WorkflowExecution.class);
assertEquals(execution, converted);
}

static class TestPayload {
private long id;
private Instant timestamp;
private String name;

public TestPayload() {}

TestPayload(long id, Instant timestamp, String name) {
this.id = id;
this.timestamp = timestamp;
this.name = name;
}

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public Instant getTimestamp() {
return timestamp;
}

public void setTimestamp(Instant timestamp) {
this.timestamp = timestamp;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TestPayload that = (TestPayload) o;
return id == that.id
&& Objects.equals(timestamp, that.timestamp)
&& Objects.equals(name, that.name);
}

@Override
public int hashCode() {
return Objects.hash(id, timestamp, name);
}

@Override
public String toString() {
return "TestPayload{"
+ "id="
+ id
+ ", timestamp="
+ timestamp
+ ", name='"
+ name
+ '\''
+ '}';
}
}
}