Compiles!

Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>
This commit is contained in:
slinkydeveloper 2020-04-20 15:52:49 +02:00 committed by Francesco Guardiani
parent 8f1b8d2da9
commit c7b9f3dab5
39 changed files with 339 additions and 4206 deletions

View File

@ -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 <T extends BinaryMessageVisitor<V>, V> V visit(BinaryMessageVisitorFactory<T, V> visitorFactory) throws MessageVisitException, IllegalStateException {
BinaryMessageVisitor<V> visitor = visitorFactory.apply(this.attributes.getSpecVersion());
BinaryMessageVisitor<V> 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);
}
}

View File

@ -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> T fromInputStream(final InputStream inputStream,
Class<T> clazz) {
try {
return MAPPER.readValue(inputStream, clazz);
} catch (Exception e) {
throw new IllegalStateException("Failed to encode as JSON: "
+ e.getMessage());
}
}
public static <T> T fromInputStream(final InputStream inputStream,
final TypeReference<T> 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 <T> 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> T decodeValue(final String str, final Class<T> 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> T binaryDecodeValue(byte[] payload, final Class<T> 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 <T> 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> T decodeValue(final String str, final TypeReference<T> 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:
* <pre>
* String someJson = "...";
* Class<?> clazz = Much.class;
*
* Json.decodeValue(someJson, CloudEventImpl.class, clazz);
* </pre>
* @param str The JSON String to parse
* @param parametrized Actual full type
* @param parameterClasses Type parameters to apply
* @param <T> 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> 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:
* <pre>
* String someJson = "...";
* Class<?> clazz = Much.class;
*
* Json.decodeValue(someJson, CloudEventImpl.class, clazz);
* </pre>
* @param json The JSON byte array to parse
* @param parametrized Actual full type
* @param parameterClasses Type parameters to apply
* @param <T> 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> 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 <T> The 'data' type
* @param <A> The attributes type
* @param type The type of 'data'
* @return A new instance of {@link DataUnmarshaller}
*/
public static <T, A extends Attributes> DataUnmarshaller<String, T, A>
umarshaller(Class<T> type) {
return (payload, attributes) -> Json.decodeValue(payload, type);
}
/**
* Unmarshals a byte array into T type
* @param <T> The 'data' type
* @param <A> The attributes type
* @return The data objects
*/
public static <T, A extends Attributes> DataUnmarshaller<byte[], T, A>
binaryUmarshaller(Class<T> type) {
return (payload, attributes) -> Json.binaryDecodeValue(payload, type);
}
/**
* Creates a JSON Data Marshaller that produces a {@link String}
* @param <T> The 'data' type
* @param <H> The type of headers value
* @return A new instance of {@link DataMarshaller}
*/
public static <T, H> DataMarshaller<String, T, H> marshaller() {
return (data, headers) -> Json.encode(data);
}
/**
* Marshalls the 'data' value as JSON, producing a byte array
* @param <T> The 'data' type
* @param <H> 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 <T, H> byte[] binaryMarshal(T data,
Map<String, H> headers) {
return Json.binaryEncode(data);
}
private Json() {
// no-op
}
}

View File

@ -2,7 +2,7 @@ package io.cloudevents.message;
import io.cloudevents.SpecVersion;
import java.util.function.Function;
@FunctionalInterface
public interface BinaryMessageVisitorFactory<T extends BinaryMessageVisitor<V>, V> extends Function<SpecVersion, T> { }
public interface BinaryMessageVisitorFactory<T extends BinaryMessageVisitor<V>, V> {
T createBinaryMessageVisitor(SpecVersion version);
}

View File

@ -6,6 +6,14 @@ public interface Message extends StructuredMessage, BinaryMessage {
Encoding getEncoding();
default <BV extends BinaryMessageVisitor<R>, R> R visit(MessageVisitor<BV, R> visitor) throws MessageVisitException, IllegalStateException {
switch (getEncoding()) {
case BINARY: return this.visit((BinaryMessageVisitorFactory<BV, R>) visitor);
case STRUCTURED: return this.visit((StructuredMessageVisitor<R>)visitor);
default: throw Encoding.UNKNOWN_ENCODING_EXCEPTION;
}
}
default CloudEvent toEvent() throws MessageVisitException, IllegalStateException {
switch (getEncoding()) {
case BINARY: return ((BinaryMessage)this).toEvent();

View File

@ -0,0 +1,3 @@
package io.cloudevents.message;
public interface MessageVisitor<BV extends BinaryMessageVisitor<R>, R> extends BinaryMessageVisitorFactory<BV, R>, StructuredMessageVisitor<R> { }

View File

@ -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<String> getDataContentType() {
return Optional.ofNullable(datacontenttype);
}
public Optional<URI> 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<String, String> marshal(AttributesImpl attributes) {
// Objects.requireNonNull(attributes);
//
// Map<String, String> 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<String, String> 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);
}
}

View File

@ -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<String, String> marshal(AttributesImpl attributes) {
// Objects.requireNonNull(attributes);
// Map<String, String> 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<String, String> 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);
}
}

View File

@ -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.<Attributes, Much, String, String>builder()
.mime(null, "");
}
@Test
public void should_throw_on_null_envelope_mime_value() {
// setup
expectedEx.expect(NullPointerException.class);
// act
StructuredMarshaller.<Attributes, Much, String, String>builder()
.mime("", null);
}
@Test
public void should_be_ok_on_the_first_step() {
// act
StructuredMarshaller.<Attributes, Much, String, String>builder()
.mime("Content-Type", "application/cloudevents+json");
}
@Test
public void should_throw_on_null_marshaller_step() {
// setup
expectedEx.expect(NullPointerException.class);
// act
StructuredMarshaller.<Attributes, Much, String, String>builder()
.mime("Content-Type", "application/cloudevents+json")
.map(null);
}
@Test
public void should_throw_on_null_event() {
// setup
expectedEx.expect(NullPointerException.class);
StructuredMarshaller.<Attributes, Much, String, String>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.<Attributes, Much, String, String>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.<Attributes, Much, String, String>builder()
.mime("Content-Type", "application/cloudevents+json")
.map((ce) -> null)
.map(null);
}
@Test
public void should_ok_on_the_extension_acessor() {
// act
StructuredMarshaller.<Attributes, Much, String, String>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.<Attributes, Much, String, String>builder()
.mime("Content-Type", "application/cloudevents+json")
.map((ce) -> null)
.map((event) -> null)
.map(null);
}
@Test
public void should_ok_on_extension_marshaller() {
StructuredMarshaller.<Attributes, Much, String, String>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.<Attributes, Much, String, String>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.<Attributes, Much, String, String>builder()
.mime("Content-Type", "application/cloudevents+json")
.map((ce) -> null)
.map((event) -> null)
.map((extensions) -> null)
.map((attributes, extensions) -> null);
}
}

View File

@ -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.<Attributes, Much, String>builder()
.map(null);
}
@Test
public void should_ok_on_extension_mapper() {
StructuredUnmarshaller.<Attributes, Much, String>builder()
.map((headers) -> {
return null;
});
}
@Test
public void should_throw_on_null_extension_unmarshaller() {
// setup
expectedEx.expect(NullPointerException.class);
StructuredUnmarshaller.<Attributes, Much, String>builder()
.map((headers) -> {
return null;
})
.map(null);
}
@Test
public void should_ok_on_extension_unmarshaller() {
StructuredUnmarshaller.<Attributes, Much, String>builder()
.map((headers) -> {
return null;
})
.map((extensions) -> {
return null;
});
}
@Test
public void should_throw_on_null_envelope_unmarshaller() {
// setup
expectedEx.expect(NullPointerException.class);
StructuredUnmarshaller.<Attributes, Much, String>builder()
.map((headers) -> {
return null;
})
.map((extensions) -> {
return null;
})
.next()
.map(null);
}
@Test
public void should_ok_on_envelope_unmarshaller() {
StructuredUnmarshaller.<Attributes, Much, String>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.<Attributes, Much, String>builder()
.map((headers) -> null)
.map((extensions) -> null)
.next()
.map((payload, extensions) -> null)
.withHeaders(null);
}
@Test
public void should_ok_on_headers() {
StructuredUnmarshaller.<Attributes, Much, String>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.<Attributes, Much, String>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.<Attributes, Much, String>builder()
.map((headers) -> null)
.map((extensions) -> null)
.next()
.map((payload, extensions) -> null)
.withHeaders(() -> null)
.withPayload(() -> null);
}
}

View File

@ -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<String, String, Object>("payload", null);
}
@Test
public void throws_when_try_to_change_headers() {
// setup
expectedEx.expect(UnsupportedOperationException.class);
Map<String, Object> headers = new HashMap<>();
headers.put("contenttype", "application/json");
// act
Wire<String, String, Object> wire = new Wire<>("payload", headers);
wire.getHeaders().put("my-header", "my-header-val");
}
@Test
public void should_ok_when_null_payload() {
Wire<String, String, Object> expected =
new Wire<>(null, new HashMap<>());
assertFalse(expected.getPayload().isPresent());
}
@Test
public void should_ok_when_payload_not_null() {
Wire<String, String, Object> actual =
new Wire<>("payload", new HashMap<>());
assertTrue(actual.getPayload().isPresent());
assertEquals("payload", actual.getPayload().get());
}
}

View File

@ -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<String, Object> 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<String, String> 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<String, String> 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<String, String> headers = io.cloudevents.v02.http.HeaderMapper
.map(attributes, new HashMap<String, String>());
// 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<String, Object> 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<String, String> 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"));
}
}

View File

@ -0,0 +1,4 @@
package io.cloudevents.impl;
public class CloudEventImplTest {
}

View File

@ -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<Map<String, Object>>() {});
// assert
assertNull(actual);
}
@Test
public void should_result_null_on_decode_typereference_null_string() {
// act
Object actual = Json.decodeValue(null, new TypeReference<Map<String, Object>>() {});
// assert
assertNull(actual);
}
}

View File

@ -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);
}
}

View File

@ -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<MockBinaryMessage, MockBinaryMessage>, BinaryMessageVisitor<MockBinaryMessage> {
private SpecVersion version;
private Map<String, Object> attributes;
private byte[] data;
private Map<String, Object> extensions;
public MockBinaryMessage(SpecVersion version, Map<String, Object> attributes, byte[] data, Map<String, Object> 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 <T extends BinaryMessageVisitor<V>, V> V visit(BinaryMessageVisitorFactory<T, V> visitorFactory) throws MessageVisitException, IllegalStateException {
if (version == null) {
throw new IllegalStateException("MockBinaryMessage is empty");
}
BinaryMessageVisitor<V> visitor = visitorFactory.createBinaryMessageVisitor(version);
for (Map.Entry<String, Object> 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<String, Object> 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> T visit(StructuredMessageVisitor<T> 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;
}
}

View File

@ -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<CloudEvent> allEvents() {
return Stream.concat(v1Events(), v03Events());
}
public static Stream<CloudEvent> v1Events() {
return Stream.of(
Data.V1_MIN,
Data.V1_WITH_JSON_DATA
);
}
public static Stream<CloudEvent> v03Events() {
return v1Events().map(CloudEvent::toV03);
}
}

View File

@ -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<Object> ce =
CloudEventBuilder.<Object>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withSchemaurl(URI.create("/schema"))
.withDatacontenttype("text/plain")
.withData("my-data")
.build();
// act
Collection<ExtensionFormat> 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<Object> ce =
CloudEventBuilder.<Object>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<ExtensionFormat> 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<Object> ce =
CloudEventBuilder.<Object>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<ExtensionFormat> 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());
}
}

View File

@ -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.<Object>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.<Object>builder()
.withId("id")
.withType("type")
.withSource(URI.create("/source"))
.withSubject("subject")
.withDatacontentencoding("binary")
.build();
}
@Test
public void should_have_subject() {
// act
CloudEvent<AttributesImpl, Object> ce =
CloudEventBuilder.<Object>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<Object> 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<Object> 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<String> event = CloudEventBuilder
.<String>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<AttributesImpl, String> event = CloudEventBuilder.<String>of(
expected,
new AttributesImpl(null, null, null, null, null, null, null, null, null),
Collections.emptyList(),
validator
);
CloudEvent<AttributesImpl, String> result = CloudEventBuilder
.builder(event)
.withValidator(validator)
.build();
assertNotNull(result);
assertEquals(expected, result.getData().get());
}
}

View File

@ -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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> ce =
Json.fromInputStream(resourceOf("03_new.json"), CloudEventImpl.class);
// assert
assertTrue(ce.getAttributes().getTime().isPresent());
}
@Test
public void should_have_source() {
// act
CloudEvent<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Object> 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<AttributesImpl, Much> ce =
Json.decodeValue(json, new TypeReference<CloudEventImpl<Much>>() {});
// assert
assertTrue(ce.getData().isPresent());
assertEquals(expected.getWow(), ce.getData().get().getWow());
}
}

View File

@ -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<String, Object> headers = new HashMap<>();
headers.put("ce-type", null);
String expected = "type";
// act
Map<String, String> attributes =
AttributeMapper.map(headers);
// assert
assertFalse(attributes.containsKey(expected));
}
@Test
public void should_ok_when_no_content_type() {
// setup
Map<String, Object> headers = new HashMap<>();
headers.put("ce-specversion", "0.3");
// act
Map<String, String> attributes =
AttributeMapper.map(headers);
// assert
assertFalse(attributes.isEmpty());
}
@Test
public void should_map_cespecversion_to_specversion() {
// setup
Map<String, Object> headers = new HashMap<>();
headers.put("ce-specversion", "0.3");
headers.put("Content-Type", "application/json");
String expected = "specversion";
// act
Map<String, String> attributes =
AttributeMapper.map(headers);
// assert
assertNotNull(attributes.get(expected));
}
@Test
public void should_all_without_prefix_ce() {
// setup
Map<String, Object> 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<String, String> actual = AttributeMapper.map(myHeaders);
actual.keySet()
.forEach((attribute) -> {
assertFalse(attribute.startsWith("ce-"));
});
}
}

View File

@ -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<String, Object> 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<String, String> actual = ExtensionMapper.map(myHeaders);
// assert
assertFalse(actual.containsKey(expected));
}
@Test
public void should_return_just_potential_extensions() {
// setup
Map<String, Object> 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<String, String> 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"));
}
}

View File

@ -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<Much> ce =
CloudEventBuilder.<Much>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDatacontenttype("application/json")
.withSubject("subject")
.withData(ceData)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<Much>
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<Much> ce =
CloudEventBuilder.<Much>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDatacontenttype("application/json")
.withSubject("subject")
.withData(ceData)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<Much>
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<String> ce =
CloudEventBuilder.<String>builder()
.withId("id")
.withSource(URI.create("/source"))
.withType("type")
.withExtension(tracing)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<String>
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));
}
}

View File

@ -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<String, Object> 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<AttributesImpl, Much> 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<String, Object> 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<AttributesImpl, Much> 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);
}
}

View File

@ -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<Much> ce =
CloudEventBuilder.<Much>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDatacontenttype("application/json")
.withSubject("subject")
.withData(ceData)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<Much>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<String> ce =
CloudEventBuilder.<String>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDatacontenttype("text/plain")
.withData(ceData)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<String>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<String> ce =
CloudEventBuilder.<String>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDatacontenttype("text/plain")
.withData(ceData)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<String>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<String> ce =
CloudEventBuilder.<String>builder()
.withId("id")
.withSource(URI.create("/source"))
.withType("type")
.withExtension(tracing)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<String>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));
}
}

View File

@ -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<String, Object> 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<Much> expected =
CloudEventBuilder.<Much>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDatacontenttype("application/json")
.withSubject("subject")
.withData(ceData)
.build();
// act
CloudEvent<AttributesImpl, Much> 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<String, Object> 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<String> expected =
CloudEventBuilder.<String>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDatacontenttype("text/plain")
.withData(ceData)
.build();
// act
CloudEvent<AttributesImpl, String> 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<String, Object> 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<AttributesImpl, String> 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);
}
}

View File

@ -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<String, String> extensions = new HashMap<>();
// act
HeaderMapper.map(null, extensions);
}
@Test
public void error_when_extensions_map_isnull() {
// setup
expectedEx.expect(NullPointerException.class);
Map<String, String> attributes = new HashMap<>();
// act
HeaderMapper.map(attributes, null);
}
@Test
public void should_not_map_null_attribute_value() {
// setup
Map<String, String> attributes = new HashMap<>();
attributes.put("type", null);
attributes.put("specversion", "0.3");
Map<String, String> extensions = new HashMap<>();
// act
Map<String, String> actual = HeaderMapper.map(attributes, extensions);
//assert
assertFalse(actual.containsKey("ce-type"));
}
@Test
public void should_not_map_null_extension_value() {
// setup
Map<String, String> attributes = new HashMap<>();
attributes.put("type", "mytype");
attributes.put("specversion", "0.2");
Map<String, String> extensions = new HashMap<>();
extensions.put("null-ext", null);
extensions.put("comexampleextension1", "value");
// act
Map<String, String> actual = HeaderMapper.map(attributes, extensions);
//assert
assertFalse(actual.containsKey("ce-null-ext"));
}
@Test
public void should_not_map_absent_datacontenttype() {
// setup
Map<String, String> attributes = new HashMap<>();
attributes.put("type", "mytype");
attributes.put("specversion", "0.2");
Map<String, String> extensions = new HashMap<>();
extensions.put("null-ext", "null-value");
extensions.put("comexampleextension1", "value");
// act
Map<String, String> actual = HeaderMapper.map(attributes, extensions);
//assert
assertFalse(actual.containsKey("Content-Type"));
}
}

View File

@ -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<Object> ce =
CloudEventBuilder.<Object>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDataschema(URI.create("/schema"))
.withDataContentType("text/plain")
.withData("my-data")
.build();
// act
Collection<ExtensionFormat> 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<Object> ce =
CloudEventBuilder.<Object>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<ExtensionFormat> 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<Object> ce =
CloudEventBuilder.<Object>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<ExtensionFormat> 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());
}
}

View File

@ -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.<Object>builder()
.withId("id")
.withType("type")
.withSource(URI.create("/source"))
.withSubject("")
.build();
}
@Test
public void should_have_subject() {
// act
CloudEvent<AttributesImpl, Object> ce =
CloudEventBuilder.<Object>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<Object> 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<Object> 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<String> event = CloudEventBuilder
.<String>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<AttributesImpl, String> event = CloudEventBuilder.<String>builder()
.withData(expected)
.withValidator(validator)
.build();
CloudEvent<AttributesImpl, String> result = CloudEventBuilder
.builder(event)
.withValidator(validator)
.build();
assertNotNull(result);
assertEquals(expected, result.getData().get());
}
}

View File

@ -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<AttributesImpl, Much> ce =
Json.decodeValue(json, new TypeReference<CloudEventImpl<Much>>() {});
// 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<AttributesImpl, String> ce =
Json.fromInputStream(resourceOf("1_base64.json"),
new TypeReference<CloudEventImpl<String>>() {});
// 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<String> event =
CloudEventBuilder.<String>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 +"\""));
}
}

View File

@ -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<String, Object> headers = new HashMap<>();
headers.put("ce-type", null);
String expected = "type";
// act
Map<String, String> attributes =
AttributeMapper.map(headers);
// assert
assertFalse(attributes.containsKey(expected));
}
@Test
public void should_ok_when_no_content_type() {
// setup
Map<String, Object> headers = new HashMap<>();
headers.put("ce-specversion", "1.0");
// act
Map<String, String> attributes =
AttributeMapper.map(headers);
// assert
assertFalse(attributes.isEmpty());
}
@Test
public void should_map_cespecversion_to_specversion() {
// setup
Map<String, Object> headers = new HashMap<>();
headers.put("ce-specversion", "1.0");
headers.put("Content-Type", "application/json");
String expected = "specversion";
// act
Map<String, String> attributes =
AttributeMapper.map(headers);
// assert
assertNotNull(attributes.get(expected));
}
@Test
public void should_all_without_prefix_ce() {
// setup
Map<String, Object> 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<String, String> actual = AttributeMapper.map(myHeaders);
actual.keySet()
.forEach((attribute) -> {
assertFalse(attribute.startsWith("ce-"));
});
}
}

View File

@ -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<String, Object> 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<String, String> actual = ExtensionMapper.map(myHeaders);
// assert
assertFalse(actual.containsKey(expected));
}
@Test
public void should_return_just_potential_extensions() {
// setup
Map<String, Object> 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<String, String> 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"));
}
}

View File

@ -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<Much> ce =
CloudEventBuilder.<Much>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDataContentType("application/json")
.withSubject("subject")
.withData(ceData)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<Much>
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<byte[]> ce =
CloudEventBuilder.<byte[]>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDataContentType("text/plain")
.withSubject("subject")
.withData(data)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<byte[]>
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<Much> ce =
CloudEventBuilder.<Much>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDataContentType("application/json")
.withSubject("subject")
.withData(ceData)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<Much>
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<String> ce =
CloudEventBuilder.<String>builder()
.withId("id")
.withSource(URI.create("/source"))
.withType("type")
.withExtension(tracing)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<String>
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));
}
}

View File

@ -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<String, Object> 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<AttributesImpl, Much> 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<String, Object> 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<AttributesImpl, Much> 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);
}
}

View File

@ -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<String> ce =
CloudEventBuilder.<String>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDataContentType("text/plain")
.withData(ceData)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<String>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<String> ce =
CloudEventBuilder.<String>builder()
.withId("id")
.withSource(URI.create("/source"))
.withType("type")
.withExtension(tracing)
.build();
// act
Wire<String, String, String> actual =
Marshallers.<String>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));
}
}

View File

@ -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<String, Object> 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<Much> expected =
CloudEventBuilder.<Much>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDataContentType("application/json")
.withSubject("subject")
.withData(ceData)
.build();
// act
CloudEvent<AttributesImpl, Much> 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<String, Object> 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<String> expected =
CloudEventBuilder.<String>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDataContentType("text/plain")
.withData(ceData)
.build();
// act
CloudEvent<AttributesImpl, String> 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<String, Object> 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<String> expected =
CloudEventBuilder.<String>builder()
.withId("x10")
.withSource(URI.create("/source"))
.withType("event-type")
.withDataContentType("text/plain")
.withDataBase64(ceData.getBytes())
.build();
// act
CloudEvent<AttributesImpl, String> 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<String, Object> 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<AttributesImpl, String> 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);
}
}

View File

@ -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<String, String> extensions = new HashMap<>();
// act
HeaderMapper.map(null, extensions);
}
@Test
public void error_when_extensions_map_isnull() {
// setup
expectedEx.expect(NullPointerException.class);
Map<String, String> attributes = new HashMap<>();
// act
HeaderMapper.map(attributes, null);
}
@Test
public void should_not_map_null_attribute_value() {
// setup
Map<String, String> attributes = new HashMap<>();
attributes.put("type", null);
attributes.put("specversion", "1.0");
Map<String, String> extensions = new HashMap<>();
// act
Map<String, String> actual = HeaderMapper.map(attributes, extensions);
//assert
assertFalse(actual.containsKey("ce-type"));
}
@Test
public void should_not_map_null_extension_value() {
// setup
Map<String, String> attributes = new HashMap<>();
attributes.put("type", "mytype");
attributes.put("specversion", "1.0");
Map<String, String> extensions = new HashMap<>();
extensions.put("null-ext", null);
extensions.put("comexampleextension1", "value");
// act
Map<String, String> actual = HeaderMapper.map(attributes, extensions);
//assert
assertFalse(actual.containsKey("ce-null-ext"));
}
@Test
public void should_not_map_absent_datacontenttype() {
// setup
Map<String, String> attributes = new HashMap<>();
attributes.put("type", "mytype");
attributes.put("specversion", "1.0");
Map<String, String> extensions = new HashMap<>();
extensions.put("null-ext", "null-value");
extensions.put("comexampleextension1", "value");
// act
Map<String, String> actual = HeaderMapper.map(attributes, extensions);
//assert
assertFalse(actual.containsKey("Content-Type"));
}
}

View File

@ -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 <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {
return new HashSet<>();
}
@Override
public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) {
return null;
}
@Override
public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
return null;
}
@Override
public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
return null;
}
@Override
public <T> T unwrap(Class<T> type) {
return null;
}
@Override
public ExecutableValidator forExecutables() {
return null;
}
}

View File

@ -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 <T> 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 <T> HeadersStep<AttributesImpl, T, byte[]>
public static <T> HeadersStep<AttributesImpl, T, byte[]>
binary(Class<T> type) {
return
return
BinaryUnmarshaller.<AttributesImpl, T, byte[]>
builder()
.map(AttributeMapper::map)
@ -57,66 +53,66 @@ public class Unmarshallers {
.builder(CloudEventBuilder.<T>builder()::build);
}
/**
* Builds a Structured Content Mode unmarshaller to unmarshal JSON as CloudEvents data
* for Kafka Transport Binding
*
*
* @param <T> 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 <T> HeadersStep<AttributesImpl, T, byte[]>
public static <T> HeadersStep<AttributesImpl, T, byte[]>
structured(Class<T> typeOfData) {
return
StructuredUnmarshaller.<AttributesImpl, T, byte[]>
builder()
.map(ExtensionMapper::map)
.map(DistributedTracingExtension::unmarshall)
.next()
.map((payload, extensions) -> {
.map((payload, extensions) -> {
CloudEventImpl<T> event =
Json.<CloudEventImpl<T>>
binaryDecodeValue(payload, CloudEventImpl.class, typeOfData);
Optional<ExtensionFormat> dteFormat =
Optional<ExtensionFormat> dteFormat =
ofNullable(event.getExtensions().get(IN_MEMORY_KEY))
.filter(extension -> extension instanceof Map)
.map(extension -> (Map<String, Object>)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<T> builder =
CloudEventBuilder<T> builder =
CloudEventBuilder.<T>builder(event);
extensions.get().forEach(extension -> {
builder.withExtension(extension);
});
dteFormat.ifPresent(tracing -> {
builder.withExtension(tracing);
});
return builder.build();
});
}

View File

@ -52,4 +52,4 @@ public class CloudEventsKafkaHeadersTest {
Assertions.assertEquals(expectedHeader.getValue(), values.get(expectedHeader.getKey()));
}
}
}
}