Support for data_base64 in json message format

Signed-off-by: Fabio José <fabiojose@gmail.com>
This commit is contained in:
Fabio José 2019-10-26 17:29:57 -03:00
parent 9e97e10ac6
commit 59962ba689
4 changed files with 73 additions and 57 deletions

View File

@ -158,7 +158,11 @@ public class CloudEventBuilder<T> implements
datacontenttype, dataschema, subject, time);
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 =
getValidator().validate(cloudEvent);

View File

@ -18,6 +18,7 @@ package io.cloudevents.v1;
import java.net.URI;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@ -25,14 +26,15 @@ import java.util.stream.Collectors;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import io.cloudevents.CloudEvent;
import io.cloudevents.extensions.ExtensionFormat;
@ -46,12 +48,20 @@ import io.cloudevents.extensions.InMemoryFormat;
@JsonInclude(value = Include.NON_ABSENT)
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
@NotNull
private final AttributesImpl attributes;
@JsonIgnore
private final T data;
//To use with json binary data
@JsonIgnore
private byte[] dataBase64;
@NotNull
private final Map<String, Object> extensions;
@ -77,6 +87,14 @@ public class CloudEventImpl<T> implements CloudEvent<AttributesImpl, T> {
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
@Override
public AttributesImpl getAttributes() {
@ -91,7 +109,16 @@ public class CloudEventImpl<T> implements CloudEvent<AttributesImpl, T> {
@JsonAnyGetter
@Override
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("subject") String subject,
@JsonProperty("time") ZonedDateTime time,
@JsonProperty("data") T data){
@JsonProperty("data")
@JsonAlias("data_base64")
T data){
return CloudEventBuilder.<T>builder()
.withId(id)

View File

@ -22,6 +22,8 @@ import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import java.net.URI;
import java.time.ZonedDateTime;
import java.util.Base64;
import org.junit.Rule;
import org.junit.Test;
@ -281,4 +283,38 @@ public class CloudEventJacksonTest {
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 +"\""));
}
}

View File

@ -38,59 +38,6 @@ import io.cloudevents.v1.http.Marshallers;
*
*/
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
public void should_headers_have_content_type() {