Ignore invalid extension names in jackson CloudEventDeserializer (#429)
Signed-off-by: mhyeon-lee <mhyeon.lee@navercorp.com>
This commit is contained in:
parent
8d91cdaee6
commit
ceb06757a3
|
@ -38,19 +38,39 @@ import java.io.IOException;
|
||||||
* Jackson {@link com.fasterxml.jackson.databind.JsonDeserializer} for {@link CloudEvent}
|
* Jackson {@link com.fasterxml.jackson.databind.JsonDeserializer} for {@link CloudEvent}
|
||||||
*/
|
*/
|
||||||
class CloudEventDeserializer extends StdDeserializer<CloudEvent> {
|
class CloudEventDeserializer extends StdDeserializer<CloudEvent> {
|
||||||
|
private final boolean forceExtensionNameLowerCaseDeserialization;
|
||||||
|
private final boolean forceIgnoreInvalidExtensionNameDeserialization;
|
||||||
|
|
||||||
protected CloudEventDeserializer() {
|
protected CloudEventDeserializer() {
|
||||||
|
this(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CloudEventDeserializer(
|
||||||
|
boolean forceExtensionNameLowerCaseDeserialization,
|
||||||
|
boolean forceIgnoreInvalidExtensionNameDeserialization
|
||||||
|
) {
|
||||||
super(CloudEvent.class);
|
super(CloudEvent.class);
|
||||||
|
this.forceExtensionNameLowerCaseDeserialization = forceExtensionNameLowerCaseDeserialization;
|
||||||
|
this.forceIgnoreInvalidExtensionNameDeserialization = forceIgnoreInvalidExtensionNameDeserialization;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class JsonMessage implements CloudEventReader {
|
private static class JsonMessage implements CloudEventReader {
|
||||||
|
|
||||||
private final JsonParser p;
|
private final JsonParser p;
|
||||||
private final ObjectNode node;
|
private final ObjectNode node;
|
||||||
|
private final boolean forceExtensionNameLowerCaseDeserialization;
|
||||||
|
private final boolean forceIgnoreInvalidExtensionNameDeserialization;
|
||||||
|
|
||||||
public JsonMessage(JsonParser p, ObjectNode node) {
|
public JsonMessage(
|
||||||
|
JsonParser p,
|
||||||
|
ObjectNode node,
|
||||||
|
boolean forceExtensionNameLowerCaseDeserialization,
|
||||||
|
boolean forceIgnoreInvalidExtensionNameDeserialization
|
||||||
|
) {
|
||||||
this.p = p;
|
this.p = p;
|
||||||
this.node = node;
|
this.node = node;
|
||||||
|
this.forceExtensionNameLowerCaseDeserialization = forceExtensionNameLowerCaseDeserialization;
|
||||||
|
this.forceIgnoreInvalidExtensionNameDeserialization = forceIgnoreInvalidExtensionNameDeserialization;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -127,6 +147,14 @@ class CloudEventDeserializer extends StdDeserializer<CloudEvent> {
|
||||||
// Now let's process the extensions
|
// Now let's process the extensions
|
||||||
node.fields().forEachRemaining(entry -> {
|
node.fields().forEachRemaining(entry -> {
|
||||||
String extensionName = entry.getKey();
|
String extensionName = entry.getKey();
|
||||||
|
if (this.forceExtensionNameLowerCaseDeserialization) {
|
||||||
|
extensionName = extensionName.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.shouldSkipExtensionName(extensionName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
JsonNode extensionValue = entry.getValue();
|
JsonNode extensionValue = entry.getValue();
|
||||||
|
|
||||||
switch (extensionValue.getNodeType()) {
|
switch (extensionValue.getNodeType()) {
|
||||||
|
@ -192,6 +220,32 @@ class CloudEventDeserializer extends StdDeserializer<CloudEvent> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore not valid extension name
|
||||||
|
private boolean shouldSkipExtensionName(String extensionName) {
|
||||||
|
return this.forceIgnoreInvalidExtensionNameDeserialization && !this.isValidExtensionName(extensionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the extension name as defined in CloudEvents spec.
|
||||||
|
*
|
||||||
|
* @param name the extension name
|
||||||
|
* @return true if extension name is valid, false otherwise
|
||||||
|
* @see <a href="https://github.com/cloudevents/spec/blob/master/spec.md#attribute-naming-convention">attribute-naming-convention</a>
|
||||||
|
*/
|
||||||
|
private boolean isValidExtensionName(String name) {
|
||||||
|
for (int i = 0; i < name.length(); i++) {
|
||||||
|
if (!isValidChar(name.charAt(i))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidChar(char c) {
|
||||||
|
return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -201,7 +255,8 @@ class CloudEventDeserializer extends StdDeserializer<CloudEvent> {
|
||||||
ObjectNode node = ctxt.readValue(p, ObjectNode.class);
|
ObjectNode node = ctxt.readValue(p, ObjectNode.class);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new JsonMessage(p, node).read(CloudEventBuilder::fromSpecVersion);
|
return new JsonMessage(p, node, this.forceExtensionNameLowerCaseDeserialization, this.forceIgnoreInvalidExtensionNameDeserialization)
|
||||||
|
.read(CloudEventBuilder::fromSpecVersion);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
// Yeah this is bad but it's needed to support checked exceptions...
|
// Yeah this is bad but it's needed to support checked exceptions...
|
||||||
if (e.getCause() instanceof IOException) {
|
if (e.getCause() instanceof IOException) {
|
||||||
|
|
|
@ -45,8 +45,7 @@ public final class JsonFormat implements EventFormat {
|
||||||
public static final String CONTENT_TYPE = "application/cloudevents+json";
|
public static final String CONTENT_TYPE = "application/cloudevents+json";
|
||||||
|
|
||||||
private final ObjectMapper mapper;
|
private final ObjectMapper mapper;
|
||||||
private final boolean forceDataBase64Serialization;
|
private final JsonFormatOptions options;
|
||||||
private final boolean forceStringSerialization;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of this class customizing the serialization configuration.
|
* Create a new instance of this class customizing the serialization configuration.
|
||||||
|
@ -57,31 +56,86 @@ public final class JsonFormat implements EventFormat {
|
||||||
* @see #withForceNonJsonDataToString()
|
* @see #withForceNonJsonDataToString()
|
||||||
*/
|
*/
|
||||||
public JsonFormat(boolean forceDataBase64Serialization, boolean forceStringSerialization) {
|
public JsonFormat(boolean forceDataBase64Serialization, boolean forceStringSerialization) {
|
||||||
|
this(
|
||||||
|
JsonFormatOptions.builder()
|
||||||
|
.forceDataBase64Serialization(forceDataBase64Serialization)
|
||||||
|
.forceStringSerialization(forceStringSerialization)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of this class customizing the serialization configuration.
|
||||||
|
*
|
||||||
|
* @param options json serialization / deserialization options
|
||||||
|
*/
|
||||||
|
public JsonFormat(JsonFormatOptions options) {
|
||||||
this.mapper = new ObjectMapper();
|
this.mapper = new ObjectMapper();
|
||||||
this.mapper.registerModule(getCloudEventJacksonModule(forceDataBase64Serialization, forceStringSerialization));
|
this.mapper.registerModule(getCloudEventJacksonModule(options));
|
||||||
this.forceDataBase64Serialization = forceDataBase64Serialization;
|
this.options = options;
|
||||||
this.forceStringSerialization = forceStringSerialization;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of this class with default serialization configuration
|
* Create a new instance of this class with default serialization configuration
|
||||||
*/
|
*/
|
||||||
public JsonFormat() {
|
public JsonFormat() {
|
||||||
this(false, false);
|
this(new JsonFormatOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a copy of this JsonFormat that serialize events with json data with Base64 encoding
|
* @return a copy of this JsonFormat that serialize events with json data with Base64 encoding
|
||||||
*/
|
*/
|
||||||
public JsonFormat withForceJsonDataToBase64() {
|
public JsonFormat withForceJsonDataToBase64() {
|
||||||
return new JsonFormat(true, this.forceStringSerialization);
|
return new JsonFormat(
|
||||||
|
JsonFormatOptions.builder()
|
||||||
|
.forceDataBase64Serialization(true)
|
||||||
|
.forceStringSerialization(this.options.isForceStringSerialization())
|
||||||
|
.forceExtensionNameLowerCaseDeserialization(this.options.isForceExtensionNameLowerCaseDeserialization())
|
||||||
|
.forceIgnoreInvalidExtensionNameDeserialization(this.options.isForceIgnoreInvalidExtensionNameDeserialization())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a copy of this JsonFormat that serialize events with non-json data as string
|
* @return a copy of this JsonFormat that serialize events with non-json data as string
|
||||||
*/
|
*/
|
||||||
public JsonFormat withForceNonJsonDataToString() {
|
public JsonFormat withForceNonJsonDataToString() {
|
||||||
return new JsonFormat(this.forceDataBase64Serialization, true);
|
return new JsonFormat(
|
||||||
|
JsonFormatOptions.builder()
|
||||||
|
.forceDataBase64Serialization(this.options.isForceDataBase64Serialization())
|
||||||
|
.forceStringSerialization(true)
|
||||||
|
.forceExtensionNameLowerCaseDeserialization(this.options.isForceExtensionNameLowerCaseDeserialization())
|
||||||
|
.forceIgnoreInvalidExtensionNameDeserialization(this.options.isForceIgnoreInvalidExtensionNameDeserialization())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a copy of this JsonFormat that deserialize events with converting extension name lower case.
|
||||||
|
*/
|
||||||
|
public JsonFormat withForceExtensionNameLowerCaseDeserialization() {
|
||||||
|
return new JsonFormat(
|
||||||
|
JsonFormatOptions.builder()
|
||||||
|
.forceDataBase64Serialization(this.options.isForceDataBase64Serialization())
|
||||||
|
.forceStringSerialization(this.options.isForceStringSerialization())
|
||||||
|
.forceExtensionNameLowerCaseDeserialization(true)
|
||||||
|
.forceIgnoreInvalidExtensionNameDeserialization(this.options.isForceIgnoreInvalidExtensionNameDeserialization())
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a copy of this JsonFormat that deserialize events with ignoring invalid extension name
|
||||||
|
*/
|
||||||
|
public JsonFormat withForceIgnoreInvalidExtensionNameDeserialization() {
|
||||||
|
return new JsonFormat(
|
||||||
|
JsonFormatOptions.builder()
|
||||||
|
.forceDataBase64Serialization(this.options.isForceDataBase64Serialization())
|
||||||
|
.forceStringSerialization(this.options.isForceStringSerialization())
|
||||||
|
.forceExtensionNameLowerCaseDeserialization(this.options.isForceExtensionNameLowerCaseDeserialization())
|
||||||
|
.forceIgnoreInvalidExtensionNameDeserialization(true)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -137,9 +191,24 @@ public final class JsonFormat implements EventFormat {
|
||||||
* @see #withForceNonJsonDataToString()
|
* @see #withForceNonJsonDataToString()
|
||||||
*/
|
*/
|
||||||
public static SimpleModule getCloudEventJacksonModule(boolean forceDataBase64Serialization, boolean forceStringSerialization) {
|
public static SimpleModule getCloudEventJacksonModule(boolean forceDataBase64Serialization, boolean forceStringSerialization) {
|
||||||
|
return getCloudEventJacksonModule(
|
||||||
|
JsonFormatOptions.builder()
|
||||||
|
.forceDataBase64Serialization(forceDataBase64Serialization)
|
||||||
|
.forceStringSerialization(forceStringSerialization)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param options json serialization / deserialization options
|
||||||
|
* @return a JacksonModule with CloudEvent serializer/deserializer customizing the data serialization.
|
||||||
|
*/
|
||||||
|
public static SimpleModule getCloudEventJacksonModule(JsonFormatOptions options) {
|
||||||
final SimpleModule ceModule = new SimpleModule("CloudEvent");
|
final SimpleModule ceModule = new SimpleModule("CloudEvent");
|
||||||
ceModule.addSerializer(CloudEvent.class, new CloudEventSerializer(forceDataBase64Serialization, forceStringSerialization));
|
ceModule.addSerializer(CloudEvent.class, new CloudEventSerializer(
|
||||||
ceModule.addDeserializer(CloudEvent.class, new CloudEventDeserializer());
|
options.isForceDataBase64Serialization(), options.isForceStringSerialization()));
|
||||||
|
ceModule.addDeserializer(CloudEvent.class, new CloudEventDeserializer(
|
||||||
|
options.isForceExtensionNameLowerCaseDeserialization(), options.isForceIgnoreInvalidExtensionNameDeserialization()));
|
||||||
return ceModule;
|
return ceModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018-Present The CloudEvents Authors
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* 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.jackson;
|
||||||
|
|
||||||
|
public final class JsonFormatOptions {
|
||||||
|
private final boolean forceDataBase64Serialization;
|
||||||
|
private final boolean forceStringSerialization;
|
||||||
|
private final boolean forceExtensionNameLowerCaseDeserialization;
|
||||||
|
private final boolean forceIgnoreInvalidExtensionNameDeserialization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of this class options the serialization / deserialization.
|
||||||
|
*/
|
||||||
|
public JsonFormatOptions() {
|
||||||
|
this(false, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonFormatOptions(
|
||||||
|
boolean forceDataBase64Serialization,
|
||||||
|
boolean forceStringSerialization,
|
||||||
|
boolean forceExtensionNameLowerCaseDeserialization,
|
||||||
|
boolean forceIgnoreInvalidExtensionNameDeserialization
|
||||||
|
) {
|
||||||
|
this.forceDataBase64Serialization = forceDataBase64Serialization;
|
||||||
|
this.forceStringSerialization = forceStringSerialization;
|
||||||
|
this.forceExtensionNameLowerCaseDeserialization = forceExtensionNameLowerCaseDeserialization;
|
||||||
|
this.forceIgnoreInvalidExtensionNameDeserialization = forceIgnoreInvalidExtensionNameDeserialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsonFormatOptionsBuilder builder() {
|
||||||
|
return new JsonFormatOptionsBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForceDataBase64Serialization() {
|
||||||
|
return this.forceDataBase64Serialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForceStringSerialization() {
|
||||||
|
return this.forceStringSerialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForceExtensionNameLowerCaseDeserialization() {
|
||||||
|
return this.forceExtensionNameLowerCaseDeserialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForceIgnoreInvalidExtensionNameDeserialization() {
|
||||||
|
return this.forceIgnoreInvalidExtensionNameDeserialization;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class JsonFormatOptionsBuilder {
|
||||||
|
private boolean forceDataBase64Serialization = false;
|
||||||
|
private boolean forceStringSerialization = false;
|
||||||
|
private boolean forceExtensionNameLowerCaseDeserialization = false;
|
||||||
|
private boolean forceIgnoreInvalidExtensionNameDeserialization = false;
|
||||||
|
|
||||||
|
public JsonFormatOptionsBuilder forceDataBase64Serialization(boolean forceDataBase64Serialization) {
|
||||||
|
this.forceDataBase64Serialization = forceDataBase64Serialization;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonFormatOptionsBuilder forceStringSerialization(boolean forceStringSerialization) {
|
||||||
|
this.forceStringSerialization = forceStringSerialization;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonFormatOptionsBuilder forceExtensionNameLowerCaseDeserialization(boolean forceExtensionNameLowerCaseDeserialization) {
|
||||||
|
this.forceExtensionNameLowerCaseDeserialization = forceExtensionNameLowerCaseDeserialization;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonFormatOptionsBuilder forceIgnoreInvalidExtensionNameDeserialization(boolean forceIgnoreInvalidExtensionNameDeserialization) {
|
||||||
|
this.forceIgnoreInvalidExtensionNameDeserialization = forceIgnoreInvalidExtensionNameDeserialization;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonFormatOptions build() {
|
||||||
|
return new JsonFormatOptions(
|
||||||
|
this.forceDataBase64Serialization,
|
||||||
|
this.forceStringSerialization,
|
||||||
|
this.forceExtensionNameLowerCaseDeserialization,
|
||||||
|
this.forceIgnoreInvalidExtensionNameDeserialization
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,14 +27,12 @@ import io.cloudevents.core.builder.CloudEventBuilder;
|
||||||
import io.cloudevents.core.format.EventDeserializationException;
|
import io.cloudevents.core.format.EventDeserializationException;
|
||||||
import io.cloudevents.core.provider.EventFormatProvider;
|
import io.cloudevents.core.provider.EventFormatProvider;
|
||||||
import io.cloudevents.rw.CloudEventRWException;
|
import io.cloudevents.rw.CloudEventRWException;
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -90,6 +88,22 @@ class JsonFormatTest {
|
||||||
.isEqualTo(output);
|
.isEqualTo(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("deserializeTestArgumentsUpperCaseExtensionName")
|
||||||
|
void deserializeWithUpperCaseExtensionName(String inputFile, CloudEvent output) {
|
||||||
|
CloudEvent deserialized = getFormat().withForceExtensionNameLowerCaseDeserialization().deserialize(loadFile(inputFile));
|
||||||
|
assertThat(deserialized)
|
||||||
|
.isEqualTo(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("deserializeTestArgumentsInvalidExtensionName")
|
||||||
|
void deserializeWithInvalidExtensionName(String inputFile, CloudEvent output) {
|
||||||
|
CloudEvent deserialized = getFormat().withForceIgnoreInvalidExtensionNameDeserialization().deserialize(loadFile(inputFile));
|
||||||
|
assertThat(deserialized)
|
||||||
|
.isEqualTo(output);
|
||||||
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("roundTripTestArguments")
|
@MethodSource("roundTripTestArguments")
|
||||||
void jsonRoundTrip(String inputFile) throws IOException {
|
void jsonRoundTrip(String inputFile) throws IOException {
|
||||||
|
@ -204,6 +218,20 @@ class JsonFormatTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Stream<Arguments> deserializeTestArgumentsUpperCaseExtensionName() {
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of("v03/json_data_with_ext_upper_case.json", normalizeToJsonValueIfNeeded(V03_WITH_JSON_DATA_WITH_EXT)),
|
||||||
|
Arguments.of("v1/json_data_with_ext_upper_case.json", normalizeToJsonValueIfNeeded(V1_WITH_JSON_DATA_WITH_EXT))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<Arguments> deserializeTestArgumentsInvalidExtensionName() {
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of("v03/json_data_with_ext_invalid.json", normalizeToJsonValueIfNeeded(V03_WITH_JSON_DATA_WITH_EXT)),
|
||||||
|
Arguments.of("v1/json_data_with_ext_invalid.json", normalizeToJsonValueIfNeeded(V1_WITH_JSON_DATA_WITH_EXT))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static Stream<String> roundTripTestArguments() {
|
public static Stream<String> roundTripTestArguments() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
"v03/min.json",
|
"v03/min.json",
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"specversion": "0.3",
|
||||||
|
"id": "1",
|
||||||
|
"type": "mock.test",
|
||||||
|
"source": "http://localhost/source",
|
||||||
|
"schemaurl": "http://localhost/schema",
|
||||||
|
"datacontenttype": "application/json",
|
||||||
|
"data": {},
|
||||||
|
"subject": "sub",
|
||||||
|
"time": "2018-04-26T14:48:09+02:00",
|
||||||
|
"astring": "aaa",
|
||||||
|
"aboolean": true,
|
||||||
|
"anumber": 10,
|
||||||
|
"a_invalid_name": "invalidName"
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"specversion": "0.3",
|
||||||
|
"id": "1",
|
||||||
|
"type": "mock.test",
|
||||||
|
"source": "http://localhost/source",
|
||||||
|
"schemaurl": "http://localhost/schema",
|
||||||
|
"datacontenttype": "application/json",
|
||||||
|
"data": {},
|
||||||
|
"subject": "sub",
|
||||||
|
"time": "2018-04-26T14:48:09+02:00",
|
||||||
|
"aString": "aaa",
|
||||||
|
"aBoolean": true,
|
||||||
|
"aNumber": 10
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"specversion": "1.0",
|
||||||
|
"id": "1",
|
||||||
|
"type": "mock.test",
|
||||||
|
"source": "http://localhost/source",
|
||||||
|
"dataschema": "http://localhost/schema",
|
||||||
|
"datacontenttype": "application/json",
|
||||||
|
"data": {},
|
||||||
|
"subject": "sub",
|
||||||
|
"time": "2018-04-26T14:48:09+02:00",
|
||||||
|
"astring": "aaa",
|
||||||
|
"aboolean": true,
|
||||||
|
"anumber": 10,
|
||||||
|
"a_invalid_name": "invalidName"
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"specversion": "1.0",
|
||||||
|
"id": "1",
|
||||||
|
"type": "mock.test",
|
||||||
|
"source": "http://localhost/source",
|
||||||
|
"dataschema": "http://localhost/schema",
|
||||||
|
"datacontenttype": "application/json",
|
||||||
|
"data": {},
|
||||||
|
"subject": "sub",
|
||||||
|
"time": "2018-04-26T14:48:09+02:00",
|
||||||
|
"aString": "aaa",
|
||||||
|
"aBoolean": true,
|
||||||
|
"aNumber": 10
|
||||||
|
}
|
Loading…
Reference in New Issue