Skip to content

Commit

Permalink
Protobuf: Enhance textual content-types detection (#444)
Browse files Browse the repository at this point in the history
- 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>
  • Loading branch information
JemDay committed Jan 31, 2022
1 parent 4784f03 commit a4bc7a8
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,6 @@ public static CloudEvent toProto(io.cloudevents.CloudEvent ce) throws InvalidPro
}
}

// The proto spec says all text data should go into the text field. It is really difficult to figure out every case
// of text data based on the media type though, so I am just going to check for some common cases.
private static boolean isTextType(String type) {
if (type == null) {
return false;
}
return type.startsWith("text/") || "application/json".equals(type) || "application/xml".equals(type);
}

/**
* Defines a {@link CloudEventContextWriter} that will allow setting the attributes within a Protobuf object.
*/
Expand Down Expand Up @@ -272,9 +263,16 @@ public CloudEvent end(CloudEventData data) throws CloudEventRWException {
throw CloudEventRWException.newDataConversion(e, "byte[]", "com.google.protobuf.Any");
}
protoBuilder.setProtoData(dataAsAny);
} else if (isTextType(dataContentType)) {
} else if (ProtoSupport.isTextContent(dataContentType)) {
/**
* The protobuf format specification states that textual data must
* be carried in the 'text_data' field.
*/
protoBuilder.setTextDataBytes(ByteString.copyFrom(data.toBytes()));
} else {
/**
* All other content is assumed to be binary.
*/
ByteString byteString = ByteString.copyFrom(data.toBytes());
protoBuilder.setBinaryData(byteString);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.protobuf;

/**
* General support functions.
*/

final class ProtoSupport {

// Prevent Instantiation
private ProtoSupport() {
}

/**
* Determine if the given content type indicates that
* content is textual.
*/
static boolean isTextContent(String contentType) {

if (contentType == null) {
return false;
}

return contentType.startsWith("text/")
|| "application/json".equals(contentType)
|| "application/xml".equals(contentType)
|| contentType.endsWith("+json")
|| contentType.endsWith("+xml")
;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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.protobuf;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.util.stream.Stream;

import static org.assertj.core.api.Assertions.assertThat;

public class ProtoSupportTest {

@ParameterizedTest
@MethodSource("textContentArguments")
public void serialize(String contentType, boolean isText) throws IOException {

assertThat(isText).isEqualTo(ProtoSupport.isTextContent(contentType));
}

// Test Data set for contentType text determination.
public static Stream<Arguments> textContentArguments() {
return Stream.of(
Arguments.of("application/json", true),
Arguments.of("application/xml", true),
Arguments.of("text/plain", true),
Arguments.of("application/protobuf", false),
Arguments.of("application/fubar+xml", true),
Arguments.of("application/fubar+json", true)
);
}
}

0 comments on commit a4bc7a8

Please sign in to comment.