From d7cc7974c79522a595d9c72c270c82034f3fafcb Mon Sep 17 00:00:00 2001 From: Artur Souza Date: Wed, 27 Jan 2021 23:39:13 -0800 Subject: [PATCH] handle method not found when proto class does not have parseFrom() --- .../java/io/dapr/client/ObjectSerializer.java | 2 + .../DefaultObjectSerializerTest.java | 79 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/sdk/src/main/java/io/dapr/client/ObjectSerializer.java b/sdk/src/main/java/io/dapr/client/ObjectSerializer.java index 48939e40f..8a184885a 100644 --- a/sdk/src/main/java/io/dapr/client/ObjectSerializer.java +++ b/sdk/src/main/java/io/dapr/client/ObjectSerializer.java @@ -123,6 +123,8 @@ public class ObjectSerializer { if (method != null) { return (T) method.invoke(null, content); } + } catch (NoSuchMethodException e) { + // It was a best effort. Skip this try. } catch (Exception e) { throw new IOException(e); } diff --git a/sdk/src/test/java/io/dapr/serializer/DefaultObjectSerializerTest.java b/sdk/src/test/java/io/dapr/serializer/DefaultObjectSerializerTest.java index dcfaa1176..812e65bbe 100644 --- a/sdk/src/test/java/io/dapr/serializer/DefaultObjectSerializerTest.java +++ b/sdk/src/test/java/io/dapr/serializer/DefaultObjectSerializerTest.java @@ -5,13 +5,19 @@ package io.dapr.serializer; +import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.protobuf.ByteString; +import com.google.protobuf.CodedOutputStream; +import com.google.protobuf.MessageLite; +import com.google.protobuf.Parser; import io.dapr.client.domain.CloudEvent; import io.dapr.utils.TypeRef; import io.dapr.v1.CommonProtos; import org.junit.Test; import java.io.IOException; +import java.io.OutputStream; import java.io.Serializable; import java.lang.reflect.Type; import java.util.ArrayList; @@ -24,6 +30,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -407,6 +414,19 @@ public class DefaultObjectSerializerTest { assertEquals(valueToSerialize, deserializedValue); } + @Test + public void serializeFakeProtoTest() throws Exception { + FakeProtoClass valueToSerialize = new FakeProtoClass(); + String expectedSerializedBase64Value = "AQ=="; + + byte[] serializedValue = SERIALIZER.serialize(valueToSerialize); + assertEquals(expectedSerializedBase64Value, Base64.getEncoder().encodeToString(serializedValue)); + assertNotNull(serializedValue); + + // Tries to parse as JSON since FakeProtoClass does not have `parseFrom()` static method. + assertThrows(JsonParseException.class, () -> SERIALIZER.deserialize(serializedValue, FakeProtoClass.class)); + } + @Test public void deserializeObjectTest() { String jsonToDeserialize = "{\"stringValue\":\"A String\",\"intValue\":2147483647,\"boolValue\":true,\"charValue\":\"a\",\"byteValue\":65,\"shortValue\":32767,\"longValue\":9223372036854775807,\"floatValue\":1.0,\"doubleValue\":1000.0}"; @@ -868,4 +888,63 @@ public class DefaultObjectSerializerTest { return "\"" + content + "\""; } + + /** + * Class that simulates a proto class implementing MessageLite but does not have `parseFrom()` static method. + */ + public static final class FakeProtoClass implements MessageLite { + @Override + public void writeTo(CodedOutputStream codedOutputStream) throws IOException { + } + + @Override + public int getSerializedSize() { + return 0; + } + + @Override + public Parser getParserForType() { + return null; + } + + @Override + public ByteString toByteString() { + return null; + } + + @Override + public byte[] toByteArray() { + return new byte[]{0x1}; + } + + @Override + public void writeTo(OutputStream outputStream) throws IOException { + + } + + @Override + public void writeDelimitedTo(OutputStream outputStream) throws IOException { + + } + + @Override + public Builder newBuilderForType() { + return null; + } + + @Override + public Builder toBuilder() { + return null; + } + + @Override + public MessageLite getDefaultInstanceForType() { + return null; + } + + @Override + public boolean isInitialized() { + return false; + } + } }