diff --git a/api/src/main/java/io/cloudevents/impl/CloudEventImpl.java b/api/src/main/java/io/cloudevents/impl/CloudEventImpl.java index 91910d2e..a391386a 100644 --- a/api/src/main/java/io/cloudevents/impl/CloudEventImpl.java +++ b/api/src/main/java/io/cloudevents/impl/CloudEventImpl.java @@ -10,7 +10,7 @@ import io.cloudevents.DataConversionException; import io.cloudevents.format.EventFormat; import io.cloudevents.format.json.CloudEventDeserializer; import io.cloudevents.format.json.CloudEventSerializer; -import io.cloudevents.json.Json; +import io.cloudevents.format.json.JsonFormat; import io.cloudevents.message.*; import java.io.IOException; @@ -49,7 +49,7 @@ public final class CloudEventImpl implements CloudEvent, BinaryMessage { if (data instanceof JsonNode) { JsonNode d = (JsonNode) this.data; try { - return Optional.of(Json.MAPPER.writeValueAsString(data)); + return Optional.of(JsonFormat.MAPPER.writeValueAsString(data)); } catch (JsonProcessingException e) { throw new DataConversionException("JsonNode", "String", e); } @@ -71,7 +71,7 @@ public final class CloudEventImpl implements CloudEvent, BinaryMessage { if (data instanceof JsonNode) { JsonNode d = (JsonNode) this.data; try { - return Optional.of(Json.MAPPER.writeValueAsBytes(data)); + return Optional.of(JsonFormat.MAPPER.writeValueAsBytes(data)); } catch (JsonProcessingException e) { throw new DataConversionException("JsonNode", "byte[]", e); } @@ -86,14 +86,14 @@ public final class CloudEventImpl implements CloudEvent, BinaryMessage { if (data != null) { if (data instanceof String) { try { - return Optional.of(Json.MAPPER.readTree((String)data)); + return Optional.of(JsonFormat.MAPPER.readTree((String)data)); } catch (IOException e) { throw new DataConversionException("String", "JsonNode", e); } } if (data instanceof byte[]) { try { - return Optional.of(Json.MAPPER.readTree((byte[]) data)); + return Optional.of(JsonFormat.MAPPER.readTree((byte[]) data)); } catch (IOException e) { throw new DataConversionException("[]byte", "JsonNode", e); } @@ -152,7 +152,7 @@ public final class CloudEventImpl implements CloudEvent, BinaryMessage { @Override public , V> V visit(BinaryMessageVisitorFactory visitorFactory) throws MessageVisitException, IllegalStateException { - BinaryMessageVisitor visitor = visitorFactory.apply(this.attributes.getSpecVersion()); + BinaryMessageVisitor visitor = visitorFactory.createBinaryMessageVisitor(this.attributes.getSpecVersion()); this.attributes.visit(visitor); // TODO to be improved @@ -176,4 +176,19 @@ public final class CloudEventImpl implements CloudEvent, BinaryMessage { return visitor.end(); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CloudEventImpl that = (CloudEventImpl) o; + return Objects.equals(attributes, that.attributes) && + Objects.equals(data, that.data) && + Objects.equals(extensions, that.extensions); + } + + @Override + public int hashCode() { + return Objects.hash(attributes, data, extensions); + } } diff --git a/api/src/main/java/io/cloudevents/json/Json.java b/api/src/main/java/io/cloudevents/json/Json.java deleted file mode 100644 index 48fdc66a..00000000 --- a/api/src/main/java/io/cloudevents/json/Json.java +++ /dev/null @@ -1,282 +0,0 @@ -/** - * Copyright 2018 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.json; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import com.fasterxml.jackson.databind.type.TypeFactory; -import io.cloudevents.Attributes; -import io.cloudevents.CloudEvent; -import io.cloudevents.format.json.ZonedDateTimeDeserializer; -import io.cloudevents.format.json.ZonedDateTimeSerializer; -import io.cloudevents.fun.DataMarshaller; -import io.cloudevents.fun.DataUnmarshaller; - -import java.io.InputStream; -import java.time.ZonedDateTime; -import java.util.Map; - -public final class Json { - - public static final ObjectMapper MAPPER = new ObjectMapper(); - - static { - // add ZonedDateTime ser/de - final SimpleModule module = new SimpleModule("Custom ZonedDateTime"); - module.addSerializer(ZonedDateTime.class, new ZonedDateTimeSerializer()); - module.addDeserializer(ZonedDateTime.class, new ZonedDateTimeDeserializer()); - MAPPER.registerModule(module); - } - - public static String encode(final CloudEvent event) throws IllegalStateException { - - } - - public static byte[] encodeToBinary(final CloudEvent event) throws IllegalStateException { - - } - - public static CloudEvent decode(final byte[] binary) { - - } - - public static CloudEvent decode(final String string) { - - } - - // TODO remove all the stuff below - - /** - * Encode a POJO to JSON using the underlying Jackson mapper. - * - * @param obj a POJO - * @return a String containing the JSON representation of the given POJO. - * @throws IllegalStateException if a property cannot be encoded. - */ - public static String encode(final Object obj) throws IllegalStateException { - try { - return MAPPER.writeValueAsString(obj); - } catch (Exception e) { - throw new IllegalStateException("Failed to encode as JSON: " + e.getMessage()); - } - } - - /** - * Encode a POJO to JSON using the underlying Jackson mapper. - * - * @param obj a POJO - * @return a byte array containing the JSON representation of the given POJO. - * @throws IllegalStateException if a property cannot be encoded. - */ - public static byte[] binaryEncode(final Object obj) throws IllegalStateException { - try { - return MAPPER.writeValueAsBytes(obj); - } catch (Exception e) { - throw new IllegalStateException("Failed to encode as JSON: " + e.getMessage()); - } - } - - public static T fromInputStream(final InputStream inputStream, - Class clazz) { - try { - return MAPPER.readValue(inputStream, clazz); - } catch (Exception e) { - throw new IllegalStateException("Failed to encode as JSON: " - + e.getMessage()); - } - } - - public static T fromInputStream(final InputStream inputStream, - final TypeReference type) { - try { - return MAPPER.readValue(inputStream, type); - } catch (Exception e) { - throw new IllegalStateException("Failed to encode as JSON: " - + e.getMessage()); - } - } - - /** - * Decode a given JSON string to a POJO of the given class type. - * - * @param str the JSON string. - * @param clazz the class to map to. - * @param the generic type. - * @return an instance of T or {@code null} when {@code str} is an empty string or {@code null} - * @throws IllegalStateException when there is a parsing or invalid mapping. - */ - protected static T decodeValue(final String str, final Class clazz) throws IllegalStateException { - - if(null!= str && !"".equals(str.trim())) { - try { - return MAPPER.readValue(str.trim(), clazz); - } catch (Exception e) { - throw new IllegalStateException("Failed to decode: " + e.getMessage()); - } - } - - return null; - } - - protected static T binaryDecodeValue(byte[] payload, final Class clazz) { - if(null!= payload) { - try { - return MAPPER.readValue(payload, clazz); - } catch (Exception e) { - throw new IllegalStateException("Failed to decode: " + e.getMessage()); - } - } - return null; - } - - /** - * Decode a given JSON string to a POJO of the given type. - * - * @param str the JSON string. - * @param type the type to map to. - * @param the generic type. - * @return an instance of T or {@code null} when {@code str} is an empty string or {@code null} - * @throws IllegalStateException when there is a parsing or invalid mapping. - */ - public static T decodeValue(final String str, final TypeReference type) throws IllegalStateException { - if(null!= str && !"".equals(str.trim())) { - try { - return MAPPER.readValue(str.trim(), type); - } catch (Exception e) { - throw new IllegalStateException("Failed to decode: " + e.getMessage(), e); - } - } - return null; - } - - /** - * Example of use: - *
-     * String someJson = "...";
-     * Class clazz = Much.class;
-     *
-     * Json.decodeValue(someJson, CloudEventImpl.class, clazz);
-     * 
- * @param str The JSON String to parse - * @param parametrized Actual full type - * @param parameterClasses Type parameters to apply - * @param the generic type. - * @return An instance of T or {@code null} when {@code str} is an empty string or {@code null} - * @see ObjectMapper#getTypeFactory - * @see TypeFactory#constructParametricType(Class, Class...) - */ - public static T decodeValue(final String str, Class parametrized, - Class...parameterClasses) { - if(null!= str && !"".equals(str.trim())) { - try { - JavaType type = - MAPPER.getTypeFactory() - .constructParametricType(parametrized, - parameterClasses); - - return MAPPER.readValue(str.trim(), type); - } catch (Exception e) { - throw new IllegalStateException("Failed to decode: " + e.getMessage(), e); - } - } - return null; - } - - /** - * Example of use: - *
-     * String someJson = "...";
-     * Class clazz = Much.class;
-     *
-     * Json.decodeValue(someJson, CloudEventImpl.class, clazz);
-     * 
- * @param json The JSON byte array to parse - * @param parametrized Actual full type - * @param parameterClasses Type parameters to apply - * @param the generic type. - * @return An instance of T or {@code null} when {@code str} is an empty string or {@code null} - * @see ObjectMapper#getTypeFactory - * @see TypeFactory#constructParametricType(Class, Class...) - */ - public static T binaryDecodeValue(final byte[] json, Class parametrized, - Class...parameterClasses) { - if(null!= json) { - try { - JavaType type = - MAPPER.getTypeFactory() - .constructParametricType(parametrized, - parameterClasses); - - return MAPPER.readValue(json, type); - } catch (Exception e) { - throw new IllegalStateException("Failed to decode: " + e.getMessage(), e); - } - } - return null; - } - - /** - * Creates a JSON Data Unmarshaller - * @param The 'data' type - * @param The attributes type - * @param type The type of 'data' - * @return A new instance of {@link DataUnmarshaller} - */ - public static DataUnmarshaller - umarshaller(Class type) { - return (payload, attributes) -> Json.decodeValue(payload, type); - } - - /** - * Unmarshals a byte array into T type - * @param The 'data' type - * @param The attributes type - * @return The data objects - */ - public static DataUnmarshaller - binaryUmarshaller(Class type) { - return (payload, attributes) -> Json.binaryDecodeValue(payload, type); - } - - /** - * Creates a JSON Data Marshaller that produces a {@link String} - * @param The 'data' type - * @param The type of headers value - * @return A new instance of {@link DataMarshaller} - */ - public static DataMarshaller marshaller() { - return (data, headers) -> Json.encode(data); - } - - /** - * Marshalls the 'data' value as JSON, producing a byte array - * @param The 'data' type - * @param The type of headers value - * @param data The 'data' value - * @param headers The headers - * @return A byte array with 'data' value encoded JSON - */ - public static byte[] binaryMarshal(T data, - Map headers) { - return Json.binaryEncode(data); - } - - private Json() { - // no-op - } -} diff --git a/api/src/main/java/io/cloudevents/message/BinaryMessageVisitorFactory.java b/api/src/main/java/io/cloudevents/message/BinaryMessageVisitorFactory.java index 30999963..f4fb81ea 100644 --- a/api/src/main/java/io/cloudevents/message/BinaryMessageVisitorFactory.java +++ b/api/src/main/java/io/cloudevents/message/BinaryMessageVisitorFactory.java @@ -2,7 +2,7 @@ package io.cloudevents.message; import io.cloudevents.SpecVersion; -import java.util.function.Function; - @FunctionalInterface -public interface BinaryMessageVisitorFactory, V> extends Function { } +public interface BinaryMessageVisitorFactory, V> { + T createBinaryMessageVisitor(SpecVersion version); +} diff --git a/api/src/main/java/io/cloudevents/message/Message.java b/api/src/main/java/io/cloudevents/message/Message.java index 99d29e54..56ecf058 100644 --- a/api/src/main/java/io/cloudevents/message/Message.java +++ b/api/src/main/java/io/cloudevents/message/Message.java @@ -6,6 +6,14 @@ public interface Message extends StructuredMessage, BinaryMessage { Encoding getEncoding(); + default , R> R visit(MessageVisitor visitor) throws MessageVisitException, IllegalStateException { + switch (getEncoding()) { + case BINARY: return this.visit((BinaryMessageVisitorFactory) visitor); + case STRUCTURED: return this.visit((StructuredMessageVisitor)visitor); + default: throw Encoding.UNKNOWN_ENCODING_EXCEPTION; + } + } + default CloudEvent toEvent() throws MessageVisitException, IllegalStateException { switch (getEncoding()) { case BINARY: return ((BinaryMessage)this).toEvent(); diff --git a/api/src/main/java/io/cloudevents/message/MessageVisitor.java b/api/src/main/java/io/cloudevents/message/MessageVisitor.java new file mode 100644 index 00000000..9d6e9c86 --- /dev/null +++ b/api/src/main/java/io/cloudevents/message/MessageVisitor.java @@ -0,0 +1,3 @@ +package io.cloudevents.message; + +public interface MessageVisitor, R> extends BinaryMessageVisitorFactory, StructuredMessageVisitor { } diff --git a/api/src/main/java/io/cloudevents/v03/AttributesImpl.java b/api/src/main/java/io/cloudevents/v03/AttributesImpl.java index 7319beca..57e18c7c 100644 --- a/api/src/main/java/io/cloudevents/v03/AttributesImpl.java +++ b/api/src/main/java/io/cloudevents/v03/AttributesImpl.java @@ -23,6 +23,7 @@ import io.cloudevents.message.MessageVisitException; import java.net.URI; import java.time.ZonedDateTime; +import java.util.Objects; import java.util.Optional; /** @@ -74,6 +75,7 @@ public final class AttributesImpl implements AttributesInternal { public Optional getDataContentType() { return Optional.ofNullable(datacontenttype); } + public Optional getDataSchema() { return getSchemaUrl(); } @@ -156,85 +158,24 @@ public final class AttributesImpl implements AttributesInternal { + ", datacontenttype=" + datacontenttype + ", subject=" + subject + "]"; } -// -// /** -// * Used by the Jackson framework to unmarshall. -// */ -// @JsonCreator -// public static AttributesImpl build( -// @JsonProperty("id") String id, -// @JsonProperty("source") URI source, -// @JsonProperty("type") String type, -// @JsonProperty("time") ZonedDateTime time, -// @JsonProperty("schemaurl") URI schemaurl, -// @JsonProperty("datacontenttype") String datacontenttype, -// @JsonProperty("subject") String subject) { -// -// return new AttributesImpl(id, source, type, time, -// schemaurl, datacontenttype, subject); -// } -// -// /** -// * Creates the marshaller instance to marshall {@link AttributesImpl} as -// * a {@link Map} of strings -// */ -// public static Map marshal(AttributesImpl attributes) { -// Objects.requireNonNull(attributes); -// -// Map result = new HashMap<>(); -// -// result.put(ContextAttributes.TYPE.name(), -// attributes.getType()); -// result.put(ContextAttributes.SPECVERSION.name(), -// attributes.getSpecVersion()); -// result.put(ContextAttributes.SOURCE.name(), -// attributes.getSource().toString()); -// result.put(ContextAttributes.ID.name(), -// attributes.getId()); -// -// attributes.getTime().ifPresent((value) -> result.put(ContextAttributes.TIME.name(), -// value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))); -// attributes.getSchemaurl().ifPresent((schema) -> result.put(ContextAttributes.SCHEMAURL.name(), -// schema.toString())); -// attributes.getDatacontenttype().ifPresent((ct) -> result.put(ContextAttributes.DATACONTENTTYPE.name(), ct)); -// attributes.getDatacontentencoding().ifPresent(dce -> result.put(ContextAttributes.DATACONTENTENCODING.name(), dce)); -// attributes.getSubject().ifPresent(subject -> result.put(ContextAttributes.SUBJECT.name(), subject)); -// -// return result; -// } -// -// /** -// * The attribute unmarshaller for the binary format, that receives a -// * {@code Map} with attributes names as String and value as String. -// */ -// public static AttributesImpl unmarshal(Map attributes) { -// String type = attributes.get(ContextAttributes.TYPE.name()); -// ZonedDateTime time = -// Optional.ofNullable(attributes.get(ContextAttributes.TIME.name())) -// .map((t) -> ZonedDateTime.parse(t, -// ISO_ZONED_DATE_TIME)) -// .orElse(null); -// -// String specversion = attributes.get(ContextAttributes.SPECVERSION.name()); -// URI source = URI.create(attributes.get(ContextAttributes.SOURCE.name())); -// -// URI schemaurl = -// Optional.ofNullable(attributes.get(ContextAttributes.SCHEMAURL.name())) -// .map(URI::create) -// .orElse(null); -// -// String id = attributes.get(ContextAttributes.ID.name()); -// -// String datacontenttype = -// attributes.get(ContextAttributes.DATACONTENTTYPE.name()); -// -// String datacontentencoding = -// attributes.get(ContextAttributes.DATACONTENTENCODING.name()); -// -// String subject = attributes.get(ContextAttributes.SUBJECT.name()); -// -// return AttributesImpl.build(id, source, specversion, type, -// time, schemaurl, datacontentencoding, -// datacontenttype, subject); -// } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AttributesImpl that = (AttributesImpl) o; + return Objects.equals(id, that.id) && + Objects.equals(source, that.source) && + Objects.equals(type, that.type) && + Objects.equals(datacontenttype, that.datacontenttype) && + Objects.equals(schemaurl, that.schemaurl) && + Objects.equals(subject, that.subject) && + Objects.equals(time, that.time); + } + + @Override + public int hashCode() { + return Objects.hash(id, source, type, datacontenttype, schemaurl, subject, time); + } + } diff --git a/api/src/main/java/io/cloudevents/v1/AttributesImpl.java b/api/src/main/java/io/cloudevents/v1/AttributesImpl.java index 684335ff..def3bba3 100644 --- a/api/src/main/java/io/cloudevents/v1/AttributesImpl.java +++ b/api/src/main/java/io/cloudevents/v1/AttributesImpl.java @@ -23,6 +23,7 @@ import io.cloudevents.message.MessageVisitException; import java.net.URI; import java.time.ZonedDateTime; +import java.util.Objects; import java.util.Optional; /** @@ -155,76 +156,22 @@ public final class AttributesImpl implements AttributesInternal { + ", time=" + time + "]"; } -// /** -// * Used by the Jackson framework to unmarshall. -// */ -// @JsonCreator -// public static AttributesImpl build( -// @JsonProperty("id") String id, -// @JsonProperty("source") URI source, -// @JsonProperty("type") String type, -// @JsonProperty("datacontenttype") String datacontenttype, -// @JsonProperty("dataschema") URI dataschema, -// @JsonProperty("subject") String subject, -// @JsonProperty("time") ZonedDateTime time) { -// -// return new AttributesImpl(id, source, type, -// datacontenttype, dataschema, subject, time); -// } -// -// /** -// * Creates the marshaller instance to marshall {@link AttributesImpl} as -// * a {@link Map} of strings -// */ -// public static Map marshal(AttributesImpl attributes) { -// Objects.requireNonNull(attributes); -// Map result = new HashMap<>(); -// -// result.put(ContextAttributes.ID.name(), -// attributes.getId()); -// result.put(ContextAttributes.SOURCE.name(), -// attributes.getSource().toString()); -// result.put(ContextAttributes.TYPE.name(), -// attributes.getType()); -// -// attributes.getDatacontenttype().ifPresent(dct -> result.put(ContextAttributes.DATACONTENTTYPE.name(), dct)); -// attributes.getDataschema().ifPresent(dataschema -> result.put(ContextAttributes.DATASCHEMA.name(), -// dataschema.toString())); -// attributes.getSubject().ifPresent(subject -> result.put(ContextAttributes.SUBJECT.name(), subject)); -// attributes.getTime().ifPresent(time -> result.put(ContextAttributes.TIME.name(), -// time.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))); -// -// return result; -// } -// -// /** -// * The attribute unmarshaller for the binary format, that receives a -// * {@code Map} with attributes names as String and value as String. -// */ -// public static AttributesImpl unmarshal(Map attributes) { -// String type = attributes.get(ContextAttributes.TYPE.name()); -// ZonedDateTime time = -// Optional.ofNullable(attributes.get(ContextAttributes.TIME.name())) -// .map((t) -> ZonedDateTime.parse(t, -// ISO_ZONED_DATE_TIME)) -// .orElse(null); -// -// String specversion = attributes.get(ContextAttributes.SPECVERSION.name()); -// URI source = URI.create(attributes.get(ContextAttributes.SOURCE.name())); -// -// URI dataschema = -// Optional.ofNullable(attributes.get(ContextAttributes.DATASCHEMA.name())) -// .map(URI::create) -// .orElse(null); -// -// String id = attributes.get(ContextAttributes.ID.name()); -// -// String datacontenttype = -// attributes.get(ContextAttributes.DATACONTENTTYPE.name()); -// -// String subject = attributes.get(ContextAttributes.SUBJECT.name()); -// -// return AttributesImpl.build(id, source, type, -// datacontenttype, dataschema, subject, time); -// } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AttributesImpl that = (AttributesImpl) o; + return Objects.equals(id, that.id) && + Objects.equals(source, that.source) && + Objects.equals(type, that.type) && + Objects.equals(datacontenttype, that.datacontenttype) && + Objects.equals(dataschema, that.dataschema) && + Objects.equals(subject, that.subject) && + Objects.equals(time, that.time); + } + + @Override + public int hashCode() { + return Objects.hash(id, source, type, datacontenttype, dataschema, subject, time); + } } diff --git a/api/src/test/java/io/cloudevents/format/StructuredMarshallerTest.java b/api/src/test/java/io/cloudevents/format/StructuredMarshallerTest.java deleted file mode 100644 index 45395d6e..00000000 --- a/api/src/test/java/io/cloudevents/format/StructuredMarshallerTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.format; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import io.cloudevents.Attributes; -import io.cloudevents.json.types.Much; - -/** - * - * @author fabiojose - * - */ -public class StructuredMarshallerTest { - - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void should_throw_on_null_envelope_mime_header() { - // setup - expectedEx.expect(NullPointerException.class); - - // act - StructuredMarshaller.builder() - .mime(null, ""); - } - - @Test - public void should_throw_on_null_envelope_mime_value() { - // setup - expectedEx.expect(NullPointerException.class); - - // act - StructuredMarshaller.builder() - .mime("", null); - } - - @Test - public void should_be_ok_on_the_first_step() { - - // act - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json"); - } - - @Test - public void should_throw_on_null_marshaller_step() { - // setup - expectedEx.expect(NullPointerException.class); - - // act - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map(null); - } - - @Test - public void should_throw_on_null_event() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map((ce) -> null) - .skip() - .withEvent(null); - } - - @Test - public void should_be_ok_on_the_third_step() { - // act - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map((ce) -> null) - .skip() - .withEvent(() -> null); - } - - @Test - public void should_throw_on_null_extension_accessor() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map((ce) -> null) - .map(null); - } - - @Test - public void should_ok_on_the_extension_acessor() { - // act - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map((ce) -> null) - .map((event) -> null); - } - - @Test - public void should_throw_on_null_extension_marshaller() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map((ce) -> null) - .map((event) -> null) - .map(null); - } - - @Test - public void should_ok_on_extension_marshaller() { - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map((ce) -> null) - .map((event) -> null) - .map((extensions) -> null); - } - - @Test - public void should_throw_on_null_header_mapper() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map((ce) -> null) - .map((event) -> null) - .map((extensions) -> null) - .map(null); - } - - @Test - public void should_ok_on_header_mapper() { - StructuredMarshaller.builder() - .mime("Content-Type", "application/cloudevents+json") - .map((ce) -> null) - .map((event) -> null) - .map((extensions) -> null) - .map((attributes, extensions) -> null); - } -} diff --git a/api/src/test/java/io/cloudevents/format/StructuredUnmarshallerTest.java b/api/src/test/java/io/cloudevents/format/StructuredUnmarshallerTest.java deleted file mode 100644 index 156ca989..00000000 --- a/api/src/test/java/io/cloudevents/format/StructuredUnmarshallerTest.java +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.format; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import io.cloudevents.Attributes; -import io.cloudevents.json.types.Much; - -/** - * - * @author fabiojose - * - */ -public class StructuredUnmarshallerTest { - - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void should_throw_on_null_extension_mapper() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredUnmarshaller.builder() - .map(null); - } - - @Test - public void should_ok_on_extension_mapper() { - StructuredUnmarshaller.builder() - .map((headers) -> { - - return null; - }); - } - - @Test - public void should_throw_on_null_extension_unmarshaller() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredUnmarshaller.builder() - .map((headers) -> { - - return null; - }) - .map(null); - } - - @Test - public void should_ok_on_extension_unmarshaller() { - StructuredUnmarshaller.builder() - .map((headers) -> { - - return null; - }) - .map((extensions) -> { - return null; - }); - } - - @Test - public void should_throw_on_null_envelope_unmarshaller() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredUnmarshaller.builder() - .map((headers) -> { - - return null; - }) - .map((extensions) -> { - return null; - }) - .next() - .map(null); - } - - @Test - public void should_ok_on_envelope_unmarshaller() { - StructuredUnmarshaller.builder() - .map((headers) -> null) - .map((extensions) -> null) - .next() - .map((payload, extensions) -> null); - } - - @Test - public void should_throw_on_null_headers() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredUnmarshaller.builder() - .map((headers) -> null) - .map((extensions) -> null) - .next() - .map((payload, extensions) -> null) - .withHeaders(null); - } - - @Test - public void should_ok_on_headers() { - StructuredUnmarshaller.builder() - .map((headers) -> null) - .map((extensions) -> null) - .next() - .map((payload, extensions) -> null) - .withHeaders(() -> null); - } - - @Test - public void should_throw_on_null_payload_supplier() { - // setup - expectedEx.expect(NullPointerException.class); - - StructuredUnmarshaller.builder() - .map((headers) -> null) - .map((extensions) -> null) - .next() - .map((payload, extensions) -> null) - .withHeaders(() -> null) - .withPayload(null); - } - - @Test - public void should_ok_on_payload_supplier() { - StructuredUnmarshaller.builder() - .map((headers) -> null) - .map((extensions) -> null) - .next() - .map((payload, extensions) -> null) - .withHeaders(() -> null) - .withPayload(() -> null); - } -} diff --git a/api/src/test/java/io/cloudevents/format/WireTest.java b/api/src/test/java/io/cloudevents/format/WireTest.java deleted file mode 100644 index 33dd942a..00000000 --- a/api/src/test/java/io/cloudevents/format/WireTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.format; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -/** - * - * @author fabiojose - * - */ -public class WireTest { - - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void throws_error_when_null_headers() { - - // setup - expectedEx.expect(NullPointerException.class); - - new Wire("payload", null); - } - - @Test - public void throws_when_try_to_change_headers() { - // setup - expectedEx.expect(UnsupportedOperationException.class); - - Map headers = new HashMap<>(); - headers.put("contenttype", "application/json"); - - // act - Wire wire = new Wire<>("payload", headers); - - wire.getHeaders().put("my-header", "my-header-val"); - } - - @Test - public void should_ok_when_null_payload() { - Wire expected = - new Wire<>(null, new HashMap<>()); - - assertFalse(expected.getPayload().isPresent()); - } - - @Test - public void should_ok_when_payload_not_null() { - Wire actual = - new Wire<>("payload", new HashMap<>()); - - assertTrue(actual.getPayload().isPresent()); - assertEquals("payload", actual.getPayload().get()); - } - -} diff --git a/api/src/test/java/io/cloudevents/http/HttpTransportAttributesTest.java b/api/src/test/java/io/cloudevents/http/HttpTransportAttributesTest.java deleted file mode 100644 index fe576161..00000000 --- a/api/src/test/java/io/cloudevents/http/HttpTransportAttributesTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Copyright 2018 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.http; - -import static org.junit.Assert.assertEquals; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; - -public class HttpTransportAttributesTest { - - @Test - public void testVersion02Headers() { - // setup - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "0.2"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-schemaurl", "http://my.br"); - myHeaders.put("Content-Type", "application/json"); - - // act - Map attributes = io.cloudevents.v02.http.AttributeMapper.map(myHeaders); - - // assert - assertEquals("0x11", attributes.get("id")); - assertEquals("/source", attributes.get("source")); - assertEquals("0.2", attributes.get("specversion")); - assertEquals("br.my", attributes.get("type")); - assertEquals("2019-09-16T20:49:00Z", attributes.get("time")); - assertEquals("http://my.br", attributes.get("schemaurl")); - assertEquals("application/json", attributes.get("contenttype")); - } - - @Test - public void shoul_map_attributes_v02() { - // setup - Map attributes = new HashMap<>(); - attributes.put("id", "0x11"); - attributes.put("source", "/source"); - attributes.put("specversion", "0.2"); - attributes.put("type", "br.my"); - attributes.put("time", "2019-09-16T20:49:00Z"); - attributes.put("schemaurl", "http://my.br"); - attributes.put("contenttype", "application/json"); - - // act - Map headers = io.cloudevents.v02.http.HeaderMapper - .map(attributes, new HashMap()); - - // assert - assertEquals("0x11", headers.get("ce-id")); - assertEquals("/source", headers.get("ce-source")); - assertEquals("0.2", headers.get("ce-specversion")); - assertEquals("br.my", headers.get("ce-type")); - assertEquals("2019-09-16T20:49:00Z", headers.get("ce-time")); - assertEquals("http://my.br", headers.get("ce-schemaurl")); - assertEquals("application/json", headers.get("Content-Type")); - } - - @Test - public void should_map_headers_v03() { - // setup - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "0.2"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-schemaurl", "http://my.br"); - myHeaders.put("Content-Type", "application/json"); - myHeaders.put("ce-datacontentencoding", "base64"); - myHeaders.put("ce-subject", "the subject"); - - // act - Map attributes = io.cloudevents.v03.http.AttributeMapper.map(myHeaders); - - // assert - assertEquals("0x11", attributes.get("id")); - assertEquals("/source", attributes.get("source")); - assertEquals("0.2", attributes.get("specversion")); - assertEquals("br.my", attributes.get("type")); - assertEquals("2019-09-16T20:49:00Z", attributes.get("time")); - assertEquals("http://my.br", attributes.get("schemaurl")); - assertEquals("application/json", attributes.get("datacontenttype")); - assertEquals("base64", attributes.get("datacontentencoding")); - assertEquals("the subject", attributes.get("subject")); - } -} diff --git a/api/src/test/java/io/cloudevents/impl/CloudEventImplTest.java b/api/src/test/java/io/cloudevents/impl/CloudEventImplTest.java new file mode 100644 index 00000000..70fddcf4 --- /dev/null +++ b/api/src/test/java/io/cloudevents/impl/CloudEventImplTest.java @@ -0,0 +1,4 @@ +package io.cloudevents.impl; + +public class CloudEventImplTest { +} diff --git a/api/src/test/java/io/cloudevents/json/JsonTest.java b/api/src/test/java/io/cloudevents/json/JsonTest.java deleted file mode 100644 index e7ab82f7..00000000 --- a/api/src/test/java/io/cloudevents/json/JsonTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.json; - -import static org.junit.Assert.assertNull; - -import java.util.Map; - -import org.junit.Test; - -import com.fasterxml.jackson.core.type.TypeReference; - -/** - * - * @author fabiojose - * - */ -public class JsonTest { - - @Test - public void should_result_null_on_decode_type_empty_string() { - // setup - String payload = ""; - - // act - Object actual = Json.decodeValue(payload, Map.class); - - // assert - assertNull(actual); - } - - @Test - public void should_result_null_on_decode_type_null_string() { - - // act - Object actual = Json.decodeValue(null, Map.class); - - // assert - assertNull(actual); - } - - @Test - public void should_result_null_on_decode_typereference_empty_string() { - // setup - String payload = ""; - - // act - Object actual = Json.decodeValue(payload, new TypeReference>() {}); - - // assert - assertNull(actual); - } - - @Test - public void should_result_null_on_decode_typereference_null_string() { - - // act - Object actual = Json.decodeValue(null, new TypeReference>() {}); - - // assert - assertNull(actual); - } -} diff --git a/api/src/test/java/io/cloudevents/message/EventMessageRoundtripTest.java b/api/src/test/java/io/cloudevents/message/EventMessageRoundtripTest.java new file mode 100644 index 00000000..6e574a10 --- /dev/null +++ b/api/src/test/java/io/cloudevents/message/EventMessageRoundtripTest.java @@ -0,0 +1,26 @@ +package io.cloudevents.message; + +import io.cloudevents.CloudEvent; +import io.cloudevents.format.json.JsonFormat; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.assertj.core.api.Assertions.assertThat; + +public class EventMessageRoundtripTest { + + @ParameterizedTest() + @MethodSource("io.cloudevents.test.Data#allEvents") + void structuredToEvent(CloudEvent input) { + assertThat(input.asStructuredMessage(JsonFormat.getInstance()).toEvent()) + .isEqualTo(input); + } + + @ParameterizedTest() + @MethodSource("io.cloudevents.test.Data#allEvents") + void binaryToEvent(CloudEvent input) { + assertThat(input.asBinaryMessage().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 new file mode 100644 index 00000000..a784bf2b --- /dev/null +++ b/api/src/test/java/io/cloudevents/mock/MockBinaryMessage.java @@ -0,0 +1,122 @@ +package io.cloudevents.mock; + +import io.cloudevents.SpecVersion; +import io.cloudevents.message.*; + +import java.net.URI; +import java.time.ZonedDateTime; +import java.util.HashMap; +import java.util.Map; + +public class MockBinaryMessage implements Message, BinaryMessageVisitorFactory, BinaryMessageVisitor { + + private SpecVersion version; + private Map attributes; + private byte[] data; + private Map extensions; + + public MockBinaryMessage(SpecVersion version, Map attributes, byte[] data, Map extensions) { + this.version = version; + this.attributes = attributes; + this.data = data; + this.extensions = extensions; + } + + public MockBinaryMessage() { + this.attributes = new HashMap<>(); + this.extensions = new HashMap<>(); + } + + @Override + public Encoding getEncoding() { + return Encoding.BINARY; + } + + @Override + public , V> V visit(BinaryMessageVisitorFactory visitorFactory) throws MessageVisitException, IllegalStateException { + if (version == null) { + throw new IllegalStateException("MockBinaryMessage is empty"); + } + + BinaryMessageVisitor visitor = visitorFactory.createBinaryMessageVisitor(version); + for (Map.Entry 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 { + // This should never happen because we build that map only through our builders + throw new IllegalStateException("Illegal value inside extensions map: " + e); + } + } + + for (Map.Entry entry : this.extensions.entrySet()) { + if (entry.getValue() instanceof String) { + visitor.setExtension(entry.getKey(), (String) entry.getValue()); + } else if (entry.getValue() instanceof Number) { + visitor.setExtension(entry.getKey(), (Number) entry.getValue()); + } else if (entry.getValue() instanceof Boolean) { + visitor.setExtension(entry.getKey(), (Boolean) entry.getValue()); + } else { + // This should never happen because we build that map only through our builders + throw new IllegalStateException("Illegal value inside extensions map: " + entry); + } + } + + visitor.setBody(this.data); + + return visitor.end(); + } + + @Override + public T visit(StructuredMessageVisitor visitor) throws MessageVisitException, IllegalStateException { + throw Encoding.UNKNOWN_ENCODING_EXCEPTION; + } + + @Override + public void setBody(byte[] value) throws MessageVisitException { + this.data = value; + } + + @Override + public MockBinaryMessage end() { + return this; + } + + @Override + public void setAttribute(String name, String value) throws MessageVisitException { + this.attributes.put(name, value); + } + + @Override + public void setAttribute(String name, URI value) throws MessageVisitException { + this.attributes.put(name, value); + } + + @Override + public void setAttribute(String name, ZonedDateTime value) throws MessageVisitException { + this.attributes.put(name, value); + } + + @Override + public void setExtension(String name, String value) throws MessageVisitException { + this.extensions.put(name, value); + } + + @Override + public void setExtension(String name, Number value) throws MessageVisitException { + this.extensions.put(name, value); + } + + @Override + public void setExtension(String name, Boolean value) throws MessageVisitException { + this.extensions.put(name, value); + } + + @Override + public MockBinaryMessage createBinaryMessageVisitor(SpecVersion version) { + return this; + } +} diff --git a/api/src/test/java/io/cloudevents/test/Data.java b/api/src/test/java/io/cloudevents/test/Data.java new file mode 100644 index 00000000..ff305823 --- /dev/null +++ b/api/src/test/java/io/cloudevents/test/Data.java @@ -0,0 +1,55 @@ +package io.cloudevents.test; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.cloudevents.CloudEvent; + +import java.net.URI; +import java.time.ZonedDateTime; +import java.util.UUID; +import java.util.stream.Stream; + +public class Data { + + public static final String ID = UUID.randomUUID().toString(); + public static final String TYPE = "mock.test"; + public static final URI SOURCE = URI.create("http://localhost/source"); + 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 JsonNode DATA_JSON = new ObjectNode(JsonNodeFactory.instance); + + public static final CloudEvent V1_MIN = CloudEvent.buildV1() + .withId(ID) + .withType(TYPE) + .withSource(SOURCE) + .build(); + + public static final CloudEvent V1_WITH_JSON_DATA = CloudEvent.buildV1() + .withId(ID) + .withType(TYPE) + .withSource(SOURCE) + .withData(DATACONTENTTYPE_JSON, DATASCHEMA, DATA_JSON) + .withSubject(SUBJECT) + .withTime(TIME) + .build(); + + public static Stream allEvents() { + return Stream.concat(v1Events(), v03Events()); + } + + public static Stream v1Events() { + return Stream.of( + Data.V1_MIN, + Data.V1_WITH_JSON_DATA + ); + } + + public static Stream v03Events() { + return v1Events().map(CloudEvent::toV03); + } + +} diff --git a/api/src/test/java/io/cloudevents/v03/AccessorTest.java b/api/src/test/java/io/cloudevents/v03/AccessorTest.java deleted file mode 100644 index 62de610e..00000000 --- a/api/src/test/java/io/cloudevents/v03/AccessorTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.net.URI; -import java.util.Collection; - -import org.junit.Test; - -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.extensions.InMemoryFormat; -import io.cloudevents.v03.Accessor; -import io.cloudevents.v03.CloudEventBuilder; -import io.cloudevents.v03.CloudEventImpl; - -/** - * - * @author fabiojose - * - */ -public class AccessorTest { - - @Test - public void should_empty_collection_when_no_extensions() { - // setup - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withSchemaurl(URI.create("/schema")) - .withDatacontenttype("text/plain") - .withData("my-data") - .build(); - - // act - Collection actual = Accessor.extensionsOf(ce); - - // assert - assertTrue(actual.isEmpty()); - } - - @Test - public void should_return_the_tracing_extension() { - // setup - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat expected = new DistributedTracingExtension.Format(dt); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withSchemaurl(URI.create("/schema")) - .withDatacontenttype("text/plain") - .withData("my-data") - .withExtension(expected) - .build(); - - // act - Collection extensions = - Accessor.extensionsOf(ce); - - // assert - assertFalse(extensions.isEmpty()); - ExtensionFormat actual = extensions.iterator().next(); - - assertEquals("0", actual.transport().get("traceparent")); - assertEquals("congo=4", actual.transport().get("tracestate")); - - assertEquals("0", - ((DistributedTracingExtension)actual.memory().getValue()).getTraceparent()); - - assertEquals("congo=4", - ((DistributedTracingExtension)actual.memory().getValue()).getTracestate()); - } - - @Test - public void should_return_the_custom_extension() { - // setup - String customExt = "comexampleextension1"; - String customVal = "my-ext-val"; - InMemoryFormat inMemory = - InMemoryFormat.of(customExt, customVal, String.class); - - ExtensionFormat expected = - ExtensionFormat.of(inMemory, customExt, customVal); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withSchemaurl(URI.create("/schema")) - .withDatacontenttype("text/plain") - .withData("my-data") - .withExtension(expected) - .build(); - - // act - Collection extensions = - Accessor.extensionsOf(ce); - - // assert - assertFalse(extensions.isEmpty()); - ExtensionFormat actual = extensions.iterator().next(); - - assertEquals(customVal, actual.transport().get(customExt)); - - assertEquals(String.class, actual.memory().getValueType()); - - assertEquals(customExt, actual.memory().getKey()); - - assertEquals(customVal, actual.memory().getValue()); - } -} diff --git a/api/src/test/java/io/cloudevents/v03/CloudEventBuilderTest.java b/api/src/test/java/io/cloudevents/v03/CloudEventBuilderTest.java index 07434be0..5c3c2eff 100644 --- a/api/src/test/java/io/cloudevents/v03/CloudEventBuilderTest.java +++ b/api/src/test/java/io/cloudevents/v03/CloudEventBuilderTest.java @@ -15,33 +15,11 @@ */ package io.cloudevents.v03; -import static io.cloudevents.v03.CloudEventBuilder.builder; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.net.URI; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; -import javax.validation.executable.ExecutableValidator; -import javax.validation.metadata.BeanDescriptor; - -import io.cloudevents.validation.MockValidator; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - import io.cloudevents.CloudEvent; -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.extensions.InMemoryFormat; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.assertj.core.api.Assertions.assertThat; /** * @@ -50,206 +28,10 @@ import io.cloudevents.extensions.InMemoryFormat; */ public class CloudEventBuilderTest { - @Rule - public ExpectedException expectedEx = ExpectedException.none(); + @ParameterizedTest() + @MethodSource("io.cloudevents.test.Data#v03Events") + void testCopyWithBuilder(CloudEvent event) { + assertThat(CloudEvent.buildV1(event).build()).isEqualTo(event); + } - @Test - public void error_when_null_id() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'id' must not be blank"); - - // act - builder() - .withSource(URI.create("/test")) - .withType("type") - .build(); - } - - @Test - public void error_when_empty_id() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'id' must not be blank"); - - // act - builder() - .withId("") - .withSource(URI.create("/test")) - .withType("type") - .build(); - } - - @Test - public void error_when_null_type() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'type' must not be blank"); - - // act - builder() - .withId("id") - .withSource(URI.create("/test")) - .build(); - } - - @Test - public void error_when_empty_type() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'type' must not be blank"); - - // act - builder() - .withId("id") - .withSource(URI.create("/test")) - .withType("") - .build(); - } - - @Test - public void error_when_null_source() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'source' must not be null"); - - // act - builder() - .withId("id") - .withType("type") - .build(); - } - - @Test - public void error_when_empty_subject() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'subject' size must be between 1 and 2147483647"); - - // act - CloudEventBuilder.builder() - .withId("id") - .withType("type") - .withSource(URI.create("/source")) - .withSubject("") - .build(); - } - - @Test - public void error_when_invalid_encoding() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'datacontentencoding' must match \"base64\""); - - // act - CloudEventBuilder.builder() - .withId("id") - .withType("type") - .withSource(URI.create("/source")) - .withSubject("subject") - .withDatacontentencoding("binary") - .build(); - } - - @Test - public void should_have_subject() { - // act - CloudEvent ce = - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withSubject("subject") - .build(); - - // assert - assertTrue(ce.getAttributes().getSubject().isPresent()); - assertEquals("subject", ce.getAttributes().getSubject().get()); - } - - @Test - public void should_have_dte() { - // setup - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat tracing = new DistributedTracingExtension.Format(dt); - - // act - CloudEventImpl ce = - builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withExtension(tracing) - .build(); - - Object actual = ce.getExtensions() - .get(DistributedTracingExtension.Format.IN_MEMORY_KEY); - - // assert - assertNotNull(actual); - assertTrue(actual instanceof DistributedTracingExtension); - } - - @Test - public void should_have_custom_extension() { - String myExtKey = "comexampleextension1"; - String myExtVal = "value"; - - ExtensionFormat custom = ExtensionFormat - .of(InMemoryFormat.of(myExtKey, myExtKey, String.class), - myExtKey, myExtVal); - - // act - CloudEventImpl ce = - builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withExtension(custom) - .build(); - - Object actual = ce.getExtensions() - .get(myExtKey); - - assertNotNull(actual); - assertTrue(actual instanceof String); - } - - @Test - public void should_build_event_using_custom_validator() { - Validator validator = new MockValidator(); - String expected = "test"; - - CloudEventImpl event = CloudEventBuilder - .builder() - .withData(expected) - .withValidator(validator) - .build(); - - assertNotNull(event); - assertEquals(expected, event.getData().get()); - } - - @Test - public void should_build_event_from_event_using_custom_validator() { - Validator validator = new MockValidator(); - String expected = "test"; - CloudEvent event = CloudEventBuilder.of( - expected, - new AttributesImpl(null, null, null, null, null, null, null, null, null), - Collections.emptyList(), - validator - ); - - CloudEvent result = CloudEventBuilder - .builder(event) - .withValidator(validator) - .build(); - - assertNotNull(result); - assertEquals(expected, result.getData().get()); - } } diff --git a/api/src/test/java/io/cloudevents/v03/CloudEventJacksonTest.java b/api/src/test/java/io/cloudevents/v03/CloudEventJacksonTest.java deleted file mode 100644 index a315326d..00000000 --- a/api/src/test/java/io/cloudevents/v03/CloudEventJacksonTest.java +++ /dev/null @@ -1,283 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.InputStream; -import java.net.URI; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import com.fasterxml.jackson.core.type.TypeReference; - -import io.cloudevents.CloudEvent; -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.json.Json; -import io.cloudevents.json.types.Much; - -/** - * - * @author fabiojose - * - */ -public class CloudEventJacksonTest { - - private static InputStream resourceOf(String name) { - return Thread.currentThread().getContextClassLoader().getResourceAsStream(name); - } - - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void should_encode_right_with_minimal_attrs() { - // setup - CloudEvent ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .build(); - - // act - String json = Json.encode(ce); - - // assert - assertTrue(json.contains("x10")); - assertTrue(json.contains("/source")); - assertTrue(json.contains("event-type")); - assertTrue(json.contains("0.3")); - - assertFalse(json.contains("time")); - assertFalse(json.contains("schemaurl")); - assertFalse(json.contains("contenttype")); - assertFalse(json.contains("data")); - } - - @Test - public void should_have_optional_attrs() { - // setup - CloudEvent ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withSchemaurl(URI.create("/schema")) - .withDatacontenttype("text/plain") - .withDatacontentencoding("base64") - .withSubject("subject0") - .withData("my-data") - .build(); - - // act - String json = Json.encode(ce); - - // assert - assertTrue(json.contains("/schema")); - assertTrue(json.contains("text/plain")); - assertTrue(json.contains("my-data")); - assertTrue(json.contains("\"base64\"")); - assertTrue(json.contains("subject0")); - - assertTrue(json.contains("\"schemaurl\"")); - assertTrue(json.contains("datacontenttype")); - assertTrue(json.contains("datacontentencoding")); - assertTrue(json.contains("\"subject\"")); - } - - @Test - public void should_serialize_trace_extension() { - // setup - String expected = "\"distributedTracing\":{\"traceparent\":\"0\",\"tracestate\":\"congo=4\"}"; - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat tracing = new DistributedTracingExtension.Format(dt); - - CloudEvent ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withSchemaurl(URI.create("/schema")) - .withDatacontenttype("text/plain") - .withData("my-data") - .withExtension(tracing) - .build(); - - // act - String actual = Json.encode(ce); - - // assert - assertTrue(actual.contains(expected)); - } - - @Test - public void should_not_serialize_attributes_element() { - // setup - CloudEvent ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withSchemaurl(URI.create("/schema")) - .withDatacontenttype("text/plain") - .withSubject("subject0") - .withData("my-data") - .build(); - - // act - String actual = Json.encode(ce); - - // assert - assertFalse(actual.contains("\"attributes\"")); - } - - @Test - public void should_have_type() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_new.json"), CloudEventImpl.class); - - // assert - assertEquals("aws.s3.object.created", ce.getAttributes().getType()); - } - - @Test - public void should_have_id() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_new.json"), CloudEventImpl.class); - - // assert - assertEquals("C234-1234-1234", ce.getAttributes().getId()); - } - - //should have time - @Test - public void should_have_time() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_new.json"), CloudEventImpl.class); - - // assert - assertTrue(ce.getAttributes().getTime().isPresent()); - } - - @Test - public void should_have_source() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_new.json"), CloudEventImpl.class); - - // assert - assertEquals(URI.create("https://serverless.com"), ce.getAttributes().getSource()); - } - - @Test - public void should_have_datacontenttype() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_new.json"), CloudEventImpl.class); - - // assert - assertTrue(ce.getAttributes().getDatacontenttype().isPresent()); - assertEquals("application/json", ce.getAttributes().getDatacontenttype().get()); - } - - @Test - public void should_have_datacontentencoding() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_base64.json"), CloudEventImpl.class); - - // assert - assertTrue(ce.getAttributes().getDatacontentencoding().isPresent()); - assertEquals("base64", ce.getAttributes().getDatacontentencoding().get()); - } - - @Test - public void should_have_specversion() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_new.json"), CloudEventImpl.class); - - // assert - assertEquals("0.3", ce.getAttributes().getSpecVersion()); - } - - @Test - public void should_throw_when_absent() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'id' must not be blank"); - - // act - Json.fromInputStream(resourceOf("03_absent.json"), CloudEventImpl.class); - } - - @Test - public void should_have_tracing_extension() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_extension.json"), CloudEventImpl.class); - - // assert - assertNotNull(ce.getExtensions() - .get(DistributedTracingExtension.Format.IN_MEMORY_KEY)); - } - - @Test - public void should_have_custom_extension() { - // setup - String extensionKey = "my-extension"; - String expected = "extension-value"; - - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("03_extension.json"), CloudEventImpl.class); - - // assert - assertEquals(expected, ce.getExtensions() - .get(extensionKey)); - } - - @Test - public void should_have_custom_data() { - // setup - Much expected = new Much(); - expected.setWow("kinda"); - - String json = "{\"type\":\"aws.s3.object.created\",\"id\":\"C234-1234-1234\",\"time\":\"2019-08-19T19:35:00.000Z\",\"source\":\"https://serverless.com\",\"datacontenttype\":\"application/json\",\"specversion\":\"0.3\",\"data\":{\"wow\":\"kinda\"}}"; - - // act - CloudEvent ce = - Json.decodeValue(json, new TypeReference>() {}); - - // assert - assertTrue(ce.getData().isPresent()); - assertEquals(expected.getWow(), ce.getData().get().getWow()); - } - -} diff --git a/api/src/test/java/io/cloudevents/v03/http/AttributeMapperTest.java b/api/src/test/java/io/cloudevents/v03/http/AttributeMapperTest.java deleted file mode 100644 index b45a41e5..00000000 --- a/api/src/test/java/io/cloudevents/v03/http/AttributeMapperTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03.http; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import io.cloudevents.v03.http.AttributeMapper; - -/** - * - * @author fabiojose - * - */ -public class AttributeMapperTest { - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void error_when_headers_map_isnull() { - // setup - expectedEx.expect(NullPointerException.class); - - // act - AttributeMapper.map(null); - } - - @Test - public void should_not_map_null_value() { - // setup - Map headers = new HashMap<>(); - headers.put("ce-type", null); - - String expected = "type"; - - // act - Map attributes = - AttributeMapper.map(headers); - - // assert - assertFalse(attributes.containsKey(expected)); - } - - @Test - public void should_ok_when_no_content_type() { - // setup - Map headers = new HashMap<>(); - headers.put("ce-specversion", "0.3"); - - // act - Map attributes = - AttributeMapper.map(headers); - - // assert - assertFalse(attributes.isEmpty()); - } - - @Test - public void should_map_cespecversion_to_specversion() { - // setup - Map headers = new HashMap<>(); - headers.put("ce-specversion", "0.3"); - headers.put("Content-Type", "application/json"); - - String expected = "specversion"; - - // act - Map attributes = - AttributeMapper.map(headers); - - // assert - assertNotNull(attributes.get(expected)); - } - - @Test - public void should_all_without_prefix_ce() { - // setup - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "0.3"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-schemaurl", "http://my.br"); - myHeaders.put("Content-Type", "application/json"); - - Map actual = AttributeMapper.map(myHeaders); - - actual.keySet() - .forEach((attribute) -> { - assertFalse(attribute.startsWith("ce-")); - }); - } -} diff --git a/api/src/test/java/io/cloudevents/v03/http/ExtensionMapperTest.java b/api/src/test/java/io/cloudevents/v03/http/ExtensionMapperTest.java deleted file mode 100644 index 6b2e1132..00000000 --- a/api/src/test/java/io/cloudevents/v03/http/ExtensionMapperTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import io.cloudevents.v03.http.ExtensionMapper; - -/** - * - * @author fabiojose - * - */ -public class ExtensionMapperTest { - - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void error_when_headers_map_isnull() { - // setup - expectedEx.expect(NullPointerException.class); - - // act - ExtensionMapper.map(null); - } - - @Test - public void should_not_map_null_values() { - //setuṕ - String expected = "nullexp"; - - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "0.3"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-schemaurl", "http://my.br"); - myHeaders.put("my-ext", "myextension"); - myHeaders.put("traceparent", "0"); - myHeaders.put("tracestate", "congo=4"); - myHeaders.put("Content-Type", "application/json"); - myHeaders.put(expected, null); - - // act - Map actual = ExtensionMapper.map(myHeaders); - - - // assert - assertFalse(actual.containsKey(expected)); - } - - @Test - public void should_return_just_potential_extensions() { - // setup - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "0.3"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-schemaurl", "http://my.br"); - myHeaders.put("my-ext", "myextension"); - myHeaders.put("traceparent", "0"); - myHeaders.put("tracestate", "congo=4"); - myHeaders.put("Content-Type", "application/json"); - - // act - Map actual = ExtensionMapper.map(myHeaders); - - // asset - assertFalse(actual.isEmpty()); - assertEquals(3, actual.keySet().size()); - actual.keySet() - .forEach(header -> { - assertFalse(header.startsWith("ce-")); - }); - - assertEquals("0", actual.get("traceparent")); - assertEquals("congo=4", actual.get("tracestate")); - assertEquals("myextension", actual.get("my-ext")); - } -} diff --git a/api/src/test/java/io/cloudevents/v03/http/HTTPBinaryMarshallerTest.java b/api/src/test/java/io/cloudevents/v03/http/HTTPBinaryMarshallerTest.java deleted file mode 100644 index f35a1343..00000000 --- a/api/src/test/java/io/cloudevents/v03/http/HTTPBinaryMarshallerTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.net.URI; - -import org.junit.Test; - -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.format.Wire; -import io.cloudevents.json.types.Much; -import io.cloudevents.v03.CloudEventBuilder; -import io.cloudevents.v03.CloudEventImpl; -/** - * - * @author fabiojose - * - */ -public class HTTPBinaryMarshallerTest { - @Test - public void should_marshal_data_as_json() { - // setup - String expected = "{\"wow\":\"yes!\"}"; - Much ceData = new Much(); - ceData.setWow("yes!"); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDatacontenttype("application/json") - .withSubject("subject") - .withData(ceData) - .build(); - - // act - Wire actual = - Marshallers. - binary() - .withEvent(() -> ce) - .marshal(); - - // assert - assertTrue(actual.getPayload().isPresent()); - assertEquals(expected, actual.getPayload().get()); - } - - @Test - public void should_marshal_attributes_as_headers() { - // setup - Much ceData = new Much(); - ceData.setWow("yes!"); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDatacontenttype("application/json") - .withSubject("subject") - .withData(ceData) - .build(); - - // act - Wire actual = - Marshallers. - binary() - .withEvent(() -> ce) - .marshal(); - - // assert - assertFalse(actual.getHeaders().isEmpty()); - assertEquals(ce.getAttributes().getId(), actual.getHeaders().get("ce-id")); - assertEquals(ce.getAttributes().getSource(), URI.create(actual.getHeaders().get("ce-source"))); - assertEquals(ce.getAttributes().getType(), actual.getHeaders().get("ce-type")); - assertEquals(ce.getAttributes().getSubject().get(), actual.getHeaders().get("ce-subject")); - assertEquals(ce.getAttributes().getDatacontenttype().get(), actual.getHeaders().get("Content-Type")); - } - - - @Test - public void should_marshal_the_tracing_extension_as_header() { - // setup - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat tracing = new DistributedTracingExtension.Format(dt); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withExtension(tracing) - .build(); - - // act - Wire actual = - Marshallers. - binary() - .withEvent(() -> ce) - .marshal(); - - assertFalse(actual.getHeaders().isEmpty()); - assertNotNull(actual.getHeaders().get(DistributedTracingExtension - .Format.TRACE_PARENT_KEY)); - assertNotNull(actual.getHeaders().get(DistributedTracingExtension - .Format.TRACE_STATE_KEY)); - } -} diff --git a/api/src/test/java/io/cloudevents/v03/http/HTTPBinaryUnmarshallerTest.java b/api/src/test/java/io/cloudevents/v03/http/HTTPBinaryUnmarshallerTest.java deleted file mode 100644 index 32d1bd7b..00000000 --- a/api/src/test/java/io/cloudevents/v03/http/HTTPBinaryUnmarshallerTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; - -import io.cloudevents.CloudEvent; -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.json.types.Much; -import io.cloudevents.v03.AttributesImpl; - -/** - * - * @author fabiojose - * - */ -public class HTTPBinaryUnmarshallerTest { - @Test - public void should_unmarshal_headers_and_json_payload() { - // setup - Much expected = new Much(); - expected.setWow("yes!"); - - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "0.2"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-schemaurl", "http://my.br"); - myHeaders.put("ce-subject", "subject"); - myHeaders.put("Content-Type", "application/json"); - - String payload = "{\"wow\":\"yes!\"}"; - - // act - CloudEvent actual = - Unmarshallers.binary(Much.class) - .withHeaders(() -> myHeaders) - .withPayload(() -> payload) - .unmarshal(); - - // assert - assertEquals("0x11", actual.getAttributes().getId()); - assertEquals(URI.create("/source"), actual.getAttributes().getSource()); - assertEquals("0.3", actual.getAttributes().getSpecVersion()); - assertEquals("br.my", actual.getAttributes().getType()); - assertTrue(actual.getAttributes().getTime().isPresent()); - assertTrue(actual.getAttributes().getSchemaurl().isPresent()); - assertEquals(URI.create("http://my.br"), actual.getAttributes().getSchemaurl().get()); - assertTrue(actual.getAttributes().getDatacontenttype().isPresent()); - assertEquals("application/json", actual.getAttributes().getDatacontenttype().get()); - assertTrue(actual.getData().isPresent()); - assertEquals(expected, actual.getData().get()); - assertTrue(actual.getAttributes().getSubject().isPresent()); - assertEquals("subject", actual.getAttributes().getSubject().get()); - } - - @Test - public void should_unmarshal_tracing_extension_from_header() { - // setup - Much expected = new Much(); - expected.setWow("yes!"); - - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "0.2"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-schemaurl", "http://my.br"); - myHeaders.put("Content-Type", "application/json"); - - myHeaders.put("traceparent", "0x200"); - myHeaders.put("tracestate", "congo=9"); - - String payload = "{\"wow\":\"yes!\"}"; - - // act - CloudEvent actual = - Unmarshallers.binary(Much.class) - .withHeaders(() -> myHeaders) - .withPayload(() -> payload) - .unmarshal(); - - // assert - assertNotNull(actual.getExtensions() - .get(DistributedTracingExtension.Format.IN_MEMORY_KEY)); - assertTrue(actual.getExtensions() - .get(DistributedTracingExtension.Format.IN_MEMORY_KEY) - instanceof DistributedTracingExtension); - } -} diff --git a/api/src/test/java/io/cloudevents/v03/http/HTTPStructuredMarshallerTest.java b/api/src/test/java/io/cloudevents/v03/http/HTTPStructuredMarshallerTest.java deleted file mode 100644 index ffadccfb..00000000 --- a/api/src/test/java/io/cloudevents/v03/http/HTTPStructuredMarshallerTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.net.URI; - -import org.junit.Test; - -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.format.Wire; -import io.cloudevents.json.types.Much; -import io.cloudevents.v03.CloudEventBuilder; -import io.cloudevents.v03.CloudEventImpl; - -/** - * - * @author fabiojose - * - */ -public class HTTPStructuredMarshallerTest { - @Test - public void should_marshal_all_as_json() { - // setup - String expected = "{\"data\":{\"wow\":\"yes!\"},\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"0.3\",\"type\":\"event-type\",\"datacontenttype\":\"application/json\",\"subject\":\"subject\"}"; - - Much ceData = new Much(); - ceData.setWow("yes!"); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDatacontenttype("application/json") - .withSubject("subject") - .withData(ceData) - .build(); - - // act - Wire actual = - Marshallers.structured() - .withEvent(() -> ce) - .marshal(); - - assertTrue(actual.getPayload().isPresent()); - assertEquals(expected, actual.getPayload().get()); - } - - @Test - public void should_marshal_data_as_text_and_evelope_as_json() { - // setup - String expected = "{\"data\":\"yes!\",\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"0.3\",\"type\":\"event-type\",\"datacontenttype\":\"text/plain\"}"; - String ceData = "yes!"; - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDatacontenttype("text/plain") - .withData(ceData) - .build(); - - // act - Wire actual = - Marshallers.structured() - .withEvent(() -> ce) - .marshal(); - - assertTrue(actual.getPayload().isPresent()); - assertEquals(expected, actual.getPayload().get()); - } - - @Test - public void should_headers_have_content_type() { - // setup - String expected = "application/cloudevents+json"; - String ceData = "yes!"; - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDatacontenttype("text/plain") - .withData(ceData) - .build(); - - // act - Wire actual = - Marshallers.structured() - .withEvent(() -> ce) - .marshal(); - - assertFalse(actual.getHeaders().isEmpty()); - assertTrue(actual.getHeaders().containsKey("Content-Type")); - assertEquals(expected, actual.getHeaders().get("Content-Type")); - } - - @Test - public void should_marshal_the_tracing_extension_as_header() { - // setup - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat tracing = new DistributedTracingExtension.Format(dt); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withExtension(tracing) - .build(); - - // act - Wire actual = - Marshallers.structured() - .withEvent(() -> ce) - .marshal(); - - // assert - assertFalse(actual.getHeaders().isEmpty()); - assertNotNull(actual.getHeaders().get(DistributedTracingExtension - .Format.TRACE_PARENT_KEY)); - assertNotNull(actual.getHeaders().get(DistributedTracingExtension - .Format.TRACE_STATE_KEY)); - } -} diff --git a/api/src/test/java/io/cloudevents/v03/http/HTTPStructuredUnmarshaller.java b/api/src/test/java/io/cloudevents/v03/http/HTTPStructuredUnmarshaller.java deleted file mode 100644 index b40615d1..00000000 --- a/api/src/test/java/io/cloudevents/v03/http/HTTPStructuredUnmarshaller.java +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; - -import io.cloudevents.CloudEvent; -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.json.types.Much; -import io.cloudevents.v03.AttributesImpl; -import io.cloudevents.v03.CloudEventBuilder; -import io.cloudevents.v03.CloudEventImpl; - -/** - * - * @author fabiojose - * - */ -public class HTTPStructuredUnmarshaller { - @Test - public void should_unmarshal_json_envelope_and_json_data() { - // setup - Map httpHeaders = new HashMap<>(); - httpHeaders.put("Content-Type", "application/cloudevents+json"); - - String json = "{\"data\":{\"wow\":\"yes!\"},\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"0.2\",\"type\":\"event-type\",\"datacontenttype\":\"application/json\",\"subject\":\"subject\"}"; - - Much ceData = new Much(); - ceData.setWow("yes!"); - - CloudEventImpl expected = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDatacontenttype("application/json") - .withSubject("subject") - .withData(ceData) - .build(); - - // act - CloudEvent actual = - Unmarshallers.structured(Much.class) - .withHeaders(() -> httpHeaders) - .withPayload(() -> json) - .unmarshal(); - - // assert - assertEquals(expected.getAttributes().getSpecVersion(), - actual.getAttributes().getSpecVersion()); - - assertEquals(expected.getAttributes().getId(), - actual.getAttributes().getId()); - - assertEquals(expected.getAttributes().getSource(), - actual.getAttributes().getSource()); - - assertEquals(expected.getAttributes().getType(), - actual.getAttributes().getType()); - - assertTrue(actual.getData().isPresent()); - assertEquals(expected.getData().get(), actual.getData().get()); - - assertTrue(actual.getAttributes().getSubject().isPresent()); - assertEquals(expected.getAttributes().getSubject().get(), - actual.getAttributes().getSubject().get()); - } - - @Test - public void should_unmarshal_json_envelope_and_text_data() { - // setup - Map httpHeaders = new HashMap<>(); - httpHeaders.put("Content-Type", "application/cloudevents+json"); - - String json = "{\"data\":\"yes!\",\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"0.3\",\"type\":\"event-type\",\"datacontenttype\":\"text/plain\"}"; - String ceData = "yes!"; - - CloudEventImpl expected = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDatacontenttype("text/plain") - .withData(ceData) - .build(); - - // act - CloudEvent actual = - Unmarshallers.structured(String.class) - .withHeaders(() -> httpHeaders) - .withPayload(() -> json) - .unmarshal(); - - // assert - assertEquals(expected.getAttributes().getSpecVersion(), - actual.getAttributes().getSpecVersion()); - - assertEquals(expected.getAttributes().getId(), - actual.getAttributes().getId()); - - assertEquals(expected.getAttributes().getSource(), - actual.getAttributes().getSource()); - - assertEquals(expected.getAttributes().getType(), - actual.getAttributes().getType()); - - assertTrue(actual.getData().isPresent()); - assertEquals(expected.getData().get(), actual.getData().get()); - } - - @Test - public void should_unmarshal_the_tracing_extension_from_headers() { - // setup - Map httpHeaders = new HashMap<>(); - httpHeaders.put("Content-Type", "application/cloudevents+json"); - - httpHeaders.put("traceparent", "0x200"); - httpHeaders.put("tracestate", "congo=9"); - - String json = "{\"data\":\"yes!\",\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"0.3\",\"type\":\"event-type\",\"datacontenttype\":\"text/plain\"}"; - - // act - CloudEvent actual = - Unmarshallers.structured(String.class) - .withHeaders(() -> httpHeaders) - .withPayload(() -> json) - .unmarshal(); - - // assert - assertTrue(actual.getExtensions().containsKey( - DistributedTracingExtension.Format.IN_MEMORY_KEY)); - - assertTrue(actual.getExtensions().get( - DistributedTracingExtension.Format.IN_MEMORY_KEY) - instanceof DistributedTracingExtension); - } -} diff --git a/api/src/test/java/io/cloudevents/v03/http/HeaderMapperTest.java b/api/src/test/java/io/cloudevents/v03/http/HeaderMapperTest.java deleted file mode 100644 index 95941944..00000000 --- a/api/src/test/java/io/cloudevents/v03/http/HeaderMapperTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v03.http; - -import static org.junit.Assert.assertFalse; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -/** - * - * @author fabiojose - * - */ -public class HeaderMapperTest { - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void error_when_attributes_map_isnull() { - // setup - expectedEx.expect(NullPointerException.class); - - Map extensions = new HashMap<>(); - - // act - HeaderMapper.map(null, extensions); - } - - @Test - public void error_when_extensions_map_isnull() { - // setup - expectedEx.expect(NullPointerException.class); - - Map attributes = new HashMap<>(); - - // act - HeaderMapper.map(attributes, null); - } - - @Test - public void should_not_map_null_attribute_value() { - // setup - Map attributes = new HashMap<>(); - attributes.put("type", null); - attributes.put("specversion", "0.3"); - - Map extensions = new HashMap<>(); - - // act - Map actual = HeaderMapper.map(attributes, extensions); - - //assert - assertFalse(actual.containsKey("ce-type")); - } - - @Test - public void should_not_map_null_extension_value() { - // setup - Map attributes = new HashMap<>(); - attributes.put("type", "mytype"); - attributes.put("specversion", "0.2"); - - Map extensions = new HashMap<>(); - extensions.put("null-ext", null); - extensions.put("comexampleextension1", "value"); - - // act - Map actual = HeaderMapper.map(attributes, extensions); - - //assert - assertFalse(actual.containsKey("ce-null-ext")); - } - - @Test - public void should_not_map_absent_datacontenttype() { - // setup - Map attributes = new HashMap<>(); - attributes.put("type", "mytype"); - attributes.put("specversion", "0.2"); - - Map extensions = new HashMap<>(); - extensions.put("null-ext", "null-value"); - extensions.put("comexampleextension1", "value"); - - // act - Map actual = HeaderMapper.map(attributes, extensions); - - //assert - assertFalse(actual.containsKey("Content-Type")); - } -} diff --git a/api/src/test/java/io/cloudevents/v1/AccessorTest.java b/api/src/test/java/io/cloudevents/v1/AccessorTest.java deleted file mode 100644 index 429eac9d..00000000 --- a/api/src/test/java/io/cloudevents/v1/AccessorTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.net.URI; -import java.util.Collection; - -import org.junit.Test; - -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.extensions.InMemoryFormat; -import io.cloudevents.v1.Accessor; -import io.cloudevents.v1.CloudEventBuilder; -import io.cloudevents.v1.CloudEventImpl; - -/** - * - * @author fabiojose - * - */ -public class AccessorTest { - @Test - public void should_empty_collection_when_no_extensions() { - // setup - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataschema(URI.create("/schema")) - .withDataContentType("text/plain") - .withData("my-data") - .build(); - - // act - Collection actual = Accessor.extensionsOf(ce); - - // assert - assertTrue(actual.isEmpty()); - } - - @Test - public void should_return_the_tracing_extension() { - // setup - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat expected = new DistributedTracingExtension.Format(dt); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataschema(URI.create("/schema")) - .withDataContentType("text/plain") - .withData("my-data") - .withExtension(expected) - .build(); - - // act - Collection extensions = - Accessor.extensionsOf(ce); - - // assert - assertFalse(extensions.isEmpty()); - ExtensionFormat actual = extensions.iterator().next(); - - assertEquals("0", actual.transport().get("traceparent")); - assertEquals("congo=4", actual.transport().get("tracestate")); - - assertEquals("0", - ((DistributedTracingExtension)actual.memory().getValue()).getTraceparent()); - - assertEquals("congo=4", - ((DistributedTracingExtension)actual.memory().getValue()).getTracestate()); - } - - @Test - public void should_return_the_custom_extension() { - // setup - String customExt = "comexampleextension1"; - String customVal = "my-ext-val"; - InMemoryFormat inMemory = - InMemoryFormat.of(customExt, customVal, String.class); - - ExtensionFormat expected = - ExtensionFormat.of(inMemory, customExt, customVal); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataschema(URI.create("/schema")) - .withDataContentType("text/plain") - .withData("my-data") - .withExtension(expected) - .build(); - - // act - Collection extensions = - Accessor.extensionsOf(ce); - - // assert - assertFalse(extensions.isEmpty()); - ExtensionFormat actual = extensions.iterator().next(); - - assertEquals(customVal, actual.transport().get(customExt)); - - assertEquals(String.class, actual.memory().getValueType()); - - assertEquals(customExt, actual.memory().getKey()); - - assertEquals(customVal, actual.memory().getValue()); - } -} diff --git a/api/src/test/java/io/cloudevents/v1/CloudEventBuilderTest.java b/api/src/test/java/io/cloudevents/v1/CloudEventBuilderTest.java index 683b88f9..af4b43c0 100644 --- a/api/src/test/java/io/cloudevents/v1/CloudEventBuilderTest.java +++ b/api/src/test/java/io/cloudevents/v1/CloudEventBuilderTest.java @@ -15,218 +15,24 @@ */ package io.cloudevents.v1; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.net.URI; -import java.util.Collections; - -import javax.validation.Validator; - -import io.cloudevents.validation.MockValidator; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - import io.cloudevents.CloudEvent; -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.extensions.InMemoryFormat; -import io.cloudevents.v1.AttributesImpl; -import io.cloudevents.v1.CloudEventBuilder; -import io.cloudevents.v1.CloudEventImpl; +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 { - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void error_when_null_id() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'id' must not be blank"); - - // act - CloudEventBuilder.builder() - .withSource(URI.create("/test")) - .withType("type") - .build(); - } - - @Test - public void error_when_empty_id() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'id' must not be blank"); - - // act - CloudEventBuilder.builder() - .withId("") - .withSource(URI.create("/test")) - .withType("type") - .build(); - } - - @Test - public void error_when_null_type() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'type' must not be blank"); - - // act - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/test")) - .build(); - } - - @Test - public void error_when_empty_type() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'type' must not be blank"); - - // act - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/test")) - .withType("") - .build(); - } - - @Test - public void error_when_null_source() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'source' must not be null"); - - // act - CloudEventBuilder.builder() - .withId("id") - .withType("type") - .build(); - } - - @Test - public void error_when_empty_subject() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'subject' size must be between 1 and 2147483647"); - - // act - CloudEventBuilder.builder() - .withId("id") - .withType("type") - .withSource(URI.create("/source")) - .withSubject("") - .build(); - } - - @Test - public void should_have_subject() { - // act - CloudEvent ce = - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withSubject("subject") - .build(); - - // assert - assertTrue(ce.getAttributes().getSubject().isPresent()); - assertEquals("subject", ce.getAttributes().getSubject().get()); - } + @ParameterizedTest() + @MethodSource("io.cloudevents.test.Data#v1Events") + void testCopyWithBuilder(CloudEvent event) { + assertThat(CloudEvent.buildV1(event).build()).isEqualTo(event); + } - @Test - public void should_have_dte() { - // setup - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat tracing = new DistributedTracingExtension.Format(dt); - - // act - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withExtension(tracing) - .build(); - - Object actual = ce.getExtensions() - .get(DistributedTracingExtension.Format.IN_MEMORY_KEY); - - // assert - assertNotNull(actual); - assertTrue(actual instanceof DistributedTracingExtension); - } - - @Test - public void should_have_custom_extension() { - String myExtKey = "comexampleextension1"; - String myExtVal = "value"; - - ExtensionFormat custom = ExtensionFormat - .of(InMemoryFormat.of(myExtKey, myExtKey, String.class), - myExtKey, myExtVal); - - // act - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withExtension(custom) - .build(); - - Object actual = ce.getExtensions() - .get(myExtKey); - - assertNotNull(actual); - assertTrue(actual instanceof String); - } - - @Test - public void should_build_event_using_custom_validator() { - Validator validator = new MockValidator(); - String expected = "test"; - - CloudEventImpl event = CloudEventBuilder - .builder() - .withData(expected) - .withValidator(validator) - .build(); - - assertNotNull(event); - assertEquals(expected, event.getData().get()); - } - - @Test - public void should_build_event_from_event_using_custom_validator() { - Validator validator = new MockValidator(); - String expected = "test"; - CloudEvent event = CloudEventBuilder.builder() - .withData(expected) - .withValidator(validator) - .build(); - - CloudEvent result = CloudEventBuilder - .builder(event) - .withValidator(validator) - .build(); - - assertNotNull(result); - assertEquals(expected, result.getData().get()); - } } diff --git a/api/src/test/java/io/cloudevents/v1/CloudEventJacksonTest.java b/api/src/test/java/io/cloudevents/v1/CloudEventJacksonTest.java deleted file mode 100644 index a893e20e..00000000 --- a/api/src/test/java/io/cloudevents/v1/CloudEventJacksonTest.java +++ /dev/null @@ -1,334 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1; - -import com.fasterxml.jackson.core.type.TypeReference; -import io.cloudevents.CloudEvent; -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.json.Json; -import io.cloudevents.json.types.Much; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import java.io.InputStream; -import java.net.URI; -import java.time.ZonedDateTime; -import java.util.Base64; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static org.junit.Assert.*; - -/** - * - * @author fabiojose - * - */ -public class CloudEventJacksonTest { - - private static InputStream resourceOf(String name) { - return Thread.currentThread().getContextClassLoader().getResourceAsStream(name); - } - - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void should_encode_right_with_minimal_attrs() { - // setup - CloudEvent ce = - CloudEvent.buildV1() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .build(); - - // act - String json = Json.encode(ce); - - // assert - assertTrue(json.contains("x10")); - assertTrue(json.contains("/source")); - assertTrue(json.contains("event-type")); - assertTrue(json.contains("1.0")); - - assertFalse(json.contains("time")); - assertFalse(json.contains("schemaurl")); - assertFalse(json.contains("contenttype")); - assertFalse(json.contains("data")); - } - - @Test - public void should_have_optional_attrs() { - // setup - CloudEvent ce = - CloudEvent.buildV1() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withSubject("subject0") - .withData("text/plain", URI.create("/schema"), "my-data") - .build(); - - // act - String json = Json.encode(ce); - - // assert - assertTrue(json.contains("/schema")); - assertTrue(json.contains("text/plain")); - assertTrue(json.contains("my-data")); - assertTrue(json.contains("subject0")); - - assertTrue(json.contains("\"dataschema\"")); - assertTrue(json.contains("datacontenttype")); - assertTrue(json.contains("\"subject\"")); - - Pattern pat = Pattern.compile("(\"data\")"); - Matcher mat = pat.matcher(json); - int counter = 0; - while(mat.find()) { - counter++; - } - assertEquals(1, counter); - } - - @Test - public void should_serialize_trace_extension() { - // setup - String expected = "\"distributedTracing\":{\"traceparent\":\"0\",\"tracestate\":\"congo=4\"}"; - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat tracing = new DistributedTracingExtension.Format(dt); - - CloudEvent ce = - CloudEvent.buildV1() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataschema(URI.create("/schema")) - .withDataContentType("text/plain") - .withData("my-data") - .withExtension(tracing) - .build(); - - // act - String actual = Json.encode(ce); - - // assert - assertTrue(actual.contains(expected)); - } - - @Test - public void should_not_serialize_attributes_element() { - // setup - CloudEvent ce = - CloudEvent.buildV1() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataschema(URI.create("/schema")) - .withDataContentType("text/plain") - .withSubject("subject0") - .withData("my-data") - .build(); - - // act - String actual = Json.encode(ce); - - // assert - assertFalse(actual.contains("\"attributes\"")); - } - - @Test - public void should_have_type() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_new.json"), CloudEventImpl.class); - - // assert - assertEquals("aws.s3.object.created", ce.getAttributes().getType()); - } - - @Test - public void should_have_id() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_new.json"), CloudEventImpl.class); - - // assert - assertEquals("C234-1234-1234", ce.getAttributes().getId()); - } - - //should have time - @Test - public void should_have_time() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_new.json"), CloudEventImpl.class); - - // assert - assertTrue(ce.getAttributes().getTime().isPresent()); - } - - @Test - public void should_have_source() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_new.json"), CloudEventImpl.class); - - // assert - assertEquals(URI.create("https://serverless.com"), ce.getAttributes().getSource()); - } - - @Test - public void should_have_datacontenttype() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_new.json"), CloudEventImpl.class); - - // assert - assertTrue(ce.getAttributes().getDatacontenttype().isPresent()); - assertEquals("application/json", ce.getAttributes().getDatacontenttype().get()); - } - - @Test - public void should_have_dataschema() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_new.json"), CloudEventImpl.class); - - // assert - assertTrue(ce.getAttributes().getDataschema().isPresent()); - assertEquals(URI.create("/my-schema"), ce.getAttributes().getDataschema().get()); - } - - @Test - public void should_have_specversion() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_new.json"), CloudEventImpl.class); - - // assert - assertEquals("1.0", ce.getAttributes().getSpecVersion()); - } - - @Test - public void should_throw_when_absent() { - // setup - expectedEx.expect(IllegalStateException.class); - expectedEx.expectMessage("invalid payload: 'id' must not be blank"); - - // act - Json.fromInputStream(resourceOf("1_absent.json"), CloudEventImpl.class); - } - - @Test - public void should_have_tracing_extension() { - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_extension.json"), CloudEventImpl.class); - - // assert - assertNotNull(ce.getExtensions() - .get(DistributedTracingExtension.Format.IN_MEMORY_KEY)); - } - - @Test - public void should_have_custom_extension() { - // setup - String extensionKey = "my-extension"; - String expected = "extension-value"; - - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_extension.json"), CloudEventImpl.class); - - // assert - assertEquals(expected, ce.getExtensions() - .get(extensionKey)); - } - - @Test - public void should_have_custom_data() { - // setup - Much expected = new Much(); - expected.setWow("kinda"); - - String json = "{\"type\":\"aws.s3.object.created\",\"id\":\"C234-1234-1234\",\"time\":\"2019-08-19T19:35:00.000Z\",\"source\":\"https://serverless.com\",\"datacontenttype\":\"application/json\",\"specversion\":\"1.0\",\"data\":{\"wow\":\"kinda\"}}"; - - // act - CloudEvent ce = - Json.decodeValue(json, new TypeReference>() {}); - - // assert - assertTrue(ce.getData().isPresent()); - assertEquals(expected.getWow(), ce.getData().get().getWow()); - } - - @Test - public void should_unmarshal_data_base64() { - // setup - byte[] expected = "mydata".getBytes(); - - // act - CloudEvent ce = - Json.fromInputStream(resourceOf("1_base64.json"), - new TypeReference>() {}); - - // assert - assertNotNull(ce.getDataBase64()); - assertArrayEquals(expected, ce.getDataBase64()); - } - - @Test - public void should_marshal_data_byte_array_as_data_base64() { - // setup - byte[] data = ("--mydata--" - + "\n" - + "customer=445" - + "\n" - + "invoice=5566" - + "\n" - + "---mydata---").getBytes(); - - String expected = - Base64.getEncoder().encodeToString(data); - - CloudEventImpl event = - CloudEventBuilder.builder() - .withId("0xbin") - .withSource(URI.create("/customers/445")) - .withType("customers.ordering") - .withDataContentType("text/plain") - .withDataschema(URI.create("http://schame.server.com/customer/order")) - .withSubject("orders.json") - .withTime(ZonedDateTime.now()) - .withDataBase64(data) - .build(); - - // act - String encoded = Json.encode(event); - - // assert - assertTrue(encoded.contains("\"data_base64\"")); - assertTrue(encoded.contains("\"" + expected +"\"")); - } - -} diff --git a/api/src/test/java/io/cloudevents/v1/http/AttributeMapperTest.java b/api/src/test/java/io/cloudevents/v1/http/AttributeMapperTest.java deleted file mode 100644 index 65f1a213..00000000 --- a/api/src/test/java/io/cloudevents/v1/http/AttributeMapperTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1.http; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import io.cloudevents.v1.http.AttributeMapper; - -/** - * - * @author fabiojose - * - */ -public class AttributeMapperTest { - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void error_when_headers_map_isnull() { - // setup - expectedEx.expect(NullPointerException.class); - - // act - AttributeMapper.map(null); - } - - @Test - public void should_not_map_null_value() { - // setup - Map headers = new HashMap<>(); - headers.put("ce-type", null); - - String expected = "type"; - - // act - Map attributes = - AttributeMapper.map(headers); - - // assert - assertFalse(attributes.containsKey(expected)); - } - - @Test - public void should_ok_when_no_content_type() { - // setup - Map headers = new HashMap<>(); - headers.put("ce-specversion", "1.0"); - - // act - Map attributes = - AttributeMapper.map(headers); - - // assert - assertFalse(attributes.isEmpty()); - } - - @Test - public void should_map_cespecversion_to_specversion() { - // setup - Map headers = new HashMap<>(); - headers.put("ce-specversion", "1.0"); - headers.put("Content-Type", "application/json"); - - String expected = "specversion"; - - // act - Map attributes = - AttributeMapper.map(headers); - - // assert - assertNotNull(attributes.get(expected)); - } - - @Test - public void should_all_without_prefix_ce() { - // setup - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "1.0"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-dataschema", "http://my.br"); - myHeaders.put("Content-Type", "application/json"); - - Map actual = AttributeMapper.map(myHeaders); - - actual.keySet() - .forEach((attribute) -> { - assertFalse(attribute.startsWith("ce-")); - }); - } -} diff --git a/api/src/test/java/io/cloudevents/v1/http/ExtensionMapperTest.java b/api/src/test/java/io/cloudevents/v1/http/ExtensionMapperTest.java deleted file mode 100644 index ad567d21..00000000 --- a/api/src/test/java/io/cloudevents/v1/http/ExtensionMapperTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import io.cloudevents.v1.http.ExtensionMapper; - -/** - * - * @author fabiojose - * - */ -public class ExtensionMapperTest { - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void error_when_headers_map_isnull() { - // setup - expectedEx.expect(NullPointerException.class); - - // act - ExtensionMapper.map(null); - } - - @Test - public void should_not_map_null_values() { - //setuṕ - String expected = "nullexp"; - - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "1.0"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-dataschema", "http://my.br"); - myHeaders.put("my-ext", "myextension"); - myHeaders.put("traceparent", "0"); - myHeaders.put("tracestate", "congo=4"); - myHeaders.put("Content-Type", "application/json"); - myHeaders.put(expected, null); - - // act - Map actual = ExtensionMapper.map(myHeaders); - - - // assert - assertFalse(actual.containsKey(expected)); - } - - @Test - public void should_return_just_potential_extensions() { - // setup - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "1.0"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-dataschema", "http://my.br"); - myHeaders.put("my-ext", "myextension"); - myHeaders.put("traceparent", "0"); - myHeaders.put("tracestate", "congo=4"); - myHeaders.put("Content-Type", "application/json"); - - // act - Map actual = ExtensionMapper.map(myHeaders); - - // asset - assertFalse(actual.isEmpty()); - assertEquals(3, actual.keySet().size()); - actual.keySet() - .forEach(header -> { - assertFalse(header.startsWith("ce-")); - }); - - assertEquals("0", actual.get("traceparent")); - assertEquals("congo=4", actual.get("tracestate")); - assertEquals("myextension", actual.get("my-ext")); - } -} diff --git a/api/src/test/java/io/cloudevents/v1/http/HTTPBinaryMarshallerTest.java b/api/src/test/java/io/cloudevents/v1/http/HTTPBinaryMarshallerTest.java deleted file mode 100644 index 9a921b91..00000000 --- a/api/src/test/java/io/cloudevents/v1/http/HTTPBinaryMarshallerTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.net.URI; -import java.util.Base64; - -import org.junit.Test; - -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.format.Wire; -import io.cloudevents.json.types.Much; -import io.cloudevents.v1.CloudEventBuilder; -import io.cloudevents.v1.CloudEventImpl; -import io.cloudevents.v1.http.Marshallers; - -/** - * - * @author fabiojose - * - */ -public class HTTPBinaryMarshallerTest { - @Test - public void should_marshal_data_as_json() { - // setup - String expected = "{\"wow\":\"yes!\"}"; - Much ceData = new Much(); - ceData.setWow("yes!"); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataContentType("application/json") - .withSubject("subject") - .withData(ceData) - .build(); - - // act - Wire actual = - Marshallers. - binary() - .withEvent(() -> ce) - .marshal(); - - // assert - assertTrue(actual.getPayload().isPresent()); - assertEquals(expected, actual.getPayload().get()); - } - - @Test - public void should_marshal_byte_array_as_base64() { - // setup - - byte[] data = "my-data".getBytes(); - String expected = "\"" + - Base64.getEncoder().encodeToString(data) + "\""; - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataContentType("text/plain") - .withSubject("subject") - .withData(data) - .build(); - - // act - Wire actual = - Marshallers. - binary() - .withEvent(() -> ce) - .marshal(); - - // assert - assertTrue(actual.getPayload().isPresent()); - assertEquals(expected, actual.getPayload().get()); - } - - @Test - public void should_marshal_attributes_as_headers() { - // setup - Much ceData = new Much(); - ceData.setWow("yes!"); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataContentType("application/json") - .withSubject("subject") - .withData(ceData) - .build(); - - // act - Wire actual = - Marshallers. - binary() - .withEvent(() -> ce) - .marshal(); - - // assert - assertFalse(actual.getHeaders().isEmpty()); - assertEquals(ce.getAttributes().getId(), actual.getHeaders().get("ce-id")); - assertEquals(ce.getAttributes().getSource(), URI.create(actual.getHeaders().get("ce-source"))); - assertEquals(ce.getAttributes().getType(), actual.getHeaders().get("ce-type")); - assertEquals(ce.getAttributes().getSubject().get(), actual.getHeaders().get("ce-subject")); - assertEquals(ce.getAttributes().getDatacontenttype().get(), actual.getHeaders().get("Content-Type")); - } - - - @Test - public void should_marshal_the_tracing_extension_as_header() { - // setup - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat tracing = new DistributedTracingExtension.Format(dt); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withExtension(tracing) - .build(); - - // act - Wire actual = - Marshallers. - binary() - .withEvent(() -> ce) - .marshal(); - - assertFalse(actual.getHeaders().isEmpty()); - assertNotNull(actual.getHeaders().get(DistributedTracingExtension - .Format.TRACE_PARENT_KEY)); - assertNotNull(actual.getHeaders().get(DistributedTracingExtension - .Format.TRACE_STATE_KEY)); - } -} diff --git a/api/src/test/java/io/cloudevents/v1/http/HTTPBinaryUnmarshallerTest.java b/api/src/test/java/io/cloudevents/v1/http/HTTPBinaryUnmarshallerTest.java deleted file mode 100644 index fb0a27d1..00000000 --- a/api/src/test/java/io/cloudevents/v1/http/HTTPBinaryUnmarshallerTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1.http; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import io.cloudevents.CloudEvent; -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.json.types.Much; -import io.cloudevents.v1.AttributesImpl; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * - * @author fabiojose - * - */ -public class HTTPBinaryUnmarshallerTest { - @Test - public void should_unmarshal_headers_and_json_payload() { - // setup - Much expected = new Much(); - expected.setWow("yes!"); - - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "1.0"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-dataschema", "http://my.br"); - myHeaders.put("ce-subject", "subject"); - myHeaders.put("Content-Type", "application/json"); - - String payload = "{\"wow\":\"yes!\"}"; - - // act - CloudEvent actual = - Unmarshallers.binary(Much.class) - .withHeaders(() -> myHeaders) - .withPayload(() -> payload) - .unmarshal(); - - // assert - assertEquals("0x11", actual.getAttributes().getId()); - assertEquals(URI.create("/source"), actual.getAttributes().getSource()); - assertEquals("1.0", actual.getAttributes().getSpecVersion()); - assertEquals("br.my", actual.getAttributes().getType()); - assertTrue(actual.getAttributes().getTime().isPresent()); - assertTrue(actual.getAttributes().getDataschema().isPresent()); - assertEquals(URI.create("http://my.br"), actual.getAttributes().getDataschema().get()); - assertTrue(actual.getAttributes().getDatacontenttype().isPresent()); - assertEquals("application/json", actual.getAttributes().getDatacontenttype().get()); - assertTrue(actual.getData().isPresent()); - assertEquals(expected, actual.getData().get()); - assertTrue(actual.getAttributes().getSubject().isPresent()); - assertEquals("subject", actual.getAttributes().getSubject().get()); - } - - @Test - public void should_unmarshal_tracing_extension_from_header() { - // setup - Much expected = new Much(); - expected.setWow("yes!"); - - Map myHeaders = new HashMap<>(); - myHeaders.put("ce-id", "0x11"); - myHeaders.put("ce-source", "/source"); - myHeaders.put("ce-specversion", "1.0"); - myHeaders.put("ce-type", "br.my"); - myHeaders.put("ce-time", "2019-09-16T20:49:00Z"); - myHeaders.put("ce-schemaurl", "http://my.br"); - myHeaders.put("Content-Type", "application/json"); - - myHeaders.put("traceparent", "0x200"); - myHeaders.put("tracestate", "congo=9"); - - String payload = "{\"wow\":\"yes!\"}"; - - // act - CloudEvent actual = - Unmarshallers.binary(Much.class) - .withHeaders(() -> myHeaders) - .withPayload(() -> payload) - .unmarshal(); - - // assert - assertNotNull(actual.getExtensions() - .get(DistributedTracingExtension.Format.IN_MEMORY_KEY)); - assertTrue(actual.getExtensions() - .get(DistributedTracingExtension.Format.IN_MEMORY_KEY) - instanceof DistributedTracingExtension); - } -} diff --git a/api/src/test/java/io/cloudevents/v1/http/HTTPStructuredMarshallerTest.java b/api/src/test/java/io/cloudevents/v1/http/HTTPStructuredMarshallerTest.java deleted file mode 100644 index 39c8c6bc..00000000 --- a/api/src/test/java/io/cloudevents/v1/http/HTTPStructuredMarshallerTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.net.URI; - -import org.junit.Test; - -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; -import io.cloudevents.format.Wire; -import io.cloudevents.json.types.Much; -import io.cloudevents.v1.CloudEventBuilder; -import io.cloudevents.v1.CloudEventImpl; -import io.cloudevents.v1.http.Marshallers; - -/** - * - * @author fabiojose - * - */ -public class HTTPStructuredMarshallerTest { - - @Test - public void should_headers_have_content_type() { - // setup - String expected = "application/cloudevents+json"; - String ceData = "yes!"; - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataContentType("text/plain") - .withData(ceData) - .build(); - - // act - Wire actual = - Marshallers.structured() - .withEvent(() -> ce) - .marshal(); - - assertFalse(actual.getHeaders().isEmpty()); - assertTrue(actual.getHeaders().containsKey("Content-Type")); - assertEquals(expected, actual.getHeaders().get("Content-Type")); - } - - @Test - public void should_marshal_the_tracing_extension_as_header() { - // setup - final DistributedTracingExtension dt = new DistributedTracingExtension(); - dt.setTraceparent("0"); - dt.setTracestate("congo=4"); - - final ExtensionFormat tracing = new DistributedTracingExtension.Format(dt); - - CloudEventImpl ce = - CloudEventBuilder.builder() - .withId("id") - .withSource(URI.create("/source")) - .withType("type") - .withExtension(tracing) - .build(); - - // act - Wire actual = - Marshallers.structured() - .withEvent(() -> ce) - .marshal(); - - // assert - assertFalse(actual.getHeaders().isEmpty()); - assertNotNull(actual.getHeaders().get(DistributedTracingExtension - .Format.TRACE_PARENT_KEY)); - assertNotNull(actual.getHeaders().get(DistributedTracingExtension - .Format.TRACE_STATE_KEY)); - } -} diff --git a/api/src/test/java/io/cloudevents/v1/http/HTTPStructuredUnmarshallerTest.java b/api/src/test/java/io/cloudevents/v1/http/HTTPStructuredUnmarshallerTest.java deleted file mode 100644 index c80bda99..00000000 --- a/api/src/test/java/io/cloudevents/v1/http/HTTPStructuredUnmarshallerTest.java +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1.http; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; - -import java.net.URI; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; - -import io.cloudevents.CloudEvent; -import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.json.types.Much; -import io.cloudevents.v1.AttributesImpl; -import io.cloudevents.v1.CloudEventBuilder; -import io.cloudevents.v1.CloudEventImpl; - -/** - * - * @author fabiojose - * - */ -public class HTTPStructuredUnmarshallerTest { - @Test - public void should_unmarshal_json_envelope_and_json_data() { - // setup - Map httpHeaders = new HashMap<>(); - httpHeaders.put("Content-Type", "application/cloudevents+json"); - - String json = "{\"data\":{\"wow\":\"yes!\"},\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"1.0\",\"type\":\"event-type\",\"datacontenttype\":\"application/json\",\"subject\":\"subject\"}"; - - Much ceData = new Much(); - ceData.setWow("yes!"); - - CloudEventImpl expected = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataContentType("application/json") - .withSubject("subject") - .withData(ceData) - .build(); - - // act - CloudEvent actual = - Unmarshallers.structured(Much.class) - .withHeaders(() -> httpHeaders) - .withPayload(() -> json) - .unmarshal(); - - // assert - assertEquals(expected.getAttributes().getSpecversion(), - actual.getAttributes().getSpecVersion()); - - assertEquals(expected.getAttributes().getId(), - actual.getAttributes().getId()); - - assertEquals(expected.getAttributes().getSource(), - actual.getAttributes().getSource()); - - assertEquals(expected.getAttributes().getType(), - actual.getAttributes().getType()); - - assertTrue(actual.getData().isPresent()); - assertEquals(expected.getData().get(), actual.getData().get()); - - assertTrue(actual.getAttributes().getSubject().isPresent()); - assertEquals(expected.getAttributes().getSubject().get(), - actual.getAttributes().getSubject().get()); - } - - @Test - public void should_unmarshal_json_envelope_and_text_data() { - // setup - Map httpHeaders = new HashMap<>(); - httpHeaders.put("Content-Type", "application/cloudevents+json"); - - String json = "{\"data\":\"yes!\",\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"1.0\",\"type\":\"event-type\",\"datacontenttype\":\"text/plain\"}"; - String ceData = "yes!"; - - CloudEventImpl expected = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataContentType("text/plain") - .withData(ceData) - .build(); - - // act - CloudEvent actual = - Unmarshallers.structured(String.class) - .withHeaders(() -> httpHeaders) - .withPayload(() -> json) - .unmarshal(); - - // assert - assertEquals(expected.getAttributes().getSpecversion(), - actual.getAttributes().getSpecVersion()); - - assertEquals(expected.getAttributes().getId(), - actual.getAttributes().getId()); - - assertEquals(expected.getAttributes().getSource(), - actual.getAttributes().getSource()); - - assertEquals(expected.getAttributes().getType(), - actual.getAttributes().getType()); - - assertTrue(actual.getData().isPresent()); - assertEquals(expected.getData().get(), actual.getData().get()); - } - - @Test - public void should_unmarshal_json_envelope_and_text_data_base64() { - // setup - Map httpHeaders = new HashMap<>(); - httpHeaders.put("Content-Type", "application/cloudevents+json"); - - String ceData = "yes!"; - byte[] base64Data = Base64.getEncoder().encode(ceData.getBytes()); - String json = "{\"data_base64\":\"" + new String(base64Data) + "\",\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"1.0\",\"type\":\"event-type\",\"datacontenttype\":\"text/plain\"}"; - - CloudEventImpl expected = - CloudEventBuilder.builder() - .withId("x10") - .withSource(URI.create("/source")) - .withType("event-type") - .withDataContentType("text/plain") - .withDataBase64(ceData.getBytes()) - .build(); - - // act - CloudEvent actual = - Unmarshallers.structured(String.class) - .withHeaders(() -> httpHeaders) - .withPayload(() -> json) - .unmarshal(); - - // assert - assertEquals(expected.getAttributes().getSpecversion(), - actual.getAttributes().getSpecVersion()); - - assertEquals(expected.getAttributes().getId(), - actual.getAttributes().getId()); - - assertEquals(expected.getAttributes().getSource(), - actual.getAttributes().getSource()); - - assertEquals(expected.getAttributes().getType(), - actual.getAttributes().getType()); - - assertFalse(actual.getData().isPresent()); - assertNotNull(actual.getDataBase64()); - assertEquals(new String(expected.getDataBase64()), new String(actual.getDataBase64())); - } - - @Test - public void should_unmarshal_the_tracing_extension_from_headers() { - // setup - Map httpHeaders = new HashMap<>(); - httpHeaders.put("Content-Type", "application/cloudevents+json"); - - httpHeaders.put("traceparent", "0x200"); - httpHeaders.put("tracestate", "congo=9"); - - String json = "{\"data\":\"yes!\",\"id\":\"x10\",\"source\":\"/source\",\"specversion\":\"1.0\",\"type\":\"event-type\",\"datacontenttype\":\"text/plain\"}"; - - // act - CloudEvent actual = - Unmarshallers.structured(String.class) - .withHeaders(() -> httpHeaders) - .withPayload(() -> json) - .unmarshal(); - - // assert - assertTrue(actual.getExtensions().containsKey( - DistributedTracingExtension.Format.IN_MEMORY_KEY)); - - assertTrue(actual.getExtensions().get( - DistributedTracingExtension.Format.IN_MEMORY_KEY) - instanceof DistributedTracingExtension); - } -} diff --git a/api/src/test/java/io/cloudevents/v1/http/HeaderMapperTest.java b/api/src/test/java/io/cloudevents/v1/http/HeaderMapperTest.java deleted file mode 100644 index 30761604..00000000 --- a/api/src/test/java/io/cloudevents/v1/http/HeaderMapperTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/** - * Copyright 2019 The CloudEvents Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.cloudevents.v1.http; - -import static org.junit.Assert.assertFalse; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import io.cloudevents.v1.http.HeaderMapper; - -/** - * - * @author fabiojose - * - */ -public class HeaderMapperTest { - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - - @Test - public void error_when_attributes_map_isnull() { - // setup - expectedEx.expect(NullPointerException.class); - - Map extensions = new HashMap<>(); - - // act - HeaderMapper.map(null, extensions); - } - - @Test - public void error_when_extensions_map_isnull() { - // setup - expectedEx.expect(NullPointerException.class); - - Map attributes = new HashMap<>(); - - // act - HeaderMapper.map(attributes, null); - } - - @Test - public void should_not_map_null_attribute_value() { - // setup - Map attributes = new HashMap<>(); - attributes.put("type", null); - attributes.put("specversion", "1.0"); - - Map extensions = new HashMap<>(); - - // act - Map actual = HeaderMapper.map(attributes, extensions); - - //assert - assertFalse(actual.containsKey("ce-type")); - } - - @Test - public void should_not_map_null_extension_value() { - // setup - Map attributes = new HashMap<>(); - attributes.put("type", "mytype"); - attributes.put("specversion", "1.0"); - - Map extensions = new HashMap<>(); - extensions.put("null-ext", null); - extensions.put("comexampleextension1", "value"); - - // act - Map actual = HeaderMapper.map(attributes, extensions); - - //assert - assertFalse(actual.containsKey("ce-null-ext")); - } - - @Test - public void should_not_map_absent_datacontenttype() { - // setup - Map attributes = new HashMap<>(); - attributes.put("type", "mytype"); - attributes.put("specversion", "1.0"); - - Map extensions = new HashMap<>(); - extensions.put("null-ext", "null-value"); - extensions.put("comexampleextension1", "value"); - - // act - Map actual = HeaderMapper.map(attributes, extensions); - - //assert - assertFalse(actual.containsKey("Content-Type")); - } -} diff --git a/api/src/test/java/io/cloudevents/validation/MockValidator.java b/api/src/test/java/io/cloudevents/validation/MockValidator.java deleted file mode 100644 index d50d9dd9..00000000 --- a/api/src/test/java/io/cloudevents/validation/MockValidator.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.cloudevents.validation; - -import java.util.HashSet; -import java.util.Set; - -import javax.validation.ConstraintViolation; -import javax.validation.Validator; -import javax.validation.executable.ExecutableValidator; -import javax.validation.metadata.BeanDescriptor; - -public class MockValidator implements Validator { - - @Override - public Set> validate(T object, Class... groups) { - return new HashSet<>(); - } - - @Override - public Set> validateProperty(T object, String propertyName, Class... groups) { - return null; - } - - @Override - public Set> validateValue(Class beanType, String propertyName, Object value, Class... groups) { - return null; - } - - @Override - public BeanDescriptor getConstraintsForClass(Class clazz) { - return null; - } - - @Override - public T unwrap(Class type) { - return null; - } - - @Override - public ExecutableValidator forExecutables() { - return null; - } -} \ No newline at end of file diff --git a/kafka/src/main/java/io/cloudevents/v1/kafka/Unmarshallers.java b/kafka/src/main/java/io/cloudevents/v1/kafka/Unmarshallers.java index 00f3647f..66710d0f 100644 --- a/kafka/src/main/java/io/cloudevents/v1/kafka/Unmarshallers.java +++ b/kafka/src/main/java/io/cloudevents/v1/kafka/Unmarshallers.java @@ -1,19 +1,8 @@ package io.cloudevents.v1.kafka; -import static io.cloudevents.extensions.DistributedTracingExtension.Format.IN_MEMORY_KEY; -import static io.cloudevents.extensions.DistributedTracingExtension.Format.TRACE_PARENT_KEY; -import static io.cloudevents.extensions.DistributedTracingExtension.Format.TRACE_STATE_KEY; -import static java.util.Optional.ofNullable; - -import java.util.Map; -import java.util.Optional; -import java.util.AbstractMap.SimpleEntry; -import java.util.Map.Entry; -import java.util.stream.Collectors; - import io.cloudevents.extensions.DistributedTracingExtension; -import io.cloudevents.extensions.ExtensionFormat; import io.cloudevents.extensions.DistributedTracingExtension.Format; +import io.cloudevents.extensions.ExtensionFormat; import io.cloudevents.format.BinaryUnmarshaller; import io.cloudevents.format.StructuredUnmarshaller; import io.cloudevents.format.builder.HeadersStep; @@ -21,30 +10,37 @@ import io.cloudevents.json.Json; import io.cloudevents.v1.AttributesImpl; import io.cloudevents.v1.CloudEventBuilder; import io.cloudevents.v1.CloudEventImpl; -import io.cloudevents.v1.kafka.AttributeMapper; -import io.cloudevents.v1.kafka.ExtensionMapper; + +import java.util.AbstractMap.SimpleEntry; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.stream.Collectors; + +import static io.cloudevents.extensions.DistributedTracingExtension.Format.*; +import static java.util.Optional.ofNullable; /** - * + * * @author fabiojose * @version 1.0 */ public class Unmarshallers { private Unmarshallers() {} - + /** * Builds a Binary Content Mode unmarshaller to unmarshal JSON as CloudEvents data * for Kafka Transport Binding - * + * * @param The 'data' type * @param type The type reference to use for 'data' unmarshal * @return A step to supply the headers, payload and to unmarshal * @see BinaryUnmarshaller */ - public static HeadersStep + public static HeadersStep binary(Class type) { - - return + + return BinaryUnmarshaller. builder() .map(AttributeMapper::map) @@ -57,66 +53,66 @@ public class Unmarshallers { .builder(CloudEventBuilder.builder()::build); } - + /** * Builds a Structured Content Mode unmarshaller to unmarshal JSON as CloudEvents data * for Kafka Transport Binding - * + * * @param The 'data' type * @param typeOfData The type reference to use for 'data' unmarshal * @return A step to supply the headers, payload and to unmarshal * @see StructuredUnmarshaller */ @SuppressWarnings("unchecked") - public static HeadersStep + public static HeadersStep structured(Class typeOfData) { - + return StructuredUnmarshaller. builder() .map(ExtensionMapper::map) .map(DistributedTracingExtension::unmarshall) .next() - .map((payload, extensions) -> { + .map((payload, extensions) -> { CloudEventImpl event = Json.> binaryDecodeValue(payload, CloudEventImpl.class, typeOfData); - - Optional dteFormat = + + Optional dteFormat = ofNullable(event.getExtensions().get(IN_MEMORY_KEY)) .filter(extension -> extension instanceof Map) .map(extension -> (Map)extension) - .map(extension -> + .map(extension -> extension.entrySet() .stream() - .filter(entry -> - null!= entry.getKey() + .filter(entry -> + null!= entry.getKey() && null!= entry.getValue()) - .map(tracing -> - new SimpleEntry<>(tracing.getKey(), + .map(tracing -> + new SimpleEntry<>(tracing.getKey(), tracing.getValue().toString())) .collect(Collectors.toMap(Entry::getKey, Entry::getValue))) .map(extension -> { - DistributedTracingExtension dte = + DistributedTracingExtension dte = new DistributedTracingExtension(); dte.setTraceparent(extension.get(TRACE_PARENT_KEY)); dte.setTracestate(extension.get(TRACE_STATE_KEY)); - + return new Format(dte); }); - - CloudEventBuilder builder = + + CloudEventBuilder builder = CloudEventBuilder.builder(event); - + extensions.get().forEach(extension -> { builder.withExtension(extension); }); - + dteFormat.ifPresent(tracing -> { builder.withExtension(tracing); }); - + return builder.build(); }); } diff --git a/kafka/src/test/java/io/cloudevents/kafka/CloudEventsKafkaHeadersTest.java b/kafka/src/test/java/io/cloudevents/kafka/CloudEventsKafkaHeadersTest.java index 811db9c3..5ccd20a3 100644 --- a/kafka/src/test/java/io/cloudevents/kafka/CloudEventsKafkaHeadersTest.java +++ b/kafka/src/test/java/io/cloudevents/kafka/CloudEventsKafkaHeadersTest.java @@ -52,4 +52,4 @@ public class CloudEventsKafkaHeadersTest { Assertions.assertEquals(expectedHeader.getValue(), values.get(expectedHeader.getKey())); } } -} \ No newline at end of file +}