Changes to support the new signature

Signed-off-by: Fabio José <fabiojose@gmail.com>
This commit is contained in:
Fabio José 2019-08-21 11:03:52 -03:00
parent 024e7b18fe
commit afc6f3deef
2 changed files with 89 additions and 67 deletions

View File

@ -13,13 +13,18 @@ import javax.validation.ConstraintViolation;
import javax.validation.Validation; import javax.validation.Validation;
import javax.validation.Validator; import javax.validation.Validator;
import io.cloudevents.CloudEvent;
import io.cloudevents.ExtensionFormat;
import io.cloudevents.fun.EventBuilder;
/** /**
* CloudEvent instances builder * CloudEvent instances builder
* *
* @author fabiojose * @author fabiojose
* *
*/ */
public class CloudEventBuilder<T> { public class CloudEventBuilder<T> implements EventBuilder<T, AttributesImpl> {
private static Validator VALIDATOR;
private static final String SPEC_VERSION = "0.2"; private static final String SPEC_VERSION = "0.2";
private static final String MESSAGE_SEPARATOR = ", "; private static final String MESSAGE_SEPARATOR = ", ";
@ -37,23 +42,65 @@ public class CloudEventBuilder<T> {
private final Set<ExtensionFormat> extensions = new HashSet<>(); private final Set<ExtensionFormat> extensions = new HashSet<>();
private Validator getValidator() { private static Validator getValidator() {
return Validation.buildDefaultValidatorFactory().getValidator(); if(null== VALIDATOR) {
VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();
}
return VALIDATOR;
} }
/** /**
* *
* @return An new {@link CloudEvent} immutable instance * @param <T> the type of 'data'
* @param data the value of data
* @param attributes the context attributes
* @return An new {@link CloudEventImpl} immutable instance
* @throws IllegalStateException When there are specification constraints * @throws IllegalStateException When there are specification constraints
* violations * violations
*/ */
public CloudEvent<T> build() { public static <T> CloudEventImpl<T> of(T data, AttributesImpl attributes) {
CloudEvent<T> event = new CloudEvent<>(id, source, SPEC_VERSION, type, CloudEventBuilder<T> builder = new CloudEventBuilder<T>()
time, schemaurl, contenttype, data, extensions); .withId(attributes.getId())
.withSource(attributes.getSource())
.withType(attributes.getType());
Set<ConstraintViolation<CloudEvent<T>>> violations = attributes.getTime().ifPresent((time) -> {
builder.withTime(time);
});
attributes.getSchemaurl().ifPresent((schema) -> {
builder.withSchemaurl(schema);
});
attributes.getContenttype().ifPresent(contenttype -> {
builder.withContenttype(contenttype);
});
return builder.withData(data).build();
}
@Override
public CloudEvent<AttributesImpl, T> build(T data, AttributesImpl attributes){
return CloudEventBuilder.<T>of(data, attributes);
}
/**
*
* @return An new {@link CloudEventImpl} immutable instance
* @throws IllegalStateException When there are specification constraints
* violations
*/
public CloudEventImpl<T> build() {
AttributesImpl attributes = new AttributesImpl(type, SPEC_VERSION,
source, id, time, schemaurl, contenttype);
CloudEventImpl<T> event = new CloudEventImpl<>(attributes, data, extensions);
Set<ConstraintViolation<Object>> violations =
getValidator().validate(event); getValidator().validate(event);
violations.addAll(getValidator().validate(event.getAttributes()));
final String errs = final String errs =
violations.stream() violations.stream()
.map(v -> format(MESSAGE, v.getPropertyPath(), v.getMessage())) .map(v -> format(MESSAGE, v.getPropertyPath(), v.getMessage()))

View File

@ -8,63 +8,42 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.annotation.JsonUnwrapped;
import io.cloudevents.json.ZonedDateTimeDeserializer; import io.cloudevents.CloudEvent;
import io.cloudevents.ExtensionFormat;
/** /**
* The event implementation
* *
* @author fabiojose * @author fabiojose
* *
* Implemented using immutable data structure.
*
*/ */
@JsonInclude(value = Include.NON_ABSENT) @JsonInclude(value = Include.NON_ABSENT)
public class CloudEvent<T> { public class CloudEventImpl<T> implements CloudEvent<AttributesImpl, T> {
@NotBlank
private final String type;
@NotBlank
@Pattern(regexp = "0\\.2")
private final String specversion;
@JsonIgnore
@NotNull @NotNull
private final URI source; private final AttributesImpl attributes;
@NotBlank
private final String id;
private final ZonedDateTime time;
private final URI schemaurl;
private final String contenttype;
private final T data; private final T data;
@NotNull
private final Map<String, Object> extensions; private final Map<String, Object> extensions;
CloudEvent(String id, URI source, String specversion, String type, CloudEventImpl(AttributesImpl attributes, T data,
ZonedDateTime time, URI schemaurl, String contenttype, Set<ExtensionFormat> extensions) {
T data, Set<ExtensionFormat> extensions) {
this.id = id; this.attributes = attributes;
this.source = source;
this.specversion = specversion;
this.type = type;
this.time = time;
this.schemaurl = schemaurl;
this.contenttype = contenttype;
this.data = data; this.data = data;
@ -75,45 +54,41 @@ public class CloudEvent<T> {
ExtensionFormat::getExtension)); ExtensionFormat::getExtension));
} }
public String getType() { @JsonUnwrapped
return type; @Override
} public AttributesImpl getAttributes() {
public String getId() { return this.attributes;
return id;
}
public String getSpecversion() {
return specversion;
}
public URI getSource() {
return source;
} }
@JsonDeserialize(using = ZonedDateTimeDeserializer.class) /**
public Optional<ZonedDateTime> getTime() { * The event payload. The payload depends on the eventType,
return Optional.ofNullable(time); * schemaURL and eventTypeVersion, the payload is encoded into
} * a media format which is specified by the contentType attribute
public Optional<URI> getSchemaurl() { * (e.g. application/json).
return Optional.ofNullable(schemaurl); */
}
public Optional<String> getContenttype() {
return Optional.ofNullable(contenttype);
}
public Optional<T> getData() { public Optional<T> getData() {
return Optional.ofNullable(data); return Optional.ofNullable(data);
} }
@JsonAnyGetter @JsonAnyGetter
Map<String, Object> getExtensions() { public Map<String, Object> getExtensions() {
return Collections.unmodifiableMap(extensions); return Collections.unmodifiableMap(extensions);
} }
/**
* The unique method that allows mutation. Used by
* Jackson Framework to inject the extensions.
*
* @param name Extension name
* @param value Extension value
*/
@JsonAnySetter @JsonAnySetter
void addExtension(String name, Object value) { void addExtension(String name, Object value) {
extensions.put(name, value); extensions.put(name, value);
} }
@JsonCreator @JsonCreator
public static <T> CloudEvent<T> build( public static <T> CloudEventImpl<T> build(
@JsonProperty("id") String id, @JsonProperty("id") String id,
@JsonProperty("source") URI source, @JsonProperty("source") URI source,
@JsonProperty("specversion") String specversion, @JsonProperty("specversion") String specversion,