You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@eventmesh.apache.org by mi...@apache.org on 2021/09/24 07:05:49 UTC
[incubator-eventmesh] branch develop updated: Implement the
conversion from openmessaging to cloudevent (#514)
This is an automated email from the ASF dual-hosted git repository.
mikexue pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-eventmesh.git
The following commit(s) were added to refs/heads/develop by this push:
new 537ed82 Implement the conversion from openmessaging to cloudevent (#514)
537ed82 is described below
commit 537ed8226f95337ddba770339387a8855bcb0a4d
Author: wangshaojie4039 <15...@163.com>
AuthorDate: Fri Sep 24 15:05:44 2021 +0800
Implement the conversion from openmessaging to cloudevent (#514)
* cloudevent commit
* cloudevent commit
* add cloudevent lib licenses
Co-authored-by: wangshaojie <wa...@cmss.chinamobile.com>
---
build.gradle | 2 +
eventmesh-runtime/build.gradle | 2 +-
.../protocol/cloudevent/OMSMessageFactory.java | 99 +++++++
.../cloudevent/impl/OMSBinaryMessageReader.java | 90 +++++++
.../core/protocol/cloudevent/impl/OMSHeaders.java | 44 ++++
.../protocol/cloudevent/impl/OMSMessageWriter.java | 100 +++++++
.../eventmesh/runtime/cloudevent/CSVFormat.java | 107 ++++++++
.../apache/eventmesh/runtime/cloudevent/Data.java | 197 ++++++++++++++
.../runtime/cloudevent/OMSFactoryTest.java | 260 +++++++++++++++++++
.../runtime/cloudevent/OMSWriterTest.java | 287 +++++++++++++++++++++
tool/license/allowed-licenses.txt | 10 +
11 files changed, 1197 insertions(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index d42d81d..a8950a3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -387,12 +387,14 @@ subprojects {
dependency "org.powermock:powermock-module-junit4:2.0.2"
dependency "org.powermock:powermock-api-mockito2:2.0.2"
+
dependency 'org.springframework.boot:spring-boot-starter-data-jdbc:2.5.4'
dependency 'org.springframework.boot:spring-boot-starter-data-jpa:2.5.4'
dependency 'org.springframework.boot:spring-boot-starter-jdbc:2.5.4'
dependency 'org.springframework:spring-beans:5.1.8.RELEASE'
dependency 'org.projectlombok:lombok:1.18.20'
dependency 'com.h2database:h2:1.4.200'
+ dependency "io.cloudevents:cloudevents-core:2.2.0"
}
}
}
\ No newline at end of file
diff --git a/eventmesh-runtime/build.gradle b/eventmesh-runtime/build.gradle
index 33d4452..b3d4d48 100644
--- a/eventmesh-runtime/build.gradle
+++ b/eventmesh-runtime/build.gradle
@@ -22,7 +22,7 @@ dependencies {
api 'io.opentelemetry:opentelemetry-exporter-prometheus'
api 'io.prometheus:simpleclient'
api 'io.prometheus:simpleclient_httpserver'
-
+ api 'io.cloudevents:cloudevents-core'
implementation project(":eventmesh-connector-plugin:eventmesh-connector-api")
implementation project(":eventmesh-connector-plugin:eventmesh-connector-standalone")
implementation project(":eventmesh-security-plugin:eventmesh-security-api")
diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/OMSMessageFactory.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/OMSMessageFactory.java
new file mode 100644
index 0000000..fcb2026
--- /dev/null
+++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/OMSMessageFactory.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.eventmesh.runtime.core.protocol.cloudevent;
+
+import io.cloudevents.core.message.MessageReader;
+import io.cloudevents.core.message.MessageWriter;
+import io.cloudevents.core.message.impl.GenericStructuredMessageReader;
+import io.cloudevents.core.message.impl.MessageUtils;
+import io.cloudevents.lang.Nullable;
+import io.cloudevents.rw.CloudEventRWException;
+import io.cloudevents.rw.CloudEventWriter;
+import io.openmessaging.api.Message;
+import org.apache.eventmesh.runtime.core.protocol.cloudevent.impl.OMSBinaryMessageReader;
+import org.apache.eventmesh.runtime.core.protocol.cloudevent.impl.OMSHeaders;
+import org.apache.eventmesh.runtime.core.protocol.cloudevent.impl.OMSMessageWriter;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+import java.util.Properties;
+
+/**
+ * This class provides a collection of methods to create {@link io.cloudevents.core.message.MessageReader}
+ * and {@link io.cloudevents.core.message.MessageWriter}
+ * manually serialize/deserialize {@link io.cloudevents.CloudEvent} messages.
+ */
+@ParametersAreNonnullByDefault
+public final class OMSMessageFactory {
+
+ private OMSMessageFactory() {
+ // prevent instantiation
+ }
+
+ /**
+ * create reader by message
+ * @param message
+ * @return
+ * @throws CloudEventRWException
+ */
+ public static MessageReader createReader(final Message message) throws CloudEventRWException {
+ return createReader(message.getUserProperties(), message.getBody());
+ }
+
+
+ public static MessageReader createReader(final Properties props, @Nullable final byte[] body) throws CloudEventRWException {
+
+ return MessageUtils.parseStructuredOrBinaryMessage(
+ () -> props.getOrDefault(OMSHeaders.CONTENT_TYPE,"").toString(),
+ format -> new GenericStructuredMessageReader(format, body),
+ () -> props.getOrDefault(OMSHeaders.SPEC_VERSION,"").toString(),
+ sv -> new OMSBinaryMessageReader(sv, props, body)
+ );
+ }
+
+
+ /**
+ * create writer by topic
+ * @param topic
+ * @return
+ */
+ public static MessageWriter<CloudEventWriter<Message>, Message> createWriter(String topic) {
+ return new OMSMessageWriter<>(topic);
+ }
+
+ /**
+ * create writer by topic,keys
+ * @param topic
+ * @param keys
+ * @return
+ */
+ public static MessageWriter<CloudEventWriter<Message>, Message> createWriter(String topic, String keys) {
+ return new OMSMessageWriter<>(topic, keys);
+ }
+
+ /**
+ * create writer by topic,keys,tags
+ * @param topic
+ * @param keys
+ * @param tags
+ * @return
+ */
+ public static MessageWriter<CloudEventWriter<Message>, Message> createWriter(String topic, String keys, String tags) {
+ return new OMSMessageWriter<>(topic, keys, tags);
+ }
+
+}
diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSBinaryMessageReader.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSBinaryMessageReader.java
new file mode 100644
index 0000000..ae035c7
--- /dev/null
+++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSBinaryMessageReader.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.eventmesh.runtime.core.protocol.cloudevent.impl;
+
+import io.cloudevents.SpecVersion;
+import io.cloudevents.core.data.BytesCloudEventData;
+import io.cloudevents.core.message.impl.BaseGenericBinaryMessageReaderImpl;
+
+import java.util.Objects;
+import java.util.Properties;
+import java.util.function.BiConsumer;
+
+/**
+ * binary message reader
+ */
+public class OMSBinaryMessageReader extends BaseGenericBinaryMessageReaderImpl<String, String> {
+
+ private final Properties headers;
+
+ public OMSBinaryMessageReader(SpecVersion version, Properties headers, byte[] payload) {
+ super(version, payload != null && payload.length > 0 ? BytesCloudEventData.wrap(payload) : null);
+
+ Objects.requireNonNull(headers);
+ this.headers = headers;
+ }
+
+ /**
+ * whether header key is content type
+ * @param key
+ * @return
+ */
+ @Override
+ protected boolean isContentTypeHeader(String key) {
+ return key.equals(OMSHeaders.CONTENT_TYPE);
+ }
+
+ /**
+ * whether message header is cloudEvent header
+ * @param key
+ * @return
+ */
+ @Override
+ protected boolean isCloudEventsHeader(String key) {
+ return key.length() > 3 && key.substring(0, OMSHeaders.CE_PREFIX.length()).startsWith(OMSHeaders.CE_PREFIX);
+ }
+
+ /**
+ * parse message header to cloudEvent attribute
+ * @param key
+ * @return
+ */
+ @Override
+ protected String toCloudEventsKey(String key) {
+ return key.substring(OMSHeaders.CE_PREFIX.length()).toLowerCase();
+ }
+
+ /**
+ *
+ * @param fn
+ */
+ @Override
+ protected void forEachHeader(BiConsumer<String, String> fn) {
+ this.headers.forEach((k, v) -> {
+ if (k != null && v != null) {
+ fn.accept(k.toString(), v.toString());
+ }
+
+ });
+ }
+
+ @Override
+ protected String toCloudEventsValue(String value) {
+ return value;
+ }
+}
diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSHeaders.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSHeaders.java
new file mode 100644
index 0000000..7747175
--- /dev/null
+++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSHeaders.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.eventmesh.runtime.core.protocol.cloudevent.impl;
+
+import io.cloudevents.core.message.impl.MessageUtils;
+import io.cloudevents.core.v1.CloudEventV1;
+
+import java.util.Map;
+
+/**
+ * Define the value of CE attribute in the header of ons
+ */
+public class OMSHeaders {
+
+ /**
+ * CE prefix
+ */
+ public static final String CE_PREFIX = "ce_";
+
+ /**
+ * Prefix each value
+ */
+ protected static final Map<String, String> ATTRIBUTES_TO_HEADERS = MessageUtils.generateAttributesToHeadersMapping(v -> CE_PREFIX + v);
+
+ public static final String CONTENT_TYPE = ATTRIBUTES_TO_HEADERS.get(CloudEventV1.DATACONTENTTYPE);
+
+ public static final String SPEC_VERSION = ATTRIBUTES_TO_HEADERS.get(CloudEventV1.SPECVERSION);
+
+}
+
diff --git a/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSMessageWriter.java b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSMessageWriter.java
new file mode 100644
index 0000000..0d74331
--- /dev/null
+++ b/eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/cloudevent/impl/OMSMessageWriter.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.eventmesh.runtime.core.protocol.cloudevent.impl;
+
+import io.cloudevents.CloudEventData;
+import io.cloudevents.SpecVersion;
+import io.cloudevents.core.format.EventFormat;
+import io.cloudevents.core.message.MessageWriter;
+import io.cloudevents.rw.CloudEventContextWriter;
+import io.cloudevents.rw.CloudEventRWException;
+import io.cloudevents.rw.CloudEventWriter;
+import io.openmessaging.api.Message;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * write ce to ons
+ * @param <R>
+ */
+public final class OMSMessageWriter<R> implements MessageWriter<CloudEventWriter<Message>, Message>, CloudEventWriter<Message> {
+
+ private Message message;
+
+
+ public OMSMessageWriter(String topic) {
+ message = new Message();
+ message.setTopic(topic);
+ }
+
+ public OMSMessageWriter(String topic, String key) {
+ message = new Message();
+ message.setTopic(topic);
+ if (key != null && key.length() > 0) {
+ message.setKey(key);
+ }
+ }
+
+ public OMSMessageWriter(String topic, String key, String tag) {
+ message = new Message();
+ message.setTopic(topic);
+ if (StringUtils.isNotEmpty(tag)) {
+ message.setTag(tag);
+ }
+
+ if (StringUtils.isNotEmpty(key)) {
+ message.setKey(key);
+ }
+ }
+
+
+ @Override
+ public CloudEventContextWriter withContextAttribute(String name, String value) throws CloudEventRWException {
+
+ String propName = OMSHeaders.ATTRIBUTES_TO_HEADERS.get(name);
+ if (propName == null) {
+ propName = OMSHeaders.CE_PREFIX + name;
+ }
+ message.putUserProperties(propName, value);
+ return this;
+ }
+
+ @Override
+ public OMSMessageWriter<R> create(final SpecVersion version) {
+ message.putUserProperties(OMSHeaders.SPEC_VERSION, version.toString());
+ return this;
+ }
+
+ @Override
+ public Message setEvent(final EventFormat format, final byte[] value) throws CloudEventRWException {
+ message.putUserProperties(OMSHeaders.CONTENT_TYPE, format.serializedContentType());
+ message.setBody(value);
+ return message;
+ }
+
+ @Override
+ public Message end(final CloudEventData data) throws CloudEventRWException {
+ message.setBody(data.toBytes());
+ return message;
+ }
+
+ @Override
+ public Message end() {
+ message.setBody(null);
+ return message;
+ }
+}
diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/CSVFormat.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/CSVFormat.java
new file mode 100644
index 0000000..6a9d3c5
--- /dev/null
+++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/CSVFormat.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.eventmesh.runtime.cloudevent;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.SpecVersion;
+import io.cloudevents.core.builder.CloudEventBuilder;
+import io.cloudevents.core.data.BytesCloudEventData;
+import io.cloudevents.core.format.EventFormat;
+import io.cloudevents.rw.CloudEventDataMapper;
+import io.cloudevents.types.Time;
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.time.OffsetDateTime;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+public class CSVFormat implements EventFormat {
+
+ public static final CSVFormat INSTANCE = new CSVFormat();
+
+ @Override
+ public byte[] serialize(CloudEvent event) {
+ return String.join(
+ ",",
+ event.getSpecVersion().toString(),
+ event.getId(),
+ event.getType(),
+ event.getSource().toString(),
+ Objects.toString(event.getDataContentType()),
+ Objects.toString(event.getDataSchema()),
+ Objects.toString(event.getSubject()),
+ event.getTime() != null
+ ? Time.writeTime(event.getTime())
+ : "null",
+ event.getData() != null
+ ? new String(Base64.getEncoder().encode(event.getData().toBytes()), StandardCharsets.UTF_8)
+ : "null"
+ ).getBytes();
+ }
+
+ @Override
+ public CloudEvent deserialize(byte[] bytes, CloudEventDataMapper mapper) {
+ String[] splitted = new String(bytes, StandardCharsets.UTF_8).split(Pattern.quote(","));
+ SpecVersion sv = SpecVersion.parse(splitted[0]);
+
+ String id = splitted[1];
+ String type = splitted[2];
+ URI source = URI.create(splitted[3]);
+ String datacontenttype = splitted[4].equals("null") ? null : splitted[4];
+ URI dataschema = splitted[5].equals("null") ? null : URI.create(splitted[5]);
+ String subject = splitted[6].equals("null") ? null : splitted[6];
+ OffsetDateTime time = splitted[7].equals("null") ? null : Time.parseTime(splitted[7]);
+ byte[] data = splitted[8].equals("null") ? null : Base64.getDecoder().decode(splitted[8].getBytes());
+
+ CloudEventBuilder builder = CloudEventBuilder.fromSpecVersion(sv)
+ .withId(id)
+ .withType(type)
+ .withSource(source);
+
+ if (datacontenttype != null) {
+ builder.withDataContentType(datacontenttype);
+ }
+ if (dataschema != null) {
+ builder.withDataSchema(dataschema);
+ }
+ if (subject != null) {
+ builder.withSubject(subject);
+ }
+ if (time != null) {
+ builder.withTime(time);
+ }
+ if (data != null) {
+ builder.withData(mapper.map(BytesCloudEventData.wrap(data)));
+ }
+ return builder.build();
+ }
+
+ @Override
+ public Set<String> deserializableContentTypes() {
+ return Collections.singleton(serializedContentType());
+ }
+
+ @Override
+ public String serializedContentType() {
+ return "application/cloudevents+csv";
+ }
+}
diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/Data.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/Data.java
new file mode 100644
index 0000000..001aa19
--- /dev/null
+++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/Data.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.eventmesh.runtime.cloudevent;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.core.builder.CloudEventBuilder;
+import io.cloudevents.types.Time;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.time.OffsetDateTime;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+public class Data {
+
+ public static final String ID = "1";
+ public static final String TYPE = "mock.test";
+ public static final URI SOURCE = URI.create("http://localhost/source");
+ public static final String DATACONTENTTYPE_JSON = "application/json";
+ public static final String DATACONTENTTYPE_XML = "application/xml";
+ public static final String DATACONTENTTYPE_TEXT = "text/plain";
+ public static final URI DATASCHEMA = URI.create("http://localhost/schema");
+ public static final String SUBJECT = "sub";
+ public static final OffsetDateTime TIME = Time.parseTime("2018-04-26T14:48:09+02:00");
+
+ protected static final byte[] DATA_JSON_SERIALIZED = "{}".getBytes();
+ protected static final byte[] DATA_XML_SERIALIZED = "<stuff></stuff>".getBytes();
+ protected static final byte[] DATA_TEXT_SERIALIZED = "Hello World Lorena!".getBytes();
+ protected static final byte[] BINARY_VALUE = { (byte) 0xE0, (byte) 0xFF, (byte) 0x00, (byte) 0x44, (byte) 0xAA }; // Base64: 4P8ARKo=
+
+ protected static final CloudEvent V1_MIN = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .build();
+
+ public static final CloudEvent V1_WITH_JSON_DATA = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .withData(DATACONTENTTYPE_JSON, DATASCHEMA, DATA_JSON_SERIALIZED)
+ .withSubject(SUBJECT)
+ .withTime(TIME)
+ .build();
+
+ public static final CloudEvent V1_WITH_JSON_DATA_WITH_FRACTIONAL_TIME = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .withData(DATACONTENTTYPE_JSON, DATASCHEMA, DATA_JSON_SERIALIZED)
+ .withSubject(SUBJECT)
+ .withTime(Time.parseTime("2018-04-26T14:48:09.1234Z"))
+ .build();
+
+ public static final CloudEvent V1_WITH_JSON_DATA_WITH_EXT = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .withData(DATACONTENTTYPE_JSON, DATASCHEMA, DATA_JSON_SERIALIZED)
+ .withSubject(SUBJECT)
+ .withTime(TIME)
+ .withExtension("astring", "aaa")
+ .withExtension("aboolean", true)
+ .withExtension("anumber", 10)
+ .build();
+
+ public static final CloudEvent V1_WITH_JSON_DATA_WITH_EXT_STRING = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .withData(DATACONTENTTYPE_JSON, DATASCHEMA, DATA_JSON_SERIALIZED)
+ .withSubject(SUBJECT)
+ .withTime(TIME)
+ .withExtension("astring", "aaa")
+ .withExtension("aboolean", "true")
+ .withExtension("anumber", "10")
+ .build();
+
+ public static final CloudEvent V1_WITH_XML_DATA = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .withData(DATACONTENTTYPE_XML, DATA_XML_SERIALIZED)
+ .withSubject(SUBJECT)
+ .withTime(TIME)
+ .build();
+
+ public static final CloudEvent V1_WITH_TEXT_DATA = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .withData(DATACONTENTTYPE_TEXT, DATA_TEXT_SERIALIZED)
+ .withSubject(SUBJECT)
+ .withTime(TIME)
+ .build();
+
+ public static final CloudEvent V1_WITH_BINARY_EXT = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .withExtension("binary", BINARY_VALUE)
+ .build();
+
+ public static final CloudEvent V1_WITH_NUMERIC_EXT = CloudEventBuilder.v1()
+ .withId(ID)
+ .withType(TYPE)
+ .withSource(SOURCE)
+ .withExtension("integer", 42)
+ .withExtension("decimal", new BigDecimal("42.42"))
+ .withExtension("float", 4.2f)
+ .withExtension("long", new Long(4200))
+ .build();
+
+ public static final CloudEvent V03_MIN = CloudEventBuilder.v03(V1_MIN).build();
+ public static final CloudEvent V03_WITH_JSON_DATA = CloudEventBuilder.v03(V1_WITH_JSON_DATA).build();
+ public static final CloudEvent V03_WITH_JSON_DATA_WITH_EXT = CloudEventBuilder.v03(V1_WITH_JSON_DATA_WITH_EXT).build();
+ public static final CloudEvent V03_WITH_JSON_DATA_WITH_EXT_STRING = CloudEventBuilder.v03(V1_WITH_JSON_DATA_WITH_EXT_STRING).build();
+ public static final CloudEvent V03_WITH_XML_DATA = CloudEventBuilder.v03(V1_WITH_XML_DATA).build();
+ public static final CloudEvent V03_WITH_TEXT_DATA = CloudEventBuilder.v03(V1_WITH_TEXT_DATA).build();
+
+ public static Stream<CloudEvent> allEvents() {
+ return Stream.concat(v1Events(), v03Events());
+ }
+
+ public static Stream<CloudEvent> allEventsWithoutExtensions() {
+ return Stream.concat(v1Events(), v03Events()).filter(e -> e.getExtensionNames().isEmpty());
+ }
+
+ public static Stream<CloudEvent> allEventsWithStringExtensions() {
+ return Stream.concat(v1EventsWithStringExt(), v03EventsWithStringExt());
+ }
+
+ public static Stream<CloudEvent> v1Events() {
+ return Stream.of(
+ Data.V1_MIN,
+ Data.V1_WITH_JSON_DATA,
+ Data.V1_WITH_JSON_DATA_WITH_EXT,
+ Data.V1_WITH_XML_DATA,
+ Data.V1_WITH_TEXT_DATA
+ );
+ }
+
+ /**
+ * Due to the nature of CE there are scenarios where an event might be serialized
+ * in such a fashion that it can not be deserialized while retaining the orginal
+ * type information, this varies from format-2-format
+ */
+
+ public static Stream<CloudEvent> v1NonRoundTripEvents() {
+ return Stream.of(
+ Data.V1_WITH_BINARY_EXT
+ );
+ }
+
+ public static Stream<CloudEvent> v03Events() {
+ return Stream.of(
+ Data.V03_MIN,
+ Data.V03_WITH_JSON_DATA,
+ Data.V03_WITH_JSON_DATA_WITH_EXT,
+ Data.V03_WITH_XML_DATA,
+ Data.V03_WITH_TEXT_DATA
+ );
+ }
+
+ public static Stream<CloudEvent> v1EventsWithStringExt() {
+ return v1Events().map(ce -> {
+ io.cloudevents.core.v1.CloudEventBuilder builder = CloudEventBuilder.v1(ce);
+ ce.getExtensionNames().forEach(k -> builder.withExtension(k, Objects.toString(ce.getExtension(k))));
+ return builder.build();
+ });
+ }
+
+ public static Stream<CloudEvent> v03EventsWithStringExt() {
+ return v03Events().map(ce -> {
+ io.cloudevents.core.v03.CloudEventBuilder builder = CloudEventBuilder.v03(ce);
+ ce.getExtensionNames().forEach(k -> builder.withExtension(k, Objects.toString(ce.getExtension(k))));
+ return builder.build();
+ });
+ }
+
+}
diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/OMSFactoryTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/OMSFactoryTest.java
new file mode 100644
index 0000000..583262e
--- /dev/null
+++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/OMSFactoryTest.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.eventmesh.runtime.cloudevent;
+
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.SpecVersion;
+import io.cloudevents.core.message.Encoding;
+import io.cloudevents.core.message.MessageReader;
+import io.cloudevents.core.provider.EventFormatProvider;
+import io.cloudevents.core.v03.CloudEventV03;
+import io.cloudevents.core.v1.CloudEventV1;
+import io.cloudevents.types.Time;
+import org.apache.eventmesh.runtime.core.protocol.cloudevent.OMSMessageFactory;
+import org.apache.eventmesh.runtime.core.protocol.cloudevent.impl.OMSHeaders;
+import org.junit.Test;
+
+import java.util.AbstractMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class OMSFactoryTest {
+
+ private static final String PREFIX_TEMPLATE = OMSHeaders.CE_PREFIX + "%s";
+ private static final String DATACONTENTTYPE_NULL = null;
+ private static final byte[] DATAPAYLOAD_NULL = null;
+
+ @Test
+ public void readBinary() {
+ Stream<Arguments> argumentsStream=binaryTestArguments();
+ argumentsStream.forEach(argument -> {
+ if (argument.contentType != null) {
+ argument.props.put(OMSHeaders.CONTENT_TYPE, argument.contentType);
+ }
+ Properties properties = new Properties();
+ properties.putAll(argument.props);
+ final MessageReader reader = OMSMessageFactory.createReader(properties, argument.body);
+ assertThat(reader.getEncoding()).isEqualTo(Encoding.BINARY);
+ assertThat(reader.toEvent()).isEqualTo(argument.event);
+
+ });
+
+ }
+
+ @Test
+ public void readStructured() {
+ Stream<CloudEvent> cloudEventStream= Data.allEventsWithoutExtensions();
+ EventFormatProvider.getInstance().registerFormat(CSVFormat.INSTANCE);
+ cloudEventStream.forEach(event -> {
+ final String contentType = CSVFormat.INSTANCE.serializedContentType() + "; charset=utf8";
+ final byte[] contentPayload = CSVFormat.INSTANCE.serialize(event);
+ Properties properties = new Properties();
+ properties.put(OMSHeaders.CONTENT_TYPE, contentType);
+ final MessageReader reader = OMSMessageFactory.createReader(properties, contentPayload);
+ assertThat(reader.getEncoding()).isEqualTo(Encoding.STRUCTURED);
+ assertThat(reader.toEvent()).isEqualTo(event);
+ });
+ }
+
+ private Stream<Arguments> binaryTestArguments() {
+
+ return Stream.of(
+ // V03
+ new Arguments(
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property("ignored", "ignore")
+ ),
+ DATACONTENTTYPE_NULL,
+ DATAPAYLOAD_NULL,
+ Data.V03_MIN
+ ),
+ new Arguments(
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV03.SCHEMAURL, Data.DATASCHEMA.toString()),
+ property(CloudEventV03.SUBJECT, Data.SUBJECT),
+ property(CloudEventV03.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignore")
+ ),
+ Data.DATACONTENTTYPE_JSON,
+ Data.DATA_JSON_SERIALIZED,
+ Data.V03_WITH_JSON_DATA
+ ),
+ new Arguments(
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV03.SCHEMAURL, Data.DATASCHEMA.toString()),
+ property(CloudEventV03.SUBJECT, Data.SUBJECT),
+ property(CloudEventV03.TIME, Time.writeTime(Data.TIME)),
+ property("astring", "aaa"),
+ property("aboolean", "true"),
+ property("anumber", "10"),
+ property("ignored", "ignored")
+ ),
+ Data.DATACONTENTTYPE_JSON,
+ Data.DATA_JSON_SERIALIZED,
+ Data.V03_WITH_JSON_DATA_WITH_EXT_STRING
+ ),
+ new Arguments(
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV03.SUBJECT, Data.SUBJECT),
+ property(CloudEventV03.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+ Data.DATACONTENTTYPE_XML,
+ Data.DATA_XML_SERIALIZED,
+ Data.V03_WITH_XML_DATA
+ ),
+ new Arguments(
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV03.SUBJECT, Data.SUBJECT),
+ property(CloudEventV03.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+ Data.DATACONTENTTYPE_TEXT,
+ Data.DATA_TEXT_SERIALIZED,
+ Data.V03_WITH_TEXT_DATA
+ ),
+ // V1
+ new Arguments(
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property("ignored", "ignored")
+ ),
+ DATACONTENTTYPE_NULL,
+ DATAPAYLOAD_NULL,
+ Data.V1_MIN
+ ),
+ new Arguments(
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV1.DATASCHEMA, Data.DATASCHEMA.toString()),
+ property(CloudEventV1.SUBJECT, Data.SUBJECT),
+ property(CloudEventV1.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+ Data.DATACONTENTTYPE_JSON,
+ Data.DATA_JSON_SERIALIZED,
+ Data.V1_WITH_JSON_DATA
+ ),
+ new Arguments(
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV1.DATASCHEMA, Data.DATASCHEMA.toString()),
+ property(CloudEventV1.SUBJECT, Data.SUBJECT),
+ property(CloudEventV1.TIME, Time.writeTime(Data.TIME)),
+ property("astring", "aaa"),
+ property("aboolean", "true"),
+ property("anumber", "10"),
+ property("ignored", "ignored")
+ ),
+ Data.DATACONTENTTYPE_JSON,
+ Data.DATA_JSON_SERIALIZED,
+ Data.V1_WITH_JSON_DATA_WITH_EXT_STRING
+ ),
+ new Arguments(
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV1.SUBJECT, Data.SUBJECT),
+ property(CloudEventV1.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+ Data.DATACONTENTTYPE_XML,
+ Data.DATA_XML_SERIALIZED,
+ Data.V1_WITH_XML_DATA
+ ),
+ new Arguments(
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV1.SUBJECT, Data.SUBJECT),
+ property(CloudEventV1.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+ Data.DATACONTENTTYPE_TEXT,
+ Data.DATA_TEXT_SERIALIZED,
+ Data.V1_WITH_TEXT_DATA
+ )
+ );
+ }
+
+ private static final AbstractMap.SimpleEntry<String, String> property(final String name, final String value) {
+ return name.equalsIgnoreCase("ignored") ?
+ new AbstractMap.SimpleEntry<>(name, value) :
+ new AbstractMap.SimpleEntry<>(String.format(PREFIX_TEMPLATE, name), value);
+ }
+
+ @SafeVarargs
+ private static final Map<String, String> properties(final AbstractMap.SimpleEntry<String, String>... entries) {
+ return Stream.of(entries)
+ .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
+
+ }
+
+
+ private class Arguments {
+ private Map<String, String> props;
+ private String contentType;
+ private byte[] body;
+ private CloudEvent event;
+
+ public Arguments(Map<String, String> props, String contentType, byte[] body, CloudEvent event) {
+ this.props = props;
+ this.contentType = contentType;
+ this.body = body;
+ this.event = event;
+ }
+ }
+}
diff --git a/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/OMSWriterTest.java b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/OMSWriterTest.java
new file mode 100644
index 0000000..834f156
--- /dev/null
+++ b/eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/cloudevent/OMSWriterTest.java
@@ -0,0 +1,287 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.eventmesh.runtime.cloudevent;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.SpecVersion;
+import io.cloudevents.core.message.StructuredMessageReader;
+import io.cloudevents.core.v03.CloudEventV03;
+import io.cloudevents.core.v1.CloudEventV1;
+import io.cloudevents.types.Time;
+import io.openmessaging.api.Message;
+import org.apache.eventmesh.runtime.core.protocol.cloudevent.OMSMessageFactory;
+import org.apache.eventmesh.runtime.core.protocol.cloudevent.impl.OMSHeaders;
+import org.junit.Test;
+
+import java.util.AbstractMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class OMSWriterTest {
+
+ private static final String PREFIX_TEMPLATE = OMSHeaders.CE_PREFIX + "%s";
+ private static final String DATACONTENTTYPE_NULL = null;
+ private static final byte[] DATAPAYLOAD_NULL = null;
+
+
+ @Test
+ public void testRequestWithStructured() {
+ Stream<CloudEvent> cloudEventStream = Data.allEventsWithoutExtensions();
+ //String expectedContentType = CSVFormat.INSTANCE.serializedContentType();
+ cloudEventStream.forEach(event -> {
+ byte[] expectedBuffer = CSVFormat.INSTANCE.serialize(event);
+
+ String topic = "test";
+ String keys = "keys";
+ String tags = "tags";
+
+ Message message = StructuredMessageReader
+ .from(event, CSVFormat.INSTANCE)
+ .read(OMSMessageFactory.createWriter(topic, keys, tags));
+
+ assertThat(message.getTopic())
+ .isEqualTo(topic);
+ assertThat(message.getKey())
+ .isEqualTo(keys);
+ assertThat(message.getTag())
+ .isEqualTo(tags);
+ assertThat(message.getBody())
+ .isEqualTo(expectedBuffer);
+ });
+
+ }
+
+ @Test
+ public void testRequestWithBinary() {
+ Stream<Arguments> argumentsStream = binaryTestArguments();
+ String topic = "test";
+ String keys = "keys";
+ String tags = "tags";
+ argumentsStream.forEach(argument -> {
+ Message message = OMSMessageFactory
+ .createWriter(topic, keys, tags)
+ .writeBinary(argument.cloudEvent);
+
+ assertThat(message.getTopic())
+ .isEqualTo(topic);
+ assertThat(message.getKey())
+ .isEqualTo(keys);
+ assertThat(message.getTag())
+ .isEqualTo(tags);
+ assertThat(message.getBody())
+ .isEqualTo(argument.body);
+ assertThat(message.getUserProperties()
+ .keySet().containsAll(argument.properties.keySet()));
+ assertThat(message.getUserProperties()
+ .values().containsAll(argument.properties.values()));
+
+
+ });
+
+ }
+
+ private Stream<Arguments> binaryTestArguments() {
+
+ return Stream.of(
+ // V03
+ new Arguments(
+ Data.V03_MIN,
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property("ignored", "ignore")
+ ),
+ DATAPAYLOAD_NULL
+ ),
+ new Arguments(
+ Data.V03_WITH_JSON_DATA,
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV03.SCHEMAURL, Data.DATASCHEMA.toString()),
+ property(CloudEventV03.SUBJECT, Data.SUBJECT),
+ property(CloudEventV03.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignore")
+ ),
+ Data.DATA_JSON_SERIALIZED
+
+ ),
+ new Arguments(
+ Data.V03_WITH_JSON_DATA_WITH_EXT_STRING,
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV03.SCHEMAURL, Data.DATASCHEMA.toString()),
+ property(CloudEventV03.SUBJECT, Data.SUBJECT),
+ property(CloudEventV03.TIME, Time.writeTime(Data.TIME)),
+ property("astring", "aaa"),
+ property("aboolean", "true"),
+ property("anumber", "10"),
+ property("ignored", "ignored")
+ ),
+ Data.DATA_JSON_SERIALIZED
+
+ ),
+ new Arguments(
+ Data.V03_WITH_XML_DATA,
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV03.SUBJECT, Data.SUBJECT),
+ property(CloudEventV03.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+
+ Data.DATA_XML_SERIALIZED
+
+ ),
+ new Arguments(
+ Data.V03_WITH_TEXT_DATA,
+ properties(
+ property(CloudEventV03.SPECVERSION, SpecVersion.V03.toString()),
+ property(CloudEventV03.ID, Data.ID),
+ property(CloudEventV03.TYPE, Data.TYPE),
+ property(CloudEventV03.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV03.SUBJECT, Data.SUBJECT),
+ property(CloudEventV03.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+
+ Data.DATA_TEXT_SERIALIZED
+
+ ),
+ // V1
+ new Arguments(
+ Data.V1_MIN,
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property("ignored", "ignored")
+ ),
+
+ DATAPAYLOAD_NULL
+
+ ),
+ new Arguments(
+ Data.V1_WITH_JSON_DATA,
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV1.DATASCHEMA, Data.DATASCHEMA.toString()),
+ property(CloudEventV1.SUBJECT, Data.SUBJECT),
+ property(CloudEventV1.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+
+ Data.DATA_JSON_SERIALIZED
+
+ ),
+ new Arguments(
+ Data.V1_WITH_JSON_DATA_WITH_EXT_STRING,
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV1.DATASCHEMA, Data.DATASCHEMA.toString()),
+ property(CloudEventV1.SUBJECT, Data.SUBJECT),
+ property(CloudEventV1.TIME, Time.writeTime(Data.TIME)),
+ property("astring", "aaa"),
+ property("aboolean", "true"),
+ property("anumber", "10"),
+ property("ignored", "ignored")
+ ),
+
+ Data.DATA_JSON_SERIALIZED
+
+ ),
+ new Arguments(
+ Data.V1_WITH_XML_DATA,
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV1.SUBJECT, Data.SUBJECT),
+ property(CloudEventV1.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+
+ Data.DATA_XML_SERIALIZED
+
+ ),
+ new Arguments(
+ Data.V1_WITH_TEXT_DATA,
+ properties(
+ property(CloudEventV1.SPECVERSION, SpecVersion.V1.toString()),
+ property(CloudEventV1.ID, Data.ID),
+ property(CloudEventV1.TYPE, Data.TYPE),
+ property(CloudEventV1.SOURCE, Data.SOURCE.toString()),
+ property(CloudEventV1.SUBJECT, Data.SUBJECT),
+ property(CloudEventV1.TIME, Time.writeTime(Data.TIME)),
+ property("ignored", "ignored")
+ ),
+
+ Data.DATA_TEXT_SERIALIZED
+
+ )
+ );
+ }
+
+ private static final AbstractMap.SimpleEntry<String, String> property(final String name, final String value) {
+ return name.equalsIgnoreCase("ignored") ?
+ new AbstractMap.SimpleEntry<>(name, value) :
+ new AbstractMap.SimpleEntry<>(String.format(PREFIX_TEMPLATE, name), value);
+ }
+
+ @SafeVarargs
+ private static final Map<String, String> properties(final AbstractMap.SimpleEntry<String, String>... entries) {
+ return Stream.of(entries)
+ .collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
+
+ }
+
+ private class Arguments {
+ CloudEvent cloudEvent;
+ Map<String, String> properties;
+ byte[] body;
+
+ public Arguments(CloudEvent cloudEvent, Map<String, String> properties, byte[] body) {
+ this.cloudEvent = cloudEvent;
+ this.properties = properties;
+ this.body = body;
+ }
+
+
+ }
+}
diff --git a/tool/license/allowed-licenses.txt b/tool/license/allowed-licenses.txt
index aeb2980..976d6c3 100644
--- a/tool/license/allowed-licenses.txt
+++ b/tool/license/allowed-licenses.txt
@@ -879,6 +879,16 @@
"moduleLicense": "Apache License, Version 2.0",
"moduleVersion": "1.28",
"moduleName": "org.yaml:snakeyaml"
+ },
+ {
+ "moduleLicense": "The Apache Software License, Version 2.0",
+ "moduleVersion": "2.2.0",
+ "moduleName": "io.cloudevents:cloudevents-api"
+ },
+ {
+ "moduleLicense": "The Apache Software License, Version 2.0",
+ "moduleVersion": "2.2.0",
+ "moduleName": "io.cloudevents:cloudevents-core"
}
]
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@eventmesh.apache.org
For additional commands, e-mail: commits-help@eventmesh.apache.org