Javadoc-ed cloudevents-core (#182)
Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>
This commit is contained in:
parent
98a6b87d5b
commit
83d9045897
|
@ -23,12 +23,14 @@ import io.cloudevents.SpecVersion;
|
|||
import io.cloudevents.rw.CloudEventWriter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNullableByDefault;
|
||||
import java.net.URI;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
/**
|
||||
* Builder interface to build a {@link CloudEvent}.
|
||||
*/
|
||||
@ParametersAreNullableByDefault
|
||||
public interface CloudEventBuilder extends CloudEventWriter<CloudEvent> {
|
||||
|
||||
/**
|
||||
|
@ -121,7 +123,7 @@ public interface CloudEventBuilder extends CloudEventWriter<CloudEvent> {
|
|||
* @param value value of the extension attribute
|
||||
* @return self
|
||||
*/
|
||||
CloudEventBuilder withExtension(String key, String value);
|
||||
CloudEventBuilder withExtension(@Nonnull String key, String value);
|
||||
|
||||
/**
|
||||
* Set an extension with provided key and numeric value
|
||||
|
@ -130,7 +132,7 @@ public interface CloudEventBuilder extends CloudEventWriter<CloudEvent> {
|
|||
* @param value value of the extension attribute
|
||||
* @return self
|
||||
*/
|
||||
CloudEventBuilder withExtension(String key, Number value);
|
||||
CloudEventBuilder withExtension(@Nonnull String key, Number value);
|
||||
|
||||
/**
|
||||
* Set an extension with provided key and boolean value
|
||||
|
@ -139,7 +141,7 @@ public interface CloudEventBuilder extends CloudEventWriter<CloudEvent> {
|
|||
* @param value value of the extension attribute
|
||||
* @return self
|
||||
*/
|
||||
CloudEventBuilder withExtension(String key, boolean value);
|
||||
CloudEventBuilder withExtension(@Nonnull String key, boolean value);
|
||||
|
||||
/**
|
||||
* Add to the builder all the extension key/values of the provided extension
|
||||
|
@ -147,7 +149,7 @@ public interface CloudEventBuilder extends CloudEventWriter<CloudEvent> {
|
|||
* @param extension materialized extension to set in the event
|
||||
* @return self
|
||||
*/
|
||||
CloudEventBuilder withExtension(Extension extension);
|
||||
CloudEventBuilder withExtension(@Nonnull Extension extension);
|
||||
|
||||
/**
|
||||
* Build the event
|
||||
|
@ -175,7 +177,7 @@ public interface CloudEventBuilder extends CloudEventWriter<CloudEvent> {
|
|||
* @param event event to bootstrap the builder
|
||||
* @return a new CloudEvent v1 builder filled with content of {@code event}
|
||||
*/
|
||||
static io.cloudevents.core.v1.CloudEventBuilder v1(CloudEvent event) {
|
||||
static io.cloudevents.core.v1.CloudEventBuilder v1(@Nonnull CloudEvent event) {
|
||||
return new io.cloudevents.core.v1.CloudEventBuilder(event);
|
||||
}
|
||||
|
||||
|
@ -190,7 +192,7 @@ public interface CloudEventBuilder extends CloudEventWriter<CloudEvent> {
|
|||
* @param event event to bootstrap the builder
|
||||
* @return a new CloudEvent v0.3 builder filled with content of {@code event}
|
||||
*/
|
||||
static io.cloudevents.core.v03.CloudEventBuilder v03(CloudEvent event) {
|
||||
static io.cloudevents.core.v03.CloudEventBuilder v03(@Nonnull CloudEvent event) {
|
||||
return new io.cloudevents.core.v03.CloudEventBuilder(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@ import java.util.Collections;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This extension embeds context from Distributed Tracing so that distributed systems can include traces that span an event-driven system.
|
||||
*
|
||||
* @see <a href="https://github.com/cloudevents/spec/blob/master/extensions/distributed-tracing.md">https://github.com/cloudevents/spec/blob/master/extensions/distributed-tracing.md</a>
|
||||
*/
|
||||
public final class DistributedTracingExtension implements Extension {
|
||||
|
||||
public static final String TRACEPARENT = "traceparent";
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
package io.cloudevents.core.format;
|
||||
|
||||
/**
|
||||
* Exception representing a deserialization error while using an {@link EventFormat}.
|
||||
*/
|
||||
public class EventDeserializationException extends RuntimeException {
|
||||
public EventDeserializationException(Throwable e) {
|
||||
super(e);
|
||||
|
|
|
@ -19,19 +19,53 @@ package io.cloudevents.core.format;
|
|||
|
||||
import io.cloudevents.CloudEvent;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An <a href="https://github.com/cloudevents/spec/blob/v1.0/spec.md#event-format">Event format</a>
|
||||
* specifies how to serialize a CloudEvent as a sequence of bytes. <br/>
|
||||
* <p>
|
||||
* An implementation of this interface should support all specification versions of {@link CloudEvent}. <br/>
|
||||
* <p>
|
||||
* Implementations of this interface can be registered to the {@link io.cloudevents.core.provider.EventFormatProvider} to use them.
|
||||
*
|
||||
* @see io.cloudevents.core.provider.EventFormatProvider
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public interface EventFormat {
|
||||
|
||||
/**
|
||||
* Serialize a {@link CloudEvent} to a byte array.
|
||||
*
|
||||
* @param event the event to serialize.
|
||||
* @return the byte representation of the provided event.
|
||||
* @throws EventSerializationException if something goes wrong during serialization.
|
||||
*/
|
||||
byte[] serialize(CloudEvent event) throws EventSerializationException;
|
||||
|
||||
CloudEvent deserialize(byte[] event) throws EventDeserializationException;
|
||||
/**
|
||||
* Deserialize a byte array to a {@link CloudEvent}.
|
||||
*
|
||||
* @param bytes the serialized event.
|
||||
* @return the deserialized event.
|
||||
* @throws EventDeserializationException if something goes wrong during deserialization.
|
||||
*/
|
||||
CloudEvent deserialize(byte[] bytes) throws EventDeserializationException;
|
||||
|
||||
/**
|
||||
* @return the set of content types this event format can deserialize. These content types are used
|
||||
* by the {@link io.cloudevents.core.provider.EventFormatProvider} to resolve an {@link EventFormat} starting
|
||||
* from the content type {@link String}.
|
||||
*/
|
||||
default Set<String> deserializableContentTypes() {
|
||||
return Collections.singleton(serializedContentType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The content type to use when writing an event with this {@link EventFormat}.
|
||||
*/
|
||||
String serializedContentType();
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
package io.cloudevents.core.format;
|
||||
|
||||
/**
|
||||
* Exception representing a serialization error while using an {@link EventFormat}.
|
||||
*/
|
||||
public class EventSerializationException extends RuntimeException {
|
||||
public EventSerializationException(Throwable e) {
|
||||
super(e);
|
||||
|
|
|
@ -22,6 +22,7 @@ import io.cloudevents.Extension;
|
|||
import io.cloudevents.core.builder.CloudEventBuilder;
|
||||
import io.cloudevents.rw.CloudEventRWException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -75,22 +76,22 @@ public abstract class BaseCloudEventBuilder<SELF extends BaseCloudEventBuilder<S
|
|||
return this.self;
|
||||
}
|
||||
|
||||
public SELF withExtension(String key, String value) {
|
||||
public SELF withExtension(@Nonnull String key, String value) {
|
||||
this.extensions.put(key, value);
|
||||
return self;
|
||||
}
|
||||
|
||||
public SELF withExtension(String key, Number value) {
|
||||
public SELF withExtension(@Nonnull String key, Number value) {
|
||||
this.extensions.put(key, value);
|
||||
return self;
|
||||
}
|
||||
|
||||
public SELF withExtension(String key, boolean value) {
|
||||
public SELF withExtension(@Nonnull String key, boolean value) {
|
||||
this.extensions.put(key, value);
|
||||
return self;
|
||||
}
|
||||
|
||||
public SELF withExtension(Extension extension) {
|
||||
public SELF withExtension(@Nonnull Extension extension) {
|
||||
for (String key : extension.getKeys()) {
|
||||
Object value = extension.getValue(key);
|
||||
if (value != null) {
|
||||
|
|
|
@ -22,9 +22,12 @@ import io.cloudevents.core.builder.CloudEventBuilder;
|
|||
import io.cloudevents.core.format.EventFormat;
|
||||
import io.cloudevents.rw.*;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
/**
|
||||
* Represents a <a href="https://github.com/cloudevents/spec/blob/v1.0/spec.md#message">CloudEvent message</a>.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public interface MessageReader extends StructuredMessageReader, CloudEventReader {
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,11 +24,14 @@ import io.cloudevents.core.message.impl.GenericStructuredMessageReader;
|
|||
import io.cloudevents.rw.CloudEventWriter;
|
||||
import io.cloudevents.rw.CloudEventWriterFactory;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
/**
|
||||
* Interface to write the {@link MessageReader} content (CloudEvents attributes, extensions and payload) to a new representation.
|
||||
*
|
||||
* @param <R> return value at the end of the write process.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public interface MessageWriter<CEV extends CloudEventWriter<R>, R> extends CloudEventWriterFactory<CEV, R>, StructuredMessageWriter<R> {
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,10 +22,13 @@ import io.cloudevents.core.format.EventFormat;
|
|||
import io.cloudevents.core.message.impl.GenericStructuredMessageReader;
|
||||
import io.cloudevents.rw.CloudEventRWException;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
/**
|
||||
* Represents a <a href="https://github.com/cloudevents/spec/blob/v1.0/spec.md#message">CloudEvent message</a> in structured mode.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@ParametersAreNonnullByDefault
|
||||
public interface StructuredMessageReader {
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,11 +20,20 @@ package io.cloudevents.core.message;
|
|||
import io.cloudevents.core.format.EventFormat;
|
||||
import io.cloudevents.rw.CloudEventRWException;
|
||||
|
||||
//TODO javadoc
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
/**
|
||||
* Interface to write the {@link MessageReader} content (CloudEvents attributes, extensions and payload) to a new representation structured representation.
|
||||
*
|
||||
* @param <T> return value at the end of the write process.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
@FunctionalInterface
|
||||
public interface StructuredMessageWriter<T> {
|
||||
|
||||
// TODO one day we'll convert this to some byte stream
|
||||
/**
|
||||
* Write an event using the provided {@link EventFormat}.
|
||||
*/
|
||||
T setEvent(EventFormat format, byte[] value) throws CloudEventRWException;
|
||||
|
||||
}
|
||||
|
|
|
@ -32,14 +32,7 @@ import java.util.stream.Stream;
|
|||
public class MessageUtils {
|
||||
|
||||
/**
|
||||
* Common flow to parse an incoming message that could be structured or binary
|
||||
*
|
||||
* @param contentTypeHeaderReader
|
||||
* @param structuredMessageFactory
|
||||
* @param specVersionHeaderReader
|
||||
* @param binaryMessageFactory
|
||||
* @param unknownMessageFactory
|
||||
* @return
|
||||
* Common flow to parse an incoming message that could be structured or binary.<br/>
|
||||
*/
|
||||
public static MessageReader parseStructuredOrBinaryMessage(
|
||||
Supplier<String> contentTypeHeaderReader,
|
||||
|
@ -72,7 +65,7 @@ public class MessageUtils {
|
|||
*
|
||||
* @param headerNameMapping mapper to generate the header name
|
||||
* @param <V> Header key type
|
||||
* @return
|
||||
* @return the generated mapping
|
||||
*/
|
||||
public static <V> Map<String, V> generateAttributesToHeadersMapping(Function<String, V> headerNameMapping) {
|
||||
return Stream.concat(
|
||||
|
|
|
@ -18,17 +18,30 @@
|
|||
package io.cloudevents.core.provider;
|
||||
|
||||
import io.cloudevents.core.format.EventFormat;
|
||||
import io.cloudevents.lang.Nullable;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.HashMap;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* Singleton holding the discovered {@link EventFormat} implementations through {@link ServiceLoader}.<br/>
|
||||
* <p>
|
||||
* You can resolve an event format using {@code EventFormatProvider.getInstance().resolveFormat(contentType)}.<br/>
|
||||
* <p>
|
||||
* You can programmatically add a new {@link EventFormat} implementation using {@link this#registerFormat(EventFormat)}.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public final class EventFormatProvider {
|
||||
|
||||
private static class SingletonContainer {
|
||||
private final static EventFormatProvider INSTANCE = new EventFormatProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return instance of {@link EventFormatProvider}
|
||||
*/
|
||||
public static EventFormatProvider getInstance() {
|
||||
return EventFormatProvider.SingletonContainer.INSTANCE;
|
||||
}
|
||||
|
@ -44,18 +57,30 @@ public final class EventFormatProvider {
|
|||
).forEach(this::registerFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new {@link EventFormat} programmatically.
|
||||
*
|
||||
* @param format the new format to register
|
||||
*/
|
||||
public void registerFormat(EventFormat format) {
|
||||
for (String k : format.deserializableContentTypes()) {
|
||||
this.formats.put(k, format);
|
||||
}
|
||||
}
|
||||
|
||||
public EventFormat resolveFormat(String key) {
|
||||
int i = key.indexOf(';');
|
||||
/**
|
||||
* Resolve an event format starting from the content type.
|
||||
*
|
||||
* @param contentType the content type to resolve the event format
|
||||
* @return null if no format was found for the provided content type
|
||||
*/
|
||||
@Nullable
|
||||
public EventFormat resolveFormat(String contentType) {
|
||||
int i = contentType.indexOf(';');
|
||||
if (i != -1) {
|
||||
key = key.substring(0, i);
|
||||
contentType = contentType.substring(0, i);
|
||||
}
|
||||
return this.formats.get(key);
|
||||
return this.formats.get(contentType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,14 +17,22 @@
|
|||
|
||||
package io.cloudevents.core.provider;
|
||||
|
||||
import io.cloudevents.CloudEvent;
|
||||
import io.cloudevents.CloudEventExtensions;
|
||||
import io.cloudevents.Extension;
|
||||
import io.cloudevents.core.extensions.DatarefExtension;
|
||||
import io.cloudevents.core.extensions.DistributedTracingExtension;
|
||||
import io.cloudevents.lang.Nullable;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Singleton to materialize CloudEvent extensions as POJOs. <br/>
|
||||
* <p>
|
||||
* You can materialize an {@link Extension} POJO with {@code ExtensionProvider.getInstance().parseExtension(DistributedTracingExtension.class, event)}.<br/>
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public final class ExtensionProvider {
|
||||
|
||||
private static class SingletonContainer {
|
||||
|
@ -35,7 +43,7 @@ public final class ExtensionProvider {
|
|||
return SingletonContainer.INSTANCE;
|
||||
}
|
||||
|
||||
private final HashMap<Class<?>, Supplier<Extension>> extensionFactories;
|
||||
private final HashMap<Class<?>, Supplier<?>> extensionFactories;
|
||||
|
||||
// TODO SPI in future?
|
||||
private ExtensionProvider() {
|
||||
|
@ -44,16 +52,31 @@ public final class ExtensionProvider {
|
|||
registerExtension(DatarefExtension.class, DatarefExtension::new);
|
||||
}
|
||||
|
||||
public <T extends Extension> void registerExtension(Class<T> extensionClass, Supplier<Extension> factory) {
|
||||
/**
|
||||
* Register a new extension type.
|
||||
*
|
||||
* @param extensionClass the class implementing {@link Extension}
|
||||
* @param factory the empty arguments factory
|
||||
* @param <T> the type of the extension
|
||||
*/
|
||||
public <T extends Extension> void registerExtension(Class<T> extensionClass, Supplier<T> factory) {
|
||||
this.extensionFactories.put(extensionClass, factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an extension from the {@link CloudEventExtensions}, materializing the corresponding POJO. <br/>
|
||||
*
|
||||
* @param extensionClass the class implementing {@link Extension}
|
||||
* @param eventExtensions the event extensions to read
|
||||
* @param <T> the type of the extension
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Extension> T parseExtension(Class<T> extensionClass, CloudEvent event) {
|
||||
Supplier<Extension> factory = extensionFactories.get(extensionClass);
|
||||
@Nullable
|
||||
public <T extends Extension> T parseExtension(Class<T> extensionClass, CloudEventExtensions eventExtensions) {
|
||||
Supplier<?> factory = extensionFactories.get(extensionClass);
|
||||
if (factory != null) {
|
||||
Extension ext = factory.get();
|
||||
ext.readFrom(event);
|
||||
Extension ext = (Extension) factory.get();
|
||||
ext.readFrom(eventExtensions);
|
||||
return (T) ext;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -28,9 +28,10 @@ import java.time.ZonedDateTime;
|
|||
import java.time.format.DateTimeParseException;
|
||||
|
||||
/**
|
||||
* The event builder.
|
||||
* CloudEvent V0.3 builder.
|
||||
*
|
||||
* @author fabiojose
|
||||
* @author slinkydeveloper
|
||||
*/
|
||||
public final class CloudEventBuilder extends BaseCloudEventBuilder<CloudEventBuilder, CloudEventV03> {
|
||||
|
||||
|
|
|
@ -30,9 +30,10 @@ import java.time.ZonedDateTime;
|
|||
import java.time.format.DateTimeParseException;
|
||||
|
||||
/**
|
||||
* CloudEvent V1.0 builder.
|
||||
*
|
||||
* @author fabiojose
|
||||
* @author slinkydeveloper
|
||||
* @version 1.0
|
||||
*/
|
||||
public final class CloudEventBuilder extends BaseCloudEventBuilder<CloudEventBuilder, CloudEventV1> {
|
||||
|
||||
|
|
|
@ -28,9 +28,10 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* CloudEvent implementation for v1.0
|
||||
*
|
||||
* @author fabiojose
|
||||
* @author slinkydeveloper
|
||||
* @version 1.0
|
||||
*/
|
||||
public final class CloudEventV1 extends BaseCloudEvent {
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ public class CSVFormat implements EventFormat {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CloudEvent deserialize(byte[] event) {
|
||||
String[] splitted = new String(event, StandardCharsets.UTF_8).split(Pattern.quote(","));
|
||||
public CloudEvent deserialize(byte[] bytes) {
|
||||
String[] splitted = new String(bytes, StandardCharsets.UTF_8).split(Pattern.quote(","));
|
||||
SpecVersion sv = SpecVersion.parse(splitted[0]);
|
||||
|
||||
String id = splitted[1];
|
||||
|
|
|
@ -69,9 +69,9 @@ public final class JsonFormat implements EventFormat {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CloudEvent deserialize(byte[] event) throws EventDeserializationException {
|
||||
public CloudEvent deserialize(byte[] bytes) throws EventDeserializationException {
|
||||
try {
|
||||
return mapper.readValue(event, CloudEvent.class);
|
||||
return mapper.readValue(bytes, CloudEvent.class);
|
||||
} catch (IOException e) {
|
||||
throw new EventDeserializationException(e);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue