diff --git a/api/src/main/java/io/cloudevents/SpecVersion.java b/api/src/main/java/io/cloudevents/SpecVersion.java index 841a2756..bd03edce 100644 --- a/api/src/main/java/io/cloudevents/SpecVersion.java +++ b/api/src/main/java/io/cloudevents/SpecVersion.java @@ -17,9 +17,12 @@ public enum SpecVersion { public static SpecVersion parse(String sv) { switch (sv) { - case "0.3": return SpecVersion.V03; - case "1.0": return SpecVersion.V1; - default: throw new IllegalArgumentException("Unrecognized SpecVersion "+ sv); + case "0.3": + return SpecVersion.V03; + case "1.0": + return SpecVersion.V1; + default: + throw new IllegalArgumentException("Unrecognized SpecVersion " + sv); } } } diff --git a/api/src/main/java/io/cloudevents/extensions/DistributedTracingExtension.java b/api/src/main/java/io/cloudevents/extensions/DistributedTracingExtension.java index 5915696b..2155d31b 100644 --- a/api/src/main/java/io/cloudevents/extensions/DistributedTracingExtension.java +++ b/api/src/main/java/io/cloudevents/extensions/DistributedTracingExtension.java @@ -15,8 +15,6 @@ public final class DistributedTracingExtension implements Extension { private String traceparent; private String tracestate; - public DistributedTracingExtension() { } - public String getTraceparent() { return traceparent; } diff --git a/api/src/main/java/io/cloudevents/message/Encoding.java b/api/src/main/java/io/cloudevents/message/Encoding.java index c173d980..d6b8e384 100644 --- a/api/src/main/java/io/cloudevents/message/Encoding.java +++ b/api/src/main/java/io/cloudevents/message/Encoding.java @@ -6,4 +6,6 @@ public enum Encoding { UNKNOWN; public static IllegalStateException UNKNOWN_ENCODING_EXCEPTION = new IllegalStateException("Unknown encoding"); + + public static IllegalStateException WRONG_ENCODING_EXCEPTION = new IllegalStateException("Wrong encoding"); } diff --git a/api/src/main/java/io/cloudevents/message/Message.java b/api/src/main/java/io/cloudevents/message/Message.java index 56ecf058..3ff9eabe 100644 --- a/api/src/main/java/io/cloudevents/message/Message.java +++ b/api/src/main/java/io/cloudevents/message/Message.java @@ -1,6 +1,7 @@ package io.cloudevents.message; import io.cloudevents.CloudEvent; +import io.cloudevents.format.EventFormat; public interface Message extends StructuredMessage, BinaryMessage { @@ -16,9 +17,20 @@ public interface Message extends StructuredMessage, BinaryMessage { default CloudEvent toEvent() throws MessageVisitException, IllegalStateException { switch (getEncoding()) { - case BINARY: return ((BinaryMessage)this).toEvent(); - case STRUCTURED: return ((StructuredMessage)this).toEvent(); - default: throw Encoding.UNKNOWN_ENCODING_EXCEPTION; + case BINARY: + return this.visit(specVersion -> { + switch (specVersion) { + case V1: + return CloudEvent.buildV1(); + case V03: + return CloudEvent.buildV03(); + } + return null; // This can never happen + }); + case STRUCTURED: + return this.visit(EventFormat::deserialize); + default: + throw Encoding.UNKNOWN_ENCODING_EXCEPTION; } }; diff --git a/api/src/main/java/io/cloudevents/v03/AttributesImpl.java b/api/src/main/java/io/cloudevents/v03/AttributesImpl.java index 017f47cb..c19fcb8d 100644 --- a/api/src/main/java/io/cloudevents/v03/AttributesImpl.java +++ b/api/src/main/java/io/cloudevents/v03/AttributesImpl.java @@ -152,12 +152,12 @@ public final class AttributesImpl implements AttributesInternal { @Override public String toString() { - return "AttributesImpl [id=" + id + ", source=" + source - + ", specversion=" + SpecVersion.V03 + ", type=" + type - + ", time=" + time + ", schemaurl=" + schemaurl - + ", datacontenttype=" + datacontenttype + ", subject=" - + subject + "]"; - } + return "Attributes V0.3 [id=" + id + ", source=" + source + + ", specversion=" + SpecVersion.V03 + ", type=" + type + + ", time=" + time + ", schemaurl=" + schemaurl + + ", datacontenttype=" + datacontenttype + ", subject=" + + subject + "]"; + } @Override public boolean equals(Object o) { diff --git a/api/src/test/java/io/cloudevents/message/EventMessageRoundtripTest.java b/api/src/test/java/io/cloudevents/message/EventMessageRoundtripTest.java index c9394675..8a0c4d51 100644 --- a/api/src/test/java/io/cloudevents/message/EventMessageRoundtripTest.java +++ b/api/src/test/java/io/cloudevents/message/EventMessageRoundtripTest.java @@ -2,6 +2,8 @@ package io.cloudevents.message; import io.cloudevents.CloudEvent; import io.cloudevents.mock.CSVFormat; +import io.cloudevents.mock.MockBinaryMessage; +import io.cloudevents.mock.MockStructuredMessage; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -12,10 +14,19 @@ public class EventMessageRoundtripTest { @ParameterizedTest() @MethodSource("io.cloudevents.test.Data#allEvents") void structuredToEvent(CloudEvent input) { + CloudEvent event = input.asStructuredMessage(CSVFormat.INSTANCE).toEvent(); + assertThat(input.asStructuredMessage(CSVFormat.INSTANCE).toEvent()) .isEqualTo(input); } + @ParameterizedTest() + @MethodSource("io.cloudevents.test.Data#allEvents") + void structuredToMockStructuredMessageToEvent(CloudEvent input) { + assertThat(input.asStructuredMessage(CSVFormat.INSTANCE).visit(new MockStructuredMessage()).toEvent()) + .isEqualTo(input); + } + @ParameterizedTest() @MethodSource("io.cloudevents.test.Data#allEvents") void binaryToEvent(CloudEvent input) { @@ -23,4 +34,11 @@ public class EventMessageRoundtripTest { .isEqualTo(input); } + @ParameterizedTest() + @MethodSource("io.cloudevents.test.Data#allEvents") + void binaryToMockBinaryMessageToEvent(CloudEvent input) { + assertThat(input.asBinaryMessage().visit(new MockBinaryMessage()).toEvent()) + .isEqualTo(input); + } + } diff --git a/api/src/test/java/io/cloudevents/mock/MockBinaryMessage.java b/api/src/test/java/io/cloudevents/mock/MockBinaryMessage.java index a784bf2b..377f713b 100644 --- a/api/src/test/java/io/cloudevents/mock/MockBinaryMessage.java +++ b/api/src/test/java/io/cloudevents/mock/MockBinaryMessage.java @@ -42,13 +42,13 @@ public class MockBinaryMessage implements Message, BinaryMessageVisitorFactory e: this.attributes.entrySet()) { if (e.getValue() instanceof String) { visitor.setAttribute(e.getKey(), (String) e.getValue()); - } else if (e.getValue() instanceof Number) { - visitor.setExtension(e.getKey(), (Number) e.getValue()); - } else if (e.getValue() instanceof Boolean) { - visitor.setExtension(e.getKey(), (Boolean) e.getValue()); + } else if (e.getValue() instanceof ZonedDateTime) { + visitor.setAttribute(e.getKey(), (ZonedDateTime) e.getValue()); + } else if (e.getValue() instanceof URI) { + visitor.setAttribute(e.getKey(), (URI) e.getValue()); } else { // This should never happen because we build that map only through our builders - throw new IllegalStateException("Illegal value inside extensions map: " + e); + throw new IllegalStateException("Illegal value inside attributes map: " + e); } } @@ -72,7 +72,7 @@ public class MockBinaryMessage implements Message, BinaryMessageVisitorFactory T visit(StructuredMessageVisitor visitor) throws MessageVisitException, IllegalStateException { - throw Encoding.UNKNOWN_ENCODING_EXCEPTION; + throw Encoding.WRONG_ENCODING_EXCEPTION; } @Override @@ -117,6 +117,8 @@ public class MockBinaryMessage implements Message, BinaryMessageVisitorFactory { + + private EventFormat format; + private byte[] payload; + + @Override + public Encoding getEncoding() { + return Encoding.STRUCTURED; + } + + @Override + public , V> V visit(BinaryMessageVisitorFactory visitor) throws MessageVisitException, IllegalStateException { + throw Encoding.WRONG_ENCODING_EXCEPTION; + } + + @Override + public T visit(StructuredMessageVisitor visitor) throws MessageVisitException, IllegalStateException { + if (this.format == null) { + throw new IllegalStateException("MockStructuredMessage is empty"); + } + + return visitor.setEvent(this.format, this.payload); + } + + @Override + public MockStructuredMessage setEvent(EventFormat format, byte[] value) throws MessageVisitException { + this.format = format; + this.payload = value; + + return this; + } +} diff --git a/api/src/test/java/io/cloudevents/test/Data.java b/api/src/test/java/io/cloudevents/test/Data.java index 02e7bdae..2b49bc0c 100644 --- a/api/src/test/java/io/cloudevents/test/Data.java +++ b/api/src/test/java/io/cloudevents/test/Data.java @@ -15,7 +15,7 @@ public class Data { public static final String DATACONTENTTYPE_JSON = "application/json"; public static final URI DATASCHEMA = URI.create("http://localhost/schema"); public static final String SUBJECT = "sub"; - public static final ZonedDateTime TIME = ZonedDateTime.now(); + public static final ZonedDateTime TIME = ZonedDateTime.now().withFixedOffsetZone().withNano(0); public static byte[] DATA_JSON_SERIALIZED = "{}".getBytes(); diff --git a/api/src/test/java/io/cloudevents/v03/CloudEventBuilderTest.java b/api/src/test/java/io/cloudevents/v03/CloudEventBuilderTest.java index 5c3c2eff..8a87fcf8 100644 --- a/api/src/test/java/io/cloudevents/v03/CloudEventBuilderTest.java +++ b/api/src/test/java/io/cloudevents/v03/CloudEventBuilderTest.java @@ -16,22 +16,32 @@ package io.cloudevents.v03; import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import static org.assertj.core.api.Assertions.assertThat; /** - * * @author fabiojose - * */ public class CloudEventBuilderTest { @ParameterizedTest() @MethodSource("io.cloudevents.test.Data#v03Events") void testCopyWithBuilder(CloudEvent event) { - assertThat(CloudEvent.buildV1(event).build()).isEqualTo(event); + assertThat(CloudEvent.buildV03(event).build()).isEqualTo(event); + } + + @ParameterizedTest() + @MethodSource("io.cloudevents.test.Data#v03Events") + void testToV1(CloudEvent event) { + CloudEvent eventV1 = CloudEvent.buildV1(event).build(); + + assertThat(eventV1.getAttributes().getSpecVersion()) + .isEqualTo(SpecVersion.V1); + + assertThat(eventV1).isEqualTo(event.toV1()); } } diff --git a/api/src/test/java/io/cloudevents/v1/CloudEventBuilderTest.java b/api/src/test/java/io/cloudevents/v1/CloudEventBuilderTest.java index af4b43c0..ad9d7d1a 100644 --- a/api/src/test/java/io/cloudevents/v1/CloudEventBuilderTest.java +++ b/api/src/test/java/io/cloudevents/v1/CloudEventBuilderTest.java @@ -16,6 +16,7 @@ package io.cloudevents.v1; import io.cloudevents.CloudEvent; +import io.cloudevents.SpecVersion; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -35,4 +36,15 @@ public class CloudEventBuilderTest { assertThat(CloudEvent.buildV1(event).build()).isEqualTo(event); } + @ParameterizedTest() + @MethodSource("io.cloudevents.test.Data#v1Events") + void testToV03(CloudEvent event) { + CloudEvent eventV03 = CloudEvent.buildV03(event).build(); + + assertThat(eventV03.getAttributes().getSpecVersion()) + .isEqualTo(SpecVersion.V03); + + assertThat(eventV03).isEqualTo(event.toV03()); + } + }