Completed implementation of message interfaces for events.
Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>
This commit is contained in:
parent
223d786a3f
commit
8f1b8d2da9
|
@ -16,6 +16,9 @@
|
|||
package io.cloudevents;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import io.cloudevents.format.EventFormat;
|
||||
import io.cloudevents.message.BinaryMessage;
|
||||
import io.cloudevents.message.StructuredMessage;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
@ -58,6 +61,10 @@ public interface CloudEvent {
|
|||
|
||||
CloudEvent toV1();
|
||||
|
||||
BinaryMessage asBinaryMessage();
|
||||
|
||||
StructuredMessage asStructuredMessage(EventFormat format);
|
||||
|
||||
static io.cloudevents.v1.CloudEventBuilder buildV1() {
|
||||
return new io.cloudevents.v1.CloudEventBuilder();
|
||||
}
|
||||
|
|
|
@ -1,35 +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.fun;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.cloudevents.Attributes;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface AttributeMarshaller<A extends Attributes> {
|
||||
|
||||
/**
|
||||
* Marshals the {@link Attributes} to map of attributes.
|
||||
*/
|
||||
Map<String, String> marshal(A attributes);
|
||||
|
||||
}
|
|
@ -1,35 +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.fun;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.cloudevents.Attributes;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface AttributeUnmarshaller<A extends Attributes> {
|
||||
|
||||
/**
|
||||
* Unmarshals the map of CloudEvent attributes into actual ones
|
||||
*/
|
||||
A unmarshal(Map<String, String> attributes);
|
||||
|
||||
}
|
|
@ -1,35 +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.fun;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BinaryFormatAttributeMapper {
|
||||
|
||||
/**
|
||||
* Maps the 'headers' of binary format into CloudEvent attributes
|
||||
* @param headers
|
||||
* @return
|
||||
*/
|
||||
Map<String, String> map(Map<String, Object> headers);
|
||||
|
||||
}
|
|
@ -1,40 +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.fun;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
* @param <P> The payload type
|
||||
* @param <T> The 'data' type
|
||||
* @param <H> The type of headers value
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DataMarshaller<P, T, H> {
|
||||
|
||||
/**
|
||||
* Marshals the 'data' into payload
|
||||
* @param data
|
||||
* @param headers
|
||||
* @return
|
||||
* @throws RuntimeException When something bad happens during the marshal process
|
||||
*/
|
||||
P marshal(T data, Map<String, H> headers) throws RuntimeException;
|
||||
|
||||
}
|
|
@ -1,40 +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.fun;
|
||||
|
||||
import io.cloudevents.Attributes;
|
||||
|
||||
/**
|
||||
* For the 'data' unmarshalling.
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
* @param <P> The payload type
|
||||
* @param <T> The 'data' type
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface DataUnmarshaller<P, T, A extends Attributes> {
|
||||
|
||||
/**
|
||||
* Unmarshals the payload into 'data'
|
||||
* @param payload
|
||||
* @param attributes
|
||||
* @return
|
||||
* @throws RuntimeException If something bad happens during the umarshal
|
||||
*/
|
||||
T unmarshal(P payload, A attributes);
|
||||
|
||||
}
|
|
@ -1,35 +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.fun;
|
||||
|
||||
import io.cloudevents.Attributes;
|
||||
import io.cloudevents.CloudEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface EnvelopeMarshaller<A extends Attributes, T, P> {
|
||||
|
||||
/**
|
||||
* Marshals a CloudEvent instance into the wire format
|
||||
* @param event The CloudEvents instance
|
||||
* @return the wire format
|
||||
*/
|
||||
P marshal(CloudEvent<A, T> event);
|
||||
}
|
|
@ -1,42 +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.fun;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.cloudevents.Attributes;
|
||||
import io.cloudevents.CloudEvent;
|
||||
import io.cloudevents.extensions.ExtensionFormat;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
public interface EnvelopeUnmarshaller<A extends Attributes, T, P> {
|
||||
|
||||
/**
|
||||
* Unmarshals the payload into {@link CloudEvent} instance implementation
|
||||
*
|
||||
* @param payload The envelope payload
|
||||
* @param extensions Supplies a list of {@link ExtensionFormat}
|
||||
* @return The unmarshalled impl of CloudEvent
|
||||
*/
|
||||
CloudEvent<A, T> unmarshal(P payload,
|
||||
Supplier<List<ExtensionFormat>> extensions);
|
||||
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package io.cloudevents.fun;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import io.cloudevents.Attributes;
|
||||
import io.cloudevents.CloudEvent;
|
||||
import io.cloudevents.extensions.ExtensionFormat;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExtensionFormatAccessor<A extends Attributes, T> {
|
||||
|
||||
/**
|
||||
* To get access to the internal collection of {@link ExtensionFormat} inside
|
||||
* the {@link CloudEvent} implementation
|
||||
*
|
||||
* @param cloudEvent
|
||||
* @return
|
||||
*/
|
||||
Collection<ExtensionFormat> extensionsOf(CloudEvent<A, T> cloudEvent);
|
||||
}
|
|
@ -1,38 +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.fun;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import io.cloudevents.extensions.ExtensionFormat;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExtensionMarshaller {
|
||||
|
||||
/**
|
||||
* Marshals a collections of {@link ExtensionFormat} into map
|
||||
* @param extensions
|
||||
* @return
|
||||
*/
|
||||
Map<String, String> marshal(Collection<ExtensionFormat> extensions);
|
||||
|
||||
}
|
|
@ -1,38 +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.fun;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import io.cloudevents.extensions.ExtensionFormat;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExtensionUmarshaller {
|
||||
|
||||
/**
|
||||
* Unmarshals the map of extensions into {@link ExtensionFormat}
|
||||
* @param extensions
|
||||
* @return
|
||||
*/
|
||||
Optional<ExtensionFormat> unmarshal(Map<String, String> extensions);
|
||||
|
||||
}
|
|
@ -1,34 +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.fun;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface FormatExtensionMapper {
|
||||
|
||||
/**
|
||||
* Maps the 'headers' of binary format into extensions
|
||||
* @param headers
|
||||
*/
|
||||
Map<String, String> map(Map<String, Object> headers);
|
||||
|
||||
}
|
|
@ -1,38 +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.fun;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
* @param <H> The header value type
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface FormatHeaderMapper<H> {
|
||||
|
||||
/**
|
||||
* Maps the 'attributes' and 'extensions' of CloudEvent envelop to
|
||||
* 'headers' of binary format
|
||||
* @param attributes
|
||||
* @return
|
||||
*/
|
||||
Map<String, H> map(Map<String, String> attributes,
|
||||
Map<String, String> extensions);
|
||||
|
||||
}
|
|
@ -1,38 +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.fun;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.cloudevents.format.Wire;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fabiojose
|
||||
*
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface WireBuilder<P, K, V> {
|
||||
|
||||
/**
|
||||
* Builds a wire format
|
||||
* @param payload
|
||||
* @param headers
|
||||
* @return
|
||||
*/
|
||||
Wire<P, K, V> build(P payload, Map<K, V> headers);
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package io.cloudevents.impl;
|
||||
|
||||
import io.cloudevents.Attributes;
|
||||
import io.cloudevents.message.BinaryMessageAttributes;
|
||||
|
||||
public interface AttributesInternal extends Attributes, BinaryMessageAttributes { }
|
|
@ -7,9 +7,11 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|||
import io.cloudevents.Attributes;
|
||||
import io.cloudevents.CloudEvent;
|
||||
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.message.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -17,15 +19,15 @@ import java.util.*;
|
|||
|
||||
@JsonSerialize(using = CloudEventSerializer.class)
|
||||
@JsonDeserialize(using = CloudEventDeserializer.class)
|
||||
public final class CloudEventImpl implements CloudEvent {
|
||||
public final class CloudEventImpl implements CloudEvent, BinaryMessage {
|
||||
|
||||
private final Attributes attributes;
|
||||
private final AttributesInternal attributes;
|
||||
private final Object data;
|
||||
private final Map<String, Object> extensions;
|
||||
|
||||
public CloudEventImpl(Attributes attributes, Object data, Map<String, Object> extensions) {
|
||||
protected CloudEventImpl(Attributes attributes, Object data, Map<String, Object> extensions) {
|
||||
Objects.requireNonNull(attributes);
|
||||
this.attributes = attributes;
|
||||
this.attributes = (AttributesInternal) attributes;
|
||||
this.data = data;
|
||||
this.extensions = extensions != null ? extensions : new HashMap<>();
|
||||
}
|
||||
|
@ -130,4 +132,48 @@ public final class CloudEventImpl implements CloudEvent {
|
|||
protected Object getRawData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Message impl
|
||||
|
||||
public BinaryMessage asBinaryMessage() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public StructuredMessage asStructuredMessage(EventFormat format) {
|
||||
CloudEvent ev = this;
|
||||
// TODO This sucks, will improve later
|
||||
return new StructuredMessage() {
|
||||
@Override
|
||||
public <T> T visit(StructuredMessageVisitor<T> visitor) throws MessageVisitException, IllegalStateException {
|
||||
return visitor.setEvent(format, format.serializeToBytes(ev));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BinaryMessageVisitor<V>, V> V visit(BinaryMessageVisitorFactory<T, V> visitorFactory) throws MessageVisitException, IllegalStateException {
|
||||
BinaryMessageVisitor<V> visitor = visitorFactory.apply(this.attributes.getSpecVersion());
|
||||
this.attributes.visit(visitor);
|
||||
|
||||
// TODO to be improved
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO to be improved to remove the allocation of useless optional
|
||||
if (this.data != null) {
|
||||
visitor.setBody(this.getDataAsBytes().get());
|
||||
}
|
||||
|
||||
return visitor.end();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,11 @@ package io.cloudevents.message;
|
|||
public class MessageVisitException extends RuntimeException {
|
||||
|
||||
public enum MessageVisitExceptionKind {
|
||||
INVALID_ATTRIBUTE_TYPE,
|
||||
INVALID_SPEC_VERSION,
|
||||
INVALID_ATTRIBUTE_NAME,
|
||||
INVALID_ATTRIBUTE_TYPE,
|
||||
INVALID_ATTRIBUTE_VALUE,
|
||||
INVALID_EXTENSION_TYPE,
|
||||
}
|
||||
|
||||
private MessageVisitExceptionKind kind;
|
||||
|
@ -23,13 +26,6 @@ public class MessageVisitException extends RuntimeException {
|
|||
return kind;
|
||||
}
|
||||
|
||||
public static MessageVisitException newInvalidAttributeType(String attributeName, Class<?> clazz) {
|
||||
return new MessageVisitException(
|
||||
MessageVisitExceptionKind.INVALID_ATTRIBUTE_TYPE,
|
||||
"Invalid attribute type for " + attributeName + ": " + clazz.getCanonicalName()
|
||||
);
|
||||
}
|
||||
|
||||
public static MessageVisitException newInvalidSpecVersion(String specVersion) {
|
||||
return new MessageVisitException(
|
||||
MessageVisitExceptionKind.INVALID_ATTRIBUTE_TYPE,
|
||||
|
@ -37,5 +33,32 @@ public class MessageVisitException extends RuntimeException {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
public static MessageVisitException newInvalidAttributeName(String attributeName) {
|
||||
return new MessageVisitException(
|
||||
MessageVisitExceptionKind.INVALID_ATTRIBUTE_NAME,
|
||||
"Invalid attribute: " + attributeName
|
||||
);
|
||||
}
|
||||
|
||||
public static MessageVisitException newInvalidAttributeType(String attributeName, Class<?> clazz) {
|
||||
return new MessageVisitException(
|
||||
MessageVisitExceptionKind.INVALID_ATTRIBUTE_TYPE,
|
||||
"Invalid attribute type for " + attributeName + ": " + clazz.getCanonicalName()
|
||||
);
|
||||
}
|
||||
|
||||
public static MessageVisitException newInvalidAttributeValue(String attributeName, Object value, Throwable cause) {
|
||||
return new MessageVisitException(
|
||||
MessageVisitExceptionKind.INVALID_ATTRIBUTE_VALUE,
|
||||
"Invalid attribute value for " + attributeName + ": " + value,
|
||||
cause
|
||||
);
|
||||
}
|
||||
|
||||
public static MessageVisitException newInvalidExtensionType(String extensionName, Class<?> clazz) {
|
||||
return new MessageVisitException(
|
||||
MessageVisitExceptionKind.INVALID_EXTENSION_TYPE,
|
||||
"Invalid extension type for " + extensionName + ": " + clazz.getCanonicalName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
package io.cloudevents.types;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
||||
public final class Time {
|
||||
public static final DateTimeFormatter RFC3339_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
|
||||
|
||||
public static ZonedDateTime parseTime(String time) throws DateTimeParseException {
|
||||
return ZonedDateTime.parse(time, RFC3339_DATE_FORMAT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ package io.cloudevents.v03;
|
|||
|
||||
import io.cloudevents.Attributes;
|
||||
import io.cloudevents.SpecVersion;
|
||||
import io.cloudevents.message.BinaryMessageAttributes;
|
||||
import io.cloudevents.impl.AttributesInternal;
|
||||
import io.cloudevents.message.BinaryMessageAttributesVisitor;
|
||||
import io.cloudevents.message.MessageVisitException;
|
||||
|
||||
|
@ -32,7 +32,7 @@ import java.util.Optional;
|
|||
* @author slinkydeveloper
|
||||
*
|
||||
*/
|
||||
public class AttributesImpl implements Attributes, BinaryMessageAttributes {
|
||||
public final class AttributesImpl implements AttributesInternal {
|
||||
|
||||
private final String id;
|
||||
private final URI source;
|
||||
|
|
|
@ -19,9 +19,12 @@ import io.cloudevents.Attributes;
|
|||
import io.cloudevents.CloudEvent;
|
||||
import io.cloudevents.impl.BaseCloudEventBuilder;
|
||||
import io.cloudevents.message.MessageVisitException;
|
||||
import io.cloudevents.types.Time;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -112,16 +115,63 @@ public final class CloudEventBuilder extends BaseCloudEventBuilder<CloudEventBui
|
|||
|
||||
@Override
|
||||
public void setAttribute(String name, String value) throws MessageVisitException {
|
||||
|
||||
switch (name) {
|
||||
case "id":
|
||||
withId(value);
|
||||
return;
|
||||
case "source":
|
||||
try {
|
||||
withSource(new URI(value));
|
||||
} catch (URISyntaxException e) {
|
||||
throw MessageVisitException.newInvalidAttributeValue("source", value, e);
|
||||
}
|
||||
return;
|
||||
case "type":
|
||||
withType(value);
|
||||
return;
|
||||
case "datacontenttype":
|
||||
withDataContentType(value);
|
||||
return;
|
||||
case "schemaurl":
|
||||
try {
|
||||
withSchemaUrl(new URI(value));
|
||||
} catch (URISyntaxException e) {
|
||||
throw MessageVisitException.newInvalidAttributeValue("schemaurl", value, e);
|
||||
}
|
||||
return;
|
||||
case "subject":
|
||||
withSubject(value);
|
||||
return;
|
||||
case "time":
|
||||
try {
|
||||
withTime(Time.parseTime(value));
|
||||
} catch (DateTimeParseException e) {
|
||||
throw MessageVisitException.newInvalidAttributeValue("time", value, e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw MessageVisitException.newInvalidAttributeName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, URI value) throws MessageVisitException {
|
||||
|
||||
switch (name) {
|
||||
case "source":
|
||||
withSource(value);
|
||||
return;
|
||||
case "schemaurl":
|
||||
withDataSchema(value);
|
||||
return;
|
||||
}
|
||||
throw MessageVisitException.newInvalidAttributeType(name, URI.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, ZonedDateTime value) throws MessageVisitException {
|
||||
|
||||
if ("time".equals(name)) {
|
||||
withTime(value);
|
||||
return;
|
||||
}
|
||||
throw MessageVisitException.newInvalidAttributeType(name, ZonedDateTime.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,4 +44,9 @@ public enum ContextAttributes {
|
|||
public static ContextAttributes parse(String value) {
|
||||
return ContextAttributes.valueOf(value.toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ package io.cloudevents.v1;
|
|||
|
||||
import io.cloudevents.Attributes;
|
||||
import io.cloudevents.SpecVersion;
|
||||
import io.cloudevents.message.BinaryMessageAttributes;
|
||||
import io.cloudevents.impl.AttributesInternal;
|
||||
import io.cloudevents.message.BinaryMessageAttributesVisitor;
|
||||
import io.cloudevents.message.MessageVisitException;
|
||||
|
||||
|
@ -31,7 +31,7 @@ import java.util.Optional;
|
|||
* @author slinkydeveloper
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AttributesImpl implements Attributes, BinaryMessageAttributes {
|
||||
public final class AttributesImpl implements AttributesInternal {
|
||||
|
||||
private final String id;
|
||||
private final URI source;
|
||||
|
|
|
@ -4,9 +4,12 @@ import io.cloudevents.Attributes;
|
|||
import io.cloudevents.CloudEvent;
|
||||
import io.cloudevents.impl.BaseCloudEventBuilder;
|
||||
import io.cloudevents.message.MessageVisitException;
|
||||
import io.cloudevents.types.Time;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -90,16 +93,63 @@ public final class CloudEventBuilder extends BaseCloudEventBuilder<CloudEventBui
|
|||
|
||||
@Override
|
||||
public void setAttribute(String name, String value) throws MessageVisitException {
|
||||
|
||||
switch (name) {
|
||||
case "id":
|
||||
withId(value);
|
||||
return;
|
||||
case "source":
|
||||
try {
|
||||
withSource(new URI(value));
|
||||
} catch (URISyntaxException e) {
|
||||
throw MessageVisitException.newInvalidAttributeValue("source", value, e);
|
||||
}
|
||||
return;
|
||||
case "type":
|
||||
withType(value);
|
||||
return;
|
||||
case "datacontenttype":
|
||||
withDataContentType(value);
|
||||
return;
|
||||
case "dataschema":
|
||||
try {
|
||||
withDataSchema(new URI(value));
|
||||
} catch (URISyntaxException e) {
|
||||
throw MessageVisitException.newInvalidAttributeValue("dataschema", value, e);
|
||||
}
|
||||
return;
|
||||
case "subject":
|
||||
withSubject(value);
|
||||
return;
|
||||
case "time":
|
||||
try {
|
||||
withTime(Time.parseTime(value));
|
||||
} catch (DateTimeParseException e) {
|
||||
throw MessageVisitException.newInvalidAttributeValue("time", value, e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw MessageVisitException.newInvalidAttributeName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, URI value) throws MessageVisitException {
|
||||
|
||||
switch (name) {
|
||||
case "source":
|
||||
withSource(value);
|
||||
return;
|
||||
case "dataschema":
|
||||
withDataSchema(value);
|
||||
return;
|
||||
}
|
||||
throw MessageVisitException.newInvalidAttributeType(name, URI.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, ZonedDateTime value) throws MessageVisitException {
|
||||
|
||||
if ("time".equals(name)) {
|
||||
withTime(value);
|
||||
return;
|
||||
}
|
||||
throw MessageVisitException.newInvalidAttributeType(name, ZonedDateTime.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,11 +35,15 @@ public enum ContextAttributes {
|
|||
TIME;
|
||||
public static final List<String> VALUES =
|
||||
Arrays.stream(ContextAttributes.values())
|
||||
.map(Enum::name)
|
||||
.map(String::toLowerCase)
|
||||
.map(ContextAttributes::toString)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
public static ContextAttributes parse(String value) {
|
||||
return ContextAttributes.valueOf(value.toUpperCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue