Support for data_base64 in json message format
Signed-off-by: Fabio José <fabiojose@gmail.com>
This commit is contained in:
parent
9e97e10ac6
commit
59962ba689
|
@ -158,7 +158,11 @@ public class CloudEventBuilder<T> implements
|
||||||
datacontenttype, dataschema, subject, time);
|
datacontenttype, dataschema, subject, time);
|
||||||
|
|
||||||
CloudEventImpl<T> cloudEvent =
|
CloudEventImpl<T> cloudEvent =
|
||||||
new CloudEventImpl<T>(attributes, data, extensions);
|
new CloudEventImpl<T>(attributes, data, extensions);
|
||||||
|
|
||||||
|
if(data instanceof byte[]) {
|
||||||
|
cloudEvent.setDataBase64((byte[])data);
|
||||||
|
}
|
||||||
|
|
||||||
Set<ConstraintViolation<Object>> violations =
|
Set<ConstraintViolation<Object>> violations =
|
||||||
getValidator().validate(cloudEvent);
|
getValidator().validate(cloudEvent);
|
||||||
|
|
|
@ -18,6 +18,7 @@ package io.cloudevents.v1;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -25,14 +26,15 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||||
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.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.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
|
||||||
|
|
||||||
import io.cloudevents.CloudEvent;
|
import io.cloudevents.CloudEvent;
|
||||||
import io.cloudevents.extensions.ExtensionFormat;
|
import io.cloudevents.extensions.ExtensionFormat;
|
||||||
|
@ -46,12 +48,20 @@ import io.cloudevents.extensions.InMemoryFormat;
|
||||||
@JsonInclude(value = Include.NON_ABSENT)
|
@JsonInclude(value = Include.NON_ABSENT)
|
||||||
public class CloudEventImpl<T> implements CloudEvent<AttributesImpl, T> {
|
public class CloudEventImpl<T> implements CloudEvent<AttributesImpl, T> {
|
||||||
|
|
||||||
|
public static final String EVENT_DATA_FIELD = "data";
|
||||||
|
public static final String EVENT_DATA_BASE64_FILED = "data_base64";
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@NotNull
|
@NotNull
|
||||||
private final AttributesImpl attributes;
|
private final AttributesImpl attributes;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
private final T data;
|
private final T data;
|
||||||
|
|
||||||
|
//To use with json binary data
|
||||||
|
@JsonIgnore
|
||||||
|
private byte[] dataBase64;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Map<String, Object> extensions;
|
private final Map<String, Object> extensions;
|
||||||
|
|
||||||
|
@ -77,6 +87,14 @@ public class CloudEventImpl<T> implements CloudEvent<AttributesImpl, T> {
|
||||||
return extensionsFormats;
|
return extensionsFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To handle the JSON base64 serialization
|
||||||
|
* @param data The byte array to encode as base64
|
||||||
|
*/
|
||||||
|
void setDataBase64(byte[] data) {
|
||||||
|
this.dataBase64 = data;
|
||||||
|
}
|
||||||
|
|
||||||
@JsonUnwrapped
|
@JsonUnwrapped
|
||||||
@Override
|
@Override
|
||||||
public AttributesImpl getAttributes() {
|
public AttributesImpl getAttributes() {
|
||||||
|
@ -91,7 +109,16 @@ public class CloudEventImpl<T> implements CloudEvent<AttributesImpl, T> {
|
||||||
@JsonAnyGetter
|
@JsonAnyGetter
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getExtensions() {
|
public Map<String, Object> getExtensions() {
|
||||||
return Collections.unmodifiableMap(extensions);
|
Map<String, Object> result = new HashMap<>(extensions);
|
||||||
|
|
||||||
|
if(null== dataBase64) {
|
||||||
|
if(null!= data) {
|
||||||
|
result.put(EVENT_DATA_FIELD, data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.put(EVENT_DATA_BASE64_FILED, dataBase64);
|
||||||
|
}
|
||||||
|
return Collections.unmodifiableMap(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,7 +146,9 @@ public class CloudEventImpl<T> implements CloudEvent<AttributesImpl, T> {
|
||||||
@JsonProperty("dataschema") URI dataschema,
|
@JsonProperty("dataschema") URI dataschema,
|
||||||
@JsonProperty("subject") String subject,
|
@JsonProperty("subject") String subject,
|
||||||
@JsonProperty("time") ZonedDateTime time,
|
@JsonProperty("time") ZonedDateTime time,
|
||||||
@JsonProperty("data") T data){
|
@JsonProperty("data")
|
||||||
|
@JsonAlias("data_base64")
|
||||||
|
T data){
|
||||||
|
|
||||||
return CloudEventBuilder.<T>builder()
|
return CloudEventBuilder.<T>builder()
|
||||||
.withId(id)
|
.withId(id)
|
||||||
|
|
|
@ -22,6 +22,8 @@ import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -281,4 +283,38 @@ public class CloudEventJacksonTest {
|
||||||
assertEquals(expected.getWow(), ce.getData().get().getWow());
|
assertEquals(expected.getWow(), ce.getData().get().getWow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_marshall_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<byte[]> event =
|
||||||
|
CloudEventBuilder.<byte[]>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())
|
||||||
|
.withData(data)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// act
|
||||||
|
String encoded = Json.encode(event);
|
||||||
|
|
||||||
|
// assert
|
||||||
|
assertTrue(encoded.contains("\"data_base64\""));
|
||||||
|
assertTrue(encoded.contains("\"" + expected +"\""));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,59 +38,6 @@ import io.cloudevents.v1.http.Marshallers;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class HTTPStructuredMarshallerTest {
|
public class HTTPStructuredMarshallerTest {
|
||||||
|
|
||||||
@Test
|
|
||||||
public void should_marshal_all_as_json() {
|
|
||||||
// setup
|
|
||||||
String expected = "{\"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> 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\":\"1.0\",\"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
|
@Test
|
||||||
public void should_headers_have_content_type() {
|
public void should_headers_have_content_type() {
|
||||||
|
|
Loading…
Reference in New Issue