Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion api/src/main/java/io/cloudevents/CloudEventData.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@

/**
* Interface that defines a wrapper for CloudEvent data.
* <p>
* This interface can be overridden to include any type of data inside a {@link CloudEvent}, given it has a method to convert back to bytes.
*/
public interface CloudEventData {

/**
* @return this CloudEventData, represented as bytes. Note: this operation may be expensive, depending on the internal representation of data
* Returns the bytes representation of this data instance.
* <p>
* Note: depending on the implementation, this operation may be expensive.
*
* @return this data, represented as bytes.
*/
byte[] toBytes();

Expand Down
4 changes: 2 additions & 2 deletions api/src/main/java/io/cloudevents/CloudEventExtensions.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import java.util.Set;

/**
* The event extensions
* The event extensions.
* <p>
* Extensions values could be String/Number/Boolean
*/
Expand All @@ -34,7 +34,7 @@ public interface CloudEventExtensions {
* Get the extension attribute named {@code extensionName}
*
* @param extensionName the extension name
* @return the extension value or null if this instance doesn't contain such extension
* @return the extension value in one of the valid types String/Number/Boolean or null if this instance doesn't contain such extension
*/
@Nullable
Object getExtension(String extensionName);
Expand Down
8 changes: 4 additions & 4 deletions api/src/main/java/io/cloudevents/Extension.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@
public interface Extension {

/**
* Fill this materialized extension with values from a {@link CloudEventExtensions} implementation
* Fill this materialized extension with values from a {@link CloudEventExtensions} implementation.
*
* @param extensions
* @param extensions the extensions where to read from
*/
void readFrom(CloudEventExtensions extensions);

/**
* Get the attribute of extension named {@code key}
* Get the attribute of extension named {@code key}.
*
* @param key the name of the extension attribute
* @return the extension value
* @return the extension value in one of the valid types String/Number/Boolean
* @throws IllegalArgumentException if the key is unknown to this extension
*/
@Nullable
Expand Down
6 changes: 4 additions & 2 deletions api/src/main/java/io/cloudevents/SpecVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package io.cloudevents;

import io.cloudevents.rw.CloudEventRWException;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.*;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -62,7 +64,7 @@ public String toString() {
*
* @param sv String representing the spec version
* @return The parsed spec version
* @throws IllegalArgumentException When the spec version string is unrecognized
* @throws CloudEventRWException When the spec version string is unrecognized
*/
public static SpecVersion parse(String sv) {
switch (sv) {
Expand All @@ -71,7 +73,7 @@ public static SpecVersion parse(String sv) {
case "1.0":
return SpecVersion.V1;
default:
throw new IllegalArgumentException("Unrecognized SpecVersion " + sv);
throw CloudEventRWException.newInvalidSpecVersion(sv);
}
}

Expand Down
23 changes: 13 additions & 10 deletions api/src/main/java/io/cloudevents/rw/CloudEventAttributesWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,20 @@ public interface CloudEventAttributesWriter {
* Set attribute with type {@link String}. This setter should not be invoked for specversion, because the built Visitor already
* has the information through the {@link CloudEventWriterFactory}.
*
* @param name
* @param value
* @throws CloudEventRWException
* @param name name of the attribute
* @param value value of the attribute
* @return self
* @throws CloudEventRWException if anything goes wrong while writing this attribute.
*/
CloudEventAttributesWriter withAttribute(String name, @Nullable String value) throws CloudEventRWException;

/**
* Set attribute with type {@link URI}.
*
* @param name
* @param value
* @throws CloudEventRWException
* @param name name of the attribute
* @param value value of the attribute
* @throws CloudEventRWException if anything goes wrong while writing this attribute.
* @return self
*/
default CloudEventAttributesWriter withAttribute(String name, @Nullable URI value) throws CloudEventRWException {
return withAttribute(name, value == null ? null : value.toString());
Expand All @@ -52,12 +54,13 @@ default CloudEventAttributesWriter withAttribute(String name, @Nullable URI valu
/**
* Set attribute with type {@link OffsetDateTime} attribute.
*
* @param name
* @param value
* @throws CloudEventRWException
* @param name name of the attribute
* @param value value of the attribute
* @throws CloudEventRWException if anything goes wrong while writing this attribute.
* @return self
*/
default CloudEventAttributesWriter withAttribute(String name, @Nullable OffsetDateTime value) throws CloudEventRWException {
return withAttribute(name, value == null ? null : Time.writeTime(value));
return withAttribute(name, value == null ? null : Time.writeTime(name, value));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,20 @@ public interface CloudEventExtensionsWriter {
/**
* Set an extension with type {@link String}.
*
* @param name
* @param value
* @throws CloudEventRWException
* @param name name of the extension
* @param value value of the extension
* @return self
* @throws CloudEventRWException if anything goes wrong while writing this extension.
*/
CloudEventExtensionsWriter withExtension(String name, @Nullable String value) throws CloudEventRWException;

/**
* Set attribute with type {@link URI}.
*
* @param name
* @param value
* @throws CloudEventRWException
* @param name name of the extension
* @param value value of the extension
* @throws CloudEventRWException if anything goes wrong while writing this extension.
* @return self
*/
default CloudEventExtensionsWriter withExtension(String name, @Nullable Number value) throws CloudEventRWException {
return withExtension(name, value == null ? null : value.toString());
Expand All @@ -49,9 +51,10 @@ default CloudEventExtensionsWriter withExtension(String name, @Nullable Number v
/**
* Set attribute with type {@link Boolean} attribute.
*
* @param name
* @param value
* @throws CloudEventRWException
* @param name name of the extension
* @param value value of the extension
* @throws CloudEventRWException if anything goes wrong while writing this extension.
* @return self
*/
default CloudEventExtensionsWriter withExtension(String name, @Nullable Boolean value) throws CloudEventRWException {
return withExtension(name, value == null ? null : value.toString());
Expand Down
70 changes: 58 additions & 12 deletions api/src/main/java/io/cloudevents/rw/CloudEventRWException.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,64 @@

package io.cloudevents.rw;

/**
* This class is the exception Protocol Binding and Event Format implementers can use to signal errors while serializing/deserializing CloudEvent.
*/
public class CloudEventRWException extends RuntimeException {

/**
* The kind of error that happened while serializing/deserializing
*/
public enum CloudEventRWExceptionKind {
/**
* Spec version string is not recognized by this particular SDK version.
*/
INVALID_SPEC_VERSION,
/**
* The attribute name is not a valid/known context attribute.
*/
INVALID_ATTRIBUTE_NAME,
/**
* The extension name is not valid,
* because it doesn't follow the <a href="https://github.com/cloudevents/spec/blob/v1.0/spec.md#attribute-naming-convention">naming convention</a>
* enforced by the CloudEvents spec.
*/
INVALID_EXTENSION_NAME,
/**
* The attribute/extension type is not valid.
*/
INVALID_ATTRIBUTE_TYPE,
/**
* The attribute/extension value is not valid.
*/
INVALID_ATTRIBUTE_VALUE,
INVALID_EXTENSION_TYPE,
/**
* The data type is not valid.
*/
INVALID_DATA_TYPE,
/**
* Error while converting CloudEventData.
*/
DATA_CONVERSION,
/**
* Other error.
*/
OTHER
}

private final CloudEventRWExceptionKind kind;

public CloudEventRWException(CloudEventRWExceptionKind kind, Throwable cause) {
private CloudEventRWException(CloudEventRWExceptionKind kind, Throwable cause) {
super(cause);
this.kind = kind;
}

public CloudEventRWException(CloudEventRWExceptionKind kind, String message) {
private CloudEventRWException(CloudEventRWExceptionKind kind, String message) {
super(message);
this.kind = kind;
}

public CloudEventRWException(CloudEventRWExceptionKind kind, String message, Throwable cause) {
private CloudEventRWException(CloudEventRWExceptionKind kind, String message, Throwable cause) {
super(message, cause);
this.kind = kind;
}
Expand All @@ -52,7 +85,7 @@ public CloudEventRWExceptionKind getKind() {

public static CloudEventRWException newInvalidSpecVersion(String specVersion) {
return new CloudEventRWException(
CloudEventRWExceptionKind.INVALID_ATTRIBUTE_TYPE,
CloudEventRWExceptionKind.INVALID_SPEC_VERSION,
"Invalid specversion: " + specVersion
);
}
Expand All @@ -64,32 +97,45 @@ public static CloudEventRWException newInvalidAttributeName(String attributeName
);
}

public static CloudEventRWException newInvalidExtensionName(String extensionName) {
return new CloudEventRWException(
CloudEventRWExceptionKind.INVALID_EXTENSION_NAME,
"Invalid extensions name: " + extensionName
);
}

public static CloudEventRWException newInvalidAttributeType(String attributeName, Class<?> clazz) {
return new CloudEventRWException(
CloudEventRWExceptionKind.INVALID_ATTRIBUTE_TYPE,
"Invalid attribute type for \"" + attributeName + "\": " + clazz.getCanonicalName()
"Invalid attribute/extension type for \"" + attributeName + "\": " + clazz.getCanonicalName()
);
}

public static CloudEventRWException newInvalidAttributeValue(String attributeName, Object value, Throwable cause) {
return new CloudEventRWException(
CloudEventRWExceptionKind.INVALID_ATTRIBUTE_VALUE,
"Invalid attribute value for \"" + attributeName + "\": " + value,
"Invalid attribute/extension value for \"" + attributeName + "\": " + value,
cause
);
}

public static CloudEventRWException newInvalidExtensionType(String extensionName, Class<?> clazz) {
public static CloudEventRWException newInvalidDataType(String actual, String... allowed) {
String message;
if (allowed.length == 0) {
message = "Invalid data type: " + actual;
} else {
message = "Invalid data type: " + actual + ". Allowed: " + String.join(", ", allowed);
}
return new CloudEventRWException(
CloudEventRWExceptionKind.INVALID_EXTENSION_TYPE,
"Invalid extension type for \"" + extensionName + "\": " + clazz.getCanonicalName()
CloudEventRWExceptionKind.INVALID_DATA_TYPE,
message
);
}

public static CloudEventRWException newDataConversion(Throwable cause, String to) {
public static CloudEventRWException newDataConversion(Throwable cause, String from, String to) {
return new CloudEventRWException(
CloudEventRWExceptionKind.DATA_CONVERSION,
"Error while trying to convert data to " + to,
"Error while trying to convert data from " + from + " to " + to,
cause
);
}
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/io/cloudevents/rw/CloudEventReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public interface CloudEventReader {
* Visit self using the provided visitor factory
*
* @param writerFactory a factory that generates a visitor starting from the SpecVersion of the event
* @throws CloudEventRWException if something went wrong during the visit.
* @throws CloudEventRWException if something went wrong during the read.
*/
default <V extends CloudEventWriter<R>, R> R read(CloudEventWriterFactory<V, R> writerFactory) throws CloudEventRWException {
return read(writerFactory, null);
Expand Down
4 changes: 3 additions & 1 deletion api/src/main/java/io/cloudevents/rw/CloudEventWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,16 @@ public interface CloudEventWriter<R> extends CloudEventAttributesWriter, CloudEv
* End the visit with a data field
*
* @return an eventual return value
* @throws CloudEventRWException if the message writer cannot be ended.
*/
R end(CloudEventData data) throws CloudEventRWException;

/**
* End the visit
*
* @return an eventual return value
* @throws CloudEventRWException if the message writer cannot be ended.
*/
R end();
R end() throws CloudEventRWException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ public interface CloudEventWriterFactory<V extends CloudEventWriter<R>, R> {
/**
* Create a {@link CloudEventWriter} starting from the provided {@link SpecVersion}
*
* @param version
* @return
* @param version the spec version to create the writer
* @return the new writer
* @throws CloudEventRWException if the spec version is invalid or the writer cannot be instantiated.
*/
V create(SpecVersion version);
V create(SpecVersion version) throws CloudEventRWException;
}
Loading