Skip to content

Commit a4bc7a8

Browse files
authored
Protobuf: Enhance textual content-types detection (#444)
- Move content-type introspection in a separate support class. - Add unit tests to ensure introspection is correct. Signed-off-by: Day, Jeremy(jday) <jday@paypal.com>
1 parent 4784f03 commit a4bc7a8

3 files changed

Lines changed: 104 additions & 10 deletions

File tree

formats/protobuf/src/main/java/io/cloudevents/protobuf/ProtoSerializer.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,6 @@ public static CloudEvent toProto(io.cloudevents.CloudEvent ce) throws InvalidPro
7777
}
7878
}
7979

80-
// The proto spec says all text data should go into the text field. It is really difficult to figure out every case
81-
// of text data based on the media type though, so I am just going to check for some common cases.
82-
private static boolean isTextType(String type) {
83-
if (type == null) {
84-
return false;
85-
}
86-
return type.startsWith("text/") || "application/json".equals(type) || "application/xml".equals(type);
87-
}
88-
8980
/**
9081
* Defines a {@link CloudEventContextWriter} that will allow setting the attributes within a Protobuf object.
9182
*/
@@ -272,9 +263,16 @@ public CloudEvent end(CloudEventData data) throws CloudEventRWException {
272263
throw CloudEventRWException.newDataConversion(e, "byte[]", "com.google.protobuf.Any");
273264
}
274265
protoBuilder.setProtoData(dataAsAny);
275-
} else if (isTextType(dataContentType)) {
266+
} else if (ProtoSupport.isTextContent(dataContentType)) {
267+
/**
268+
* The protobuf format specification states that textual data must
269+
* be carried in the 'text_data' field.
270+
*/
276271
protoBuilder.setTextDataBytes(ByteString.copyFrom(data.toBytes()));
277272
} else {
273+
/**
274+
* All other content is assumed to be binary.
275+
*/
278276
ByteString byteString = ByteString.copyFrom(data.toBytes());
279277
protoBuilder.setBinaryData(byteString);
280278
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2018-Present The CloudEvents Authors
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package io.cloudevents.protobuf;
19+
20+
/**
21+
* General support functions.
22+
*/
23+
24+
final class ProtoSupport {
25+
26+
// Prevent Instantiation
27+
private ProtoSupport() {
28+
}
29+
30+
/**
31+
* Determine if the given content type indicates that
32+
* content is textual.
33+
*/
34+
static boolean isTextContent(String contentType) {
35+
36+
if (contentType == null) {
37+
return false;
38+
}
39+
40+
return contentType.startsWith("text/")
41+
|| "application/json".equals(contentType)
42+
|| "application/xml".equals(contentType)
43+
|| contentType.endsWith("+json")
44+
|| contentType.endsWith("+xml")
45+
;
46+
}
47+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2018-Present The CloudEvents Authors
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
18+
package io.cloudevents.protobuf;
19+
20+
import org.junit.jupiter.params.ParameterizedTest;
21+
import org.junit.jupiter.params.provider.Arguments;
22+
import org.junit.jupiter.params.provider.MethodSource;
23+
24+
import java.io.IOException;
25+
import java.util.stream.Stream;
26+
27+
import static org.assertj.core.api.Assertions.assertThat;
28+
29+
public class ProtoSupportTest {
30+
31+
@ParameterizedTest
32+
@MethodSource("textContentArguments")
33+
public void serialize(String contentType, boolean isText) throws IOException {
34+
35+
assertThat(isText).isEqualTo(ProtoSupport.isTextContent(contentType));
36+
}
37+
38+
// Test Data set for contentType text determination.
39+
public static Stream<Arguments> textContentArguments() {
40+
return Stream.of(
41+
Arguments.of("application/json", true),
42+
Arguments.of("application/xml", true),
43+
Arguments.of("text/plain", true),
44+
Arguments.of("application/protobuf", false),
45+
Arguments.of("application/fubar+xml", true),
46+
Arguments.of("application/fubar+json", true)
47+
);
48+
}
49+
}

0 commit comments

Comments
 (0)