diff --git a/.github/workflows/branch.yaml b/.github/workflows/branch.yaml index 4c5f60743..06c75437b 100644 --- a/.github/workflows/branch.yaml +++ b/.github/workflows/branch.yaml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [ 8, 11 ] + java: [ 8, 11, 17 ] steps: - uses: actions/checkout@v2 - name: Setup java @@ -20,8 +20,9 @@ jobs: with: java-version: ${{ matrix.java }} - run: | - mvn clean install -DskipTests -B - mvn verify -B + ./mvnw clean install -DskipTests -B + ./mvnw verify -B + deploy: runs-on: ubuntu-latest name: Deploy @@ -38,7 +39,7 @@ jobs: gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase - name: Publish to Apache Maven Central - run: mvn clean deploy -Drelease -DskipTests -B + run: ./mvnw clean deploy -Drelease -DskipTests -B env: MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }} MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} diff --git a/.github/workflows/bump.yaml b/.github/workflows/bump.yaml index 3636cb5b2..86ca4215b 100644 --- a/.github/workflows/bump.yaml +++ b/.github/workflows/bump.yaml @@ -19,7 +19,7 @@ jobs: with: java-version: 8 - name: Bump version using Maven - run: 'mvn versions:set -DnewVersion=$NEW_VERSION -DgenerateBackupPoms=false -B' + run: './mvnw versions:set -DnewVersion=$NEW_VERSION -DgenerateBackupPoms=false -B' - name: Bump version in docs if: ${{ !endsWith(github.event.inputs.version, 'SNAPSHOT') }} run: 'find . -type f -name "*.md" -exec sed -i -e "s+[a-zA-Z0-9.-]*<\/version>+$NEW_VERSION+g" {} +' diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 57780b56f..2f808c92b 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -22,5 +22,6 @@ jobs: java-version: ${{ matrix.java }} distribution: 'temurin' - run: | - mvn clean install -DskipTests -B - mvn verify -B + ./mvnw clean install -DskipTests -B + ./mvnw verify -B + ./mvnw javadoc:javadoc diff --git a/amqp/pom.xml b/amqp/pom.xml index cff9ac2d9..ce8248b51 100644 --- a/amqp/pom.xml +++ b/amqp/pom.xml @@ -6,7 +6,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT cloudevents-amqp-proton diff --git a/api/pom.xml b/api/pom.xml index 885668ba0..0c54d7b32 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -24,7 +24,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT cloudevents-api diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 5439585d5..4661dcfd3 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -21,7 +21,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT cloudevents-benchmarks diff --git a/bom/pom.xml b/bom/pom.xml index c7b6eaaff..fb7326dcf 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -22,7 +22,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT cloudevents-bom diff --git a/core/pom.xml b/core/pom.xml index e037daa15..35f9c2643 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -22,7 +22,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT cloudevents-core diff --git a/docs/amqp-proton.md b/docs/amqp-proton.md index f6a456c04..c2bc150cc 100644 --- a/docs/amqp-proton.md +++ b/docs/amqp-proton.md @@ -18,7 +18,7 @@ binding for CloudEvents: io.cloudevents cloudevents-amqp-proton - 2.3.0 + 2.4.2 ``` diff --git a/docs/api.md b/docs/api.md index 1de08596f..66dbf2ba7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -17,7 +17,7 @@ For Maven based projects, use the following dependency: io.cloudevents cloudevents-api - 2.3.0 + 2.4.2 ``` diff --git a/docs/core.md b/docs/core.md index fcafac13d..36be5efb8 100644 --- a/docs/core.md +++ b/docs/core.md @@ -16,7 +16,7 @@ For Maven based projects, use the following dependency: io.cloudevents cloudevents-core - 2.3.0 + 2.4.2 ``` diff --git a/docs/http-basic.md b/docs/http-basic.md index f2cb67aa2..2b58934a6 100644 --- a/docs/http-basic.md +++ b/docs/http-basic.md @@ -27,7 +27,7 @@ HTTP Transport: io.cloudevents cloudevents-http-basic - 2.3.0 + 2.4.2 ``` diff --git a/docs/http-jakarta-restful-ws.md b/docs/http-jakarta-restful-ws.md index a7f08fefb..1fa123e3a 100644 --- a/docs/http-jakarta-restful-ws.md +++ b/docs/http-jakarta-restful-ws.md @@ -14,7 +14,7 @@ RESTful Web Services Binding: io.cloudevents cloudevents-http-restful-ws - 2.3.0 + 2.4.2 ``` diff --git a/docs/http-vertx.md b/docs/http-vertx.md index bdecc9a79..494b88840 100644 --- a/docs/http-vertx.md +++ b/docs/http-vertx.md @@ -14,7 +14,7 @@ HTTP Transport: io.cloudevents cloudevents-http-vertx - 2.3.0 + 2.4.2 ``` diff --git a/docs/json-jackson.md b/docs/json-jackson.md index 6bb2a7c6a..1aac7c33a 100644 --- a/docs/json-jackson.md +++ b/docs/json-jackson.md @@ -17,7 +17,7 @@ For Maven based projects, use the following dependency: io.cloudevents cloudevents-json-jackson - 2.3.0 + 2.4.2 ``` diff --git a/docs/kafka.md b/docs/kafka.md index bcdeb80ae..48fe54d8c 100644 --- a/docs/kafka.md +++ b/docs/kafka.md @@ -17,7 +17,7 @@ For Maven based projects, use the following to configure the io.cloudevents cloudevents-kafka - 2.3.0 + 2.4.2 ``` diff --git a/docs/protobuf.md b/docs/protobuf.md index 64d7c4318..902c68a93 100644 --- a/docs/protobuf.md +++ b/docs/protobuf.md @@ -17,7 +17,7 @@ For Maven based projects, use the following dependency: io.cloudevents cloudevents-protobuf - 2.3.0 + 2.4.2 ``` diff --git a/docs/spring.md b/docs/spring.md index b9dab8ed4..89381b607 100644 --- a/docs/spring.md +++ b/docs/spring.md @@ -17,7 +17,7 @@ For Maven based projects, use the following dependency: io.cloudevents cloudevents-spring - 2.3.0 + 2.4.2 ``` diff --git a/examples/amqp-proton/pom.xml b/examples/amqp-proton/pom.xml index 5b888ae31..0a0177f6f 100644 --- a/examples/amqp-proton/pom.xml +++ b/examples/amqp-proton/pom.xml @@ -3,7 +3,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/examples/basic-http/pom.xml b/examples/basic-http/pom.xml index 27b162cda..7fbb38045 100644 --- a/examples/basic-http/pom.xml +++ b/examples/basic-http/pom.xml @@ -21,7 +21,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/examples/kafka/pom.xml b/examples/kafka/pom.xml index f20ca8320..4098bfeae 100644 --- a/examples/kafka/pom.xml +++ b/examples/kafka/pom.xml @@ -5,7 +5,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/examples/pom.xml b/examples/pom.xml index 9a7ee82be..3534c038a 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -5,7 +5,7 @@ cloudevents-parent io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/examples/restful-ws-quarkus/pom.xml b/examples/restful-ws-quarkus/pom.xml index c5c2e691c..d9f77ab3f 100644 --- a/examples/restful-ws-quarkus/pom.xml +++ b/examples/restful-ws-quarkus/pom.xml @@ -5,7 +5,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 cloudevents-restful-ws-quarkus-example diff --git a/examples/restful-ws-spring-boot/pom.xml b/examples/restful-ws-spring-boot/pom.xml index 9b5a25bd8..b26966e35 100644 --- a/examples/restful-ws-spring-boot/pom.xml +++ b/examples/restful-ws-spring-boot/pom.xml @@ -5,7 +5,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/examples/spring-function/pom.xml b/examples/spring-function/pom.xml index bd9c0ecb8..3608ca042 100644 --- a/examples/spring-function/pom.xml +++ b/examples/spring-function/pom.xml @@ -5,7 +5,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/examples/spring-reactive/pom.xml b/examples/spring-reactive/pom.xml index 06313d9ea..5da76d433 100644 --- a/examples/spring-reactive/pom.xml +++ b/examples/spring-reactive/pom.xml @@ -5,7 +5,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/examples/spring-rsocket/pom.xml b/examples/spring-rsocket/pom.xml index 348b4ab64..1660bfa39 100644 --- a/examples/spring-rsocket/pom.xml +++ b/examples/spring-rsocket/pom.xml @@ -5,7 +5,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/examples/vertx/pom.xml b/examples/vertx/pom.xml index 31d56c4a5..132b2fa28 100644 --- a/examples/vertx/pom.xml +++ b/examples/vertx/pom.xml @@ -5,7 +5,7 @@ cloudevents-examples io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 diff --git a/formats/json-jackson/pom.xml b/formats/json-jackson/pom.xml index a1a8146e1..9262d30ca 100644 --- a/formats/json-jackson/pom.xml +++ b/formats/json-jackson/pom.xml @@ -22,7 +22,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../../pom.xml diff --git a/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormat.java b/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormat.java index 8454a5a22..542405894 100644 --- a/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormat.java +++ b/formats/json-jackson/src/main/java/io/cloudevents/jackson/JsonFormat.java @@ -47,7 +47,7 @@ public final class JsonFormat implements EventFormat { /** * JSON Data Content Type Discriminator */ - private static final Pattern JSON_CONTENT_TYPE_PATTERN = Pattern.compile("^(application|text)\\/([a-zA-Z]+\\+)?json$"); + private static final Pattern JSON_CONTENT_TYPE_PATTERN = Pattern.compile("^(application|text)\\/([a-zA-Z]+\\+)?json(;.*)*$"); private final ObjectMapper mapper; private final JsonFormatOptions options; diff --git a/formats/json-jackson/src/test/java/io/cloudevents/jackson/JsonFormatTest.java b/formats/json-jackson/src/test/java/io/cloudevents/jackson/JsonFormatTest.java index 7e40fe98e..253e2fc89 100644 --- a/formats/json-jackson/src/test/java/io/cloudevents/jackson/JsonFormatTest.java +++ b/formats/json-jackson/src/test/java/io/cloudevents/jackson/JsonFormatTest.java @@ -47,6 +47,22 @@ class JsonFormatTest { private final ObjectMapper mapper = new ObjectMapper(); + @ParameterizedTest + @MethodSource("jsonContentTypes") + void isJsonContentType(String contentType) { + boolean json = JsonFormat.dataIsJsonContentType(contentType); + + assertThat(json).isTrue(); + } + + @ParameterizedTest + @MethodSource("wrongJsonContentTypes") + void isNotJsonContentType(String contentType) { + boolean json = JsonFormat.dataIsJsonContentType(contentType); + + assertThat(json).isFalse(); + } + @ParameterizedTest @MethodSource("serializeTestArgumentsDefault") void serialize(CloudEvent input, String outputFile) throws IOException { @@ -151,6 +167,39 @@ void verifyDeserializeError(String inputFile){ } + static Stream jsonContentTypes() { + return Stream.of( + Arguments.of("application/json"), + Arguments.of("application/json;charset=utf-8"), + Arguments.of("application/json;\tcharset = \"utf-8\""), + Arguments.of("application/cloudevents+json;charset=UTF-8"), + Arguments.of("text/json"), + Arguments.of("text/json;charset=utf-8"), + Arguments.of("text/cloudevents+json;charset=UTF-8"), + Arguments.of("text/json;\twhatever"), + Arguments.of("text/json; boundary=something"), + Arguments.of("text/json;foo=\"bar\""), + Arguments.of("text/json; charset = \"us-ascii\""), + Arguments.of("text/json; \t"), + Arguments.of("text/json;"), + //https://www.rfc-editor.org/rfc/rfc2045#section-5.1 + // any us-ascii char can be part of parameters (except CTRLs and tspecials) + Arguments.of("text/json; char-set = $!#$%&'*+.^_`|"), + Arguments.of((Object) null) + ); + } + + static Stream wrongJsonContentTypes() { + return Stream.of( + Arguments.of("applications/json"), + Arguments.of("application/jsom"), + Arguments.of("application/jsonwrong"), + Arguments.of("text/json "), + Arguments.of("text/json ;"), + Arguments.of("test/json") + ); + } + public static Stream serializeTestArgumentsDefault() { return Stream.of( Arguments.of(V03_MIN, "v03/min.json"), diff --git a/formats/protobuf/pom.xml b/formats/protobuf/pom.xml index 0a8a2f7f8..a7b223087 100644 --- a/formats/protobuf/pom.xml +++ b/formats/protobuf/pom.xml @@ -23,7 +23,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../../pom.xml diff --git a/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoDataWrapper.java b/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoDataWrapper.java index f4b87f5ea..3316787fc 100644 --- a/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoDataWrapper.java +++ b/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoDataWrapper.java @@ -16,8 +16,11 @@ */ package io.cloudevents.protobuf; +import com.google.protobuf.Any; import com.google.protobuf.Message; +import java.util.Arrays; + class ProtoDataWrapper implements ProtoCloudEventData { private final Message protoMessage; @@ -35,4 +38,49 @@ public Message getMessage() { public byte[] toBytes() { return protoMessage.toByteArray(); } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return (true); + } + + if (!(obj instanceof ProtoDataWrapper)) { + return (false); + } + + // Now compare the actual data + ProtoDataWrapper rhs = (ProtoDataWrapper) obj; + + if (this.getMessage() == rhs.getMessage()){ + return true; + } + + // This is split out for readability. + // Compare the content in terms onf an 'Any'. + // - Verify the types match + // - Verify the values match. + + final Any lhsAny = getAsAny(this.getMessage()); + final Any rhsAny = getAsAny(rhs.getMessage()); + + final boolean typesMatch = (ProtoSupport.extractMessageType(lhsAny).equals(ProtoSupport.extractMessageType(rhsAny))); + + if (typesMatch) { + return lhsAny.getValue().equals(rhsAny.getValue()); + } else { + return false; + } + } + + private Any getAsAny(Message m) { + + if (m instanceof Any) { + return (Any) m; + } + + return Any.pack(m); + + } } diff --git a/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoDeserializer.java b/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoDeserializer.java index dd55973d5..dc1f54c27 100644 --- a/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoDeserializer.java +++ b/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoDeserializer.java @@ -105,7 +105,7 @@ public , R> R read( data = BytesCloudEventData.wrap(raw); break; case PROTO_DATA: - data = new ProtoAccessor(this.protoCe); + data = new ProtoDataWrapper(this.protoCe.getProtoData()); break; case DATA_NOT_SET: break; @@ -130,22 +130,4 @@ private OffsetDateTime covertProtoTimestamp(com.google.protobuf.Timestamp timest return instant.atOffset(ZoneOffset.UTC); } - private static class ProtoAccessor implements ProtoCloudEventData { - - private final Message message; - - ProtoAccessor(CloudEvent proto){ - this.message = proto.getProtoData(); - } - - @Override - public Message getMessage() { - return message; - } - - @Override - public byte[] toBytes() { - return message.toByteArray(); - } - } } diff --git a/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSerializer.java b/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSerializer.java index bc240d84d..2f76d81b8 100644 --- a/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSerializer.java +++ b/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSerializer.java @@ -16,11 +16,8 @@ */ package io.cloudevents.protobuf; -import com.google.protobuf.Any; -import com.google.protobuf.ByteString; +import com.google.protobuf.*; import com.google.protobuf.Descriptors.FieldDescriptor; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Timestamp; import io.cloudevents.CloudEventData; import io.cloudevents.SpecVersion; import io.cloudevents.core.CloudEventUtils; @@ -248,8 +245,14 @@ public CloudEvent end(CloudEventData data) throws CloudEventRWException { // If it's a proto message we can handle that directly. if (data instanceof ProtoCloudEventData) { final ProtoCloudEventData protoData = (ProtoCloudEventData) data; - if (protoData.getMessage() != null) { - protoBuilder.setProtoData(Any.pack(protoData.getMessage())); + final Message m = protoData.getMessage(); + if (m != null) { + // If it's already an 'Any' don't re-pack it. + if (m instanceof Any) { + protoBuilder.setProtoData((Any) m); + }else { + protoBuilder.setProtoData(Any.pack(m)); + } } } else { if (Objects.equals(dataContentType, PROTO_DATA_CONTENT_TYPE)) { diff --git a/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSupport.java b/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSupport.java index a2c079359..a4cf0ec1d 100644 --- a/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSupport.java +++ b/formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSupport.java @@ -17,6 +17,8 @@ package io.cloudevents.protobuf; +import com.google.protobuf.Any; + /** * General support functions. */ @@ -44,4 +46,16 @@ static boolean isTextContent(String contentType) { || contentType.endsWith("+xml") ; } + + /** + * Extract the Protobuf message type from an 'Any' + * @param anyMessage + * @return + */ + static String extractMessageType(final Any anyMessage) { + final String typeUrl = anyMessage.getTypeUrl(); + final String[] parts = typeUrl.split("/"); + + return parts[parts.length -1]; + } } diff --git a/formats/protobuf/src/test/java/io/cloudevents/protobuf/ProtoDataWrapperTest.java b/formats/protobuf/src/test/java/io/cloudevents/protobuf/ProtoDataWrapperTest.java new file mode 100644 index 000000000..232af3209 --- /dev/null +++ b/formats/protobuf/src/test/java/io/cloudevents/protobuf/ProtoDataWrapperTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2018-Present The CloudEvents Authors + *

+ * 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 + *

+ * 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 io.cloudevents.protobuf; + +import com.google.protobuf.Any; +import com.google.protobuf.Message; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; + +class ProtoDataWrapperTest { + + // == Closing Quotes for 2023/02/23 + private final Message quote1 = io.cloudevents.test.v1.proto.Test.Quote.newBuilder() + .setPrice(io.cloudevents.test.v1.proto.Test.Decimal.newBuilder().setScale(2).setUnscaled(7519).build()) + .setHigh(io.cloudevents.test.v1.proto.Test.Decimal.newBuilder().setScale(2).setUnscaled(7628).build()) + .setSymbol("PYPL") + .build(); + + private final Message quote2 = io.cloudevents.test.v1.proto.Test.Quote.newBuilder() + .setPrice(io.cloudevents.test.v1.proto.Test.Decimal.newBuilder().setScale(2).setUnscaled(13097).build()) + .setHigh(io.cloudevents.test.v1.proto.Test.Decimal.newBuilder().setScale(2).setUnscaled(13170).build()) + .setSymbol("IBM") + .build(); + + @Test + public void testBasic() { + + ProtoDataWrapper pdw = new ProtoDataWrapper(quote1); + + assertThat(pdw).isNotNull(); + assertThat(pdw.getMessage()).isNotNull(); + assertThat(pdw.toBytes()).withFailMessage("toBytes was NULL").isNotNull(); + assertThat(pdw.toBytes()).withFailMessage("toBytes[] returned empty array").hasSizeGreaterThan(0); + + // This is current behavior and will probably change in the next version. + assertThat(pdw.getMessage()).isInstanceOf(io.cloudevents.test.v1.proto.Test.Quote.class); + } + + @Test + public void testEquality() { + + ProtoDataWrapper pdw1 = new ProtoDataWrapper(quote1); + ProtoDataWrapper pdw2 = new ProtoDataWrapper(quote1); + + ProtoDataWrapper pdw3 = new ProtoDataWrapper(quote2); + + assertThat(pdw1).withFailMessage("Self Equality Failed - 1").isEqualTo(pdw1); + assertThat(pdw2).withFailMessage("Self Equality Failed - 2").isEqualTo(pdw2); + assertThat(pdw1).withFailMessage("Self Equality Failed - 3").isEqualTo(pdw2); + assertThat(pdw2).withFailMessage("Self Equality Failed - 4").isEqualTo(pdw1); + + assertThat(pdw1).withFailMessage("Non-Equality Failed - 1").isNotEqualTo(null); + assertThat(pdw1).withFailMessage("Non-Equality Failed - 2").isNotEqualTo(pdw3); + assertThat(pdw3).withFailMessage("Non-Equality Failed - 3").isNotEqualTo(pdw2); + + } + + /** + * Verify the generated bytes[] is correct + */ + @Test + public void testBytes() { + + // Our expected 'Any' + final Any expAny = Any.pack(quote1); + + // Our expected 'data' + final byte[] expData = expAny.toByteArray(); + + // Build the wrapper + final ProtoDataWrapper pdw = new ProtoDataWrapper(quote1); + + // Get the actual data + final byte[] actData = pdw.toBytes(); + + // Verify + Arrays.equals(expData, actData); + + } + +} diff --git a/formats/protobuf/src/test/java/io/cloudevents/protobuf/ProtobufFormatTest.java b/formats/protobuf/src/test/java/io/cloudevents/protobuf/ProtobufFormatTest.java index 539811e51..c611ce2bb 100644 --- a/formats/protobuf/src/test/java/io/cloudevents/protobuf/ProtobufFormatTest.java +++ b/formats/protobuf/src/test/java/io/cloudevents/protobuf/ProtobufFormatTest.java @@ -22,19 +22,20 @@ import io.cloudevents.core.format.EventFormat; import io.cloudevents.core.provider.EventFormatProvider; import io.cloudevents.v1.proto.CloudEvent; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.net.URI; +import java.net.URL; import java.time.OffsetDateTime; import java.time.ZoneId; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.net.URL; +import java.util.UUID; import java.util.stream.Stream; import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat; @@ -45,6 +46,46 @@ class ProtobufFormatTest { EventFormat format = new ProtobufFormat(); + public static Stream serializeTestArgumentsDefault() { + return Stream.of( + Arguments.of(V1_MIN, "v1/min.proto.json"), + Arguments.of(V1_WITH_JSON_DATA, "v1/json_data.proto.json"), + Arguments.of(V1_WITH_TEXT_DATA, "v1/text_data.proto.json"), + Arguments.of(V1_WITH_JSON_DATA_WITH_EXT, "v1/json_data_with_ext.proto.json"), + Arguments.of(V1_WITH_XML_DATA, "v1/xml_data.proto.json"), + Arguments.of(V1_WITH_BINARY_EXT, "v1/binary_ext.proto.json"), + + Arguments.of(V03_MIN, "v03/min.proto.json") + + ); + } + + public static Stream roundTripTestArguments() { + return Stream.of( + "v1/min.proto.json", + "v1/json_data.proto.json", + "v1/text_data.proto.json", + "v1/json_data_with_ext.proto.json", + "v1/xml_data.proto.json", + "v1/binary_ext.proto.json", + + "v03/min.proto.json" + ); + } + + private static Message loadProto(String filename) throws IOException { + CloudEvent.Builder b = CloudEvent.newBuilder(); + JsonFormat.parser().ignoringUnknownFields().merge(getReader(filename), b); + return b.build(); + } + + private static Reader getReader(String filename) throws IOException { + URL file = Thread.currentThread().getContextClassLoader().getResource(filename); + assertThat(file).isNotNull(); + File dataFile = new File(file.getFile()); + return new FileReader(dataFile); + } + @Test public void testRegistration() { EventFormat act = EventFormatProvider.getInstance().resolveFormat("application/cloudevents+protobuf"); @@ -90,6 +131,8 @@ public void serialize(io.cloudevents.CloudEvent input, String jsonFile) throws I } + // ---------------------------------------------------------------- + /** * RoundTrip Test *

@@ -131,46 +174,40 @@ public void roundTripTest(String filename) throws IOException { } - public static Stream serializeTestArgumentsDefault() { - return Stream.of( - Arguments.of(V1_MIN, "v1/min.proto.json"), - Arguments.of(V1_WITH_JSON_DATA, "v1/json_data.proto.json"), - Arguments.of(V1_WITH_TEXT_DATA, "v1/text_data.proto.json"), - Arguments.of(V1_WITH_JSON_DATA_WITH_EXT, "v1/json_data_with_ext.proto.json"), - Arguments.of(V1_WITH_XML_DATA, "v1/xml_data.proto.json"), - Arguments.of(V1_WITH_BINARY_EXT, "v1/binary_ext.proto.json"), - - Arguments.of(V03_MIN, "v03/min.proto.json") - - ); - } - - public static Stream roundTripTestArguments() { - return Stream.of( - "v1/min.proto.json", - "v1/json_data.proto.json", - "v1/text_data.proto.json", - "v1/json_data_with_ext.proto.json", - "v1/xml_data.proto.json", - "v1/binary_ext.proto.json", + /** + * This test verifies the fix for Issue #523 that reported the Data + * portion was being corrupted during multi-step round trips if the + * data was a Protobuf Message. + */ + @Test + public void verifyMultiRoundTrip() { + + io.cloudevents.CloudEvent event = CloudEventBuilder.v1() + .withId(UUID.randomUUID().toString()) + .withSource(SOURCE) + .withType(TYPE) + .withData(ProtoCloudEventData.wrap(io.cloudevents.test.v1.proto.Test.Quote.newBuilder() + .setHigh(io.cloudevents.test.v1.proto.Test.Decimal.newBuilder().setScale(2).setUnscaled(4200).build()) + .setPrice(io.cloudevents.test.v1.proto.Test.Decimal.newBuilder().setScale(2).setUnscaled(1000).build()) + .setSymbol("PYPL") + .build())) + .build(); - "v03/min.proto.json" - ); - } + // 1st Round Trip + byte[] raw1 = format.serialize(event); + io.cloudevents.CloudEvent act1 = format.deserialize(raw1); + assertThat(event).withFailMessage("Mismatch on 1st round trip").isEqualTo(act1); - // ---------------------------------------------------------------- + // 2nd Round Trip + byte[] raw2 = format.serialize(act1); + io.cloudevents.CloudEvent act2 = format.deserialize(raw2); + assertThat(event).withFailMessage("Mismatch on 2nd round trip").isEqualTo(act2); - private static Message loadProto(String filename) throws IOException { - CloudEvent.Builder b = CloudEvent.newBuilder(); - JsonFormat.parser().ignoringUnknownFields().merge(getReader(filename), b); - return b.build(); - } + // 3rd Time's a charm + byte[] raw3 = format.serialize(act2); + io.cloudevents.CloudEvent act3 = format.deserialize(raw3); + assertThat(event).withFailMessage("Mismatch on 3rd round trip").isEqualTo(act3); - private static Reader getReader(String filename) throws IOException { - URL file = Thread.currentThread().getContextClassLoader().getResource(filename); - assertThat(file).isNotNull(); - File dataFile = new File(file.getFile()); - return new FileReader(dataFile); } private byte[] getProtoData(String filename) throws IOException { diff --git a/http/basic/pom.xml b/http/basic/pom.xml index 63cd764a9..975bc0da1 100644 --- a/http/basic/pom.xml +++ b/http/basic/pom.xml @@ -21,7 +21,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../../pom.xml diff --git a/http/restful-ws-integration-tests/pom.xml b/http/restful-ws-integration-tests/pom.xml index 8018ba56e..ce0ecba1f 100644 --- a/http/restful-ws-integration-tests/pom.xml +++ b/http/restful-ws-integration-tests/pom.xml @@ -22,7 +22,7 @@ cloudevents-parent io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../../pom.xml 4.0.0 diff --git a/http/restful-ws-integration-tests/restful-ws-common/pom.xml b/http/restful-ws-integration-tests/restful-ws-common/pom.xml index 63a17aae0..8329eb7e0 100644 --- a/http/restful-ws-integration-tests/restful-ws-common/pom.xml +++ b/http/restful-ws-integration-tests/restful-ws-common/pom.xml @@ -22,7 +22,7 @@ cloudevents-http-restful-ws-integration-tests io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../ 4.0.0 diff --git a/http/restful-ws-integration-tests/restful-ws-jersey/pom.xml b/http/restful-ws-integration-tests/restful-ws-jersey/pom.xml index cb5f2b84e..76cb0cfb4 100644 --- a/http/restful-ws-integration-tests/restful-ws-jersey/pom.xml +++ b/http/restful-ws-integration-tests/restful-ws-jersey/pom.xml @@ -22,7 +22,7 @@ cloudevents-http-restful-ws-integration-tests io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../ 4.0.0 diff --git a/http/restful-ws-integration-tests/restful-ws-resteasy/pom.xml b/http/restful-ws-integration-tests/restful-ws-resteasy/pom.xml index f778f7fa2..e7dabc1d0 100644 --- a/http/restful-ws-integration-tests/restful-ws-resteasy/pom.xml +++ b/http/restful-ws-integration-tests/restful-ws-resteasy/pom.xml @@ -22,7 +22,7 @@ cloudevents-http-restful-ws-integration-tests io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../ 4.0.0 diff --git a/http/restful-ws-integration-tests/restful-ws-spring/pom.xml b/http/restful-ws-integration-tests/restful-ws-spring/pom.xml index c9e329775..10686acff 100644 --- a/http/restful-ws-integration-tests/restful-ws-spring/pom.xml +++ b/http/restful-ws-integration-tests/restful-ws-spring/pom.xml @@ -22,7 +22,7 @@ cloudevents-http-restful-ws-integration-tests io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../ 4.0.0 diff --git a/http/restful-ws/pom.xml b/http/restful-ws/pom.xml index ce58fe5dc..ad960cf87 100644 --- a/http/restful-ws/pom.xml +++ b/http/restful-ws/pom.xml @@ -21,7 +21,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../../pom.xml diff --git a/http/vertx/pom.xml b/http/vertx/pom.xml index be808981a..246d2ac4d 100644 --- a/http/vertx/pom.xml +++ b/http/vertx/pom.xml @@ -22,7 +22,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT ../../pom.xml diff --git a/kafka/pom.xml b/kafka/pom.xml index a7caae6e5..cc17f7641 100644 --- a/kafka/pom.xml +++ b/kafka/pom.xml @@ -23,7 +23,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT cloudevents-kafka diff --git a/pom.xml b/pom.xml index f63d8a47a..32e3f3cdf 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT pom CloudEvents @@ -168,6 +168,7 @@ https://qpid.apache.org/releases/qpid-proton-j-0.33.7/api/ https://fasterxml.github.io/jackson-databind/javadoc/2.10/ + 8 diff --git a/spring/pom.xml b/spring/pom.xml index 945554a87..ec31b0c63 100644 --- a/spring/pom.xml +++ b/spring/pom.xml @@ -23,7 +23,7 @@ io.cloudevents cloudevents-parent - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT cloudevents-spring diff --git a/sql/pom.xml b/sql/pom.xml index 746f8a569..92c153cd5 100644 --- a/sql/pom.xml +++ b/sql/pom.xml @@ -5,7 +5,7 @@ cloudevents-parent io.cloudevents - 2.4.0-SNAPSHOT + 2.4.3-SNAPSHOT 4.0.0 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy