GH-3772 Add Protobuf transformation support

Fixes https://github.com/spring-projects/spring-integration/issues/3772

* Add basic To/From Protocol Buffer's com.google.protobuf.Message transformers.
* Allow the proto_type header to specify the type.
* Add tests.
* add Protobuf docs
* Leverage the Spring ProtobufMessageConverter
* move protobuf-java-util to test dependecies as optional
* protobuf docs improvements
* improve the expected type handling
* expected type expression
* fix indentation
* fix indentation for generated test classes
* suppress style check for proto generated classes
* address the transformer doc format
* fix whats new merge conflict
* fix doc sample code
* Some code clean up; fixing typos
This commit is contained in:
Christian Tzolov
2023-02-09 06:23:25 -05:00
committed by abilan
parent acd8a03d4d
commit 451374dd11
15 changed files with 2054 additions and 5 deletions

1
.gitignore vendored
View File

@@ -31,3 +31,4 @@ vf.gf.dmn-*
hostkey.ser
.springBeans
.sts4-cache
.vscode/

View File

@@ -94,6 +94,7 @@ ext {
mysqlVersion = '8.0.32'
pahoMqttClientVersion = '1.2.5'
postgresVersion = '42.5.4'
protobufVersion = '3.21.12'
r2dbch2Version = '1.0.0.RELEASE'
reactorVersion = '2022.0.3'
resilience4jVersion = '2.0.2'
@@ -542,7 +543,7 @@ project('spring-integration-core') {
optionalApi('com.fasterxml.jackson.module:jackson-module-kotlin') {
exclude group: 'org.jetbrains.kotlin'
}
optionalApi "com.google.protobuf:protobuf-java:$protobufVersion"
optionalApi "com.jayway.jsonpath:json-path:$jsonpathVersion"
optionalApi "com.esotericsoftware:kryo:$kryoVersion"
optionalApi 'io.micrometer:micrometer-core'
@@ -553,6 +554,7 @@ project('spring-integration-core') {
optionalApi "org.apache.avro:avro:$avroVersion"
optionalApi 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor'
testImplementation "com.google.protobuf:protobuf-java-util:$protobufVersion"
testImplementation "org.aspectj:aspectjweaver:$aspectjVersion"
testImplementation 'io.micrometer:micrometer-observation-test'
testImplementation ('io.micrometer:micrometer-tracing-integration-test') {

View File

@@ -0,0 +1,140 @@
/*
* Copyright 2023 the original author or 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
*
* https://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.springframework.integration.transformer;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.expression.FunctionExpression;
import org.springframework.integration.expression.ValueExpression;
import org.springframework.integration.transformer.support.ProtoHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.converter.ProtobufMessageConverter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* A Protocol Buffer transformer to instantiate {@link com.google.protobuf.Message} objects
* from either {@code byte[]} if content type is {@code application/x-protobuf}
* or from {@code String} in case of {@code application/json} content type.
*
* @author Christian Tzolov
*
* @since 6.1
*/
public class FromProtobufTransformer extends AbstractTransformer implements BeanClassLoaderAware {
private final ProtobufMessageConverter protobufMessageConverter;
private ClassLoader beanClassLoader;
private Expression expectedTypeExpression =
new FunctionExpression<Message<?>>((message) -> message.getHeaders().get(ProtoHeaders.TYPE));
private EvaluationContext evaluationContext;
/**
* Construct an instance with the supplied default type to create.
*/
public FromProtobufTransformer() {
this(new ProtobufMessageConverter());
}
/**
* Construct an instance with the supplied default type and ProtobufMessageConverter instance.
* @param protobufMessageConverter the message converter used.
*/
public FromProtobufTransformer(ProtobufMessageConverter protobufMessageConverter) {
Assert.notNull(protobufMessageConverter, "'protobufMessageConverter' must not be null");
this.protobufMessageConverter = protobufMessageConverter;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
/**
* Set an expected protobuf class type.
* Mutually exclusive with {@link #setExpectedTypeExpression} and
* {@link #setExpectedTypeExpressionString}.
* @param expectedType expected protobuf class type.
* @return updated FromProtobufTransformer instance.
*/
public FromProtobufTransformer setExpectedType(Class<? extends com.google.protobuf.Message> expectedType) {
return setExpectedTypeExpression(new ValueExpression<>(expectedType));
}
/**
* Set an expression to evaluate against the message to determine the type id.
* Defaults to{@code headers['proto_type']}. Mutually exclusive with
* {@link #setExpectedType} and {@link #setExpectedTypeExpression}.
* @param expression the expression.
* @return updated FromProtobufTransformer instance.
*/
public FromProtobufTransformer setExpectedTypeExpressionString(String expression) {
return setExpectedTypeExpression(EXPRESSION_PARSER.parseExpression(expression));
}
/**
* Set an expression to evaluate against the message to determine the type.
* Default {@code headers['proto_type']}.
* Mutually exclusive with {@link #setExpectedType} and
* {@link #setExpectedTypeExpressionString}.
* @param expression the expression.
* @return updated FromProtobufTransformer instance.
*/
public FromProtobufTransformer setExpectedTypeExpression(Expression expression) {
Assert.notNull(expression, "'expression' must not be null");
this.expectedTypeExpression = expression;
return this;
}
@Override
protected void onInit() {
this.evaluationContext = IntegrationContextUtils.getEvaluationContext(getBeanFactory());
}
@SuppressWarnings("unchecked")
@Override
protected Object doTransform(Message<?> message) {
Class<? extends com.google.protobuf.Message> targetClass = null;
Object value = this.expectedTypeExpression.getValue(this.evaluationContext, message);
if (value instanceof Class<?>) {
targetClass = (Class<? extends com.google.protobuf.Message>) value;
}
else if (value instanceof String) {
try {
targetClass =
(Class<? extends com.google.protobuf.Message>)
ClassUtils.forName((String) value, this.beanClassLoader);
}
catch (ClassNotFoundException | LinkageError e) {
throw new IllegalStateException(e);
}
}
if (targetClass == null) {
throw new MessageTransformationException(message,
"The 'expectedTypeExpression' (" + this.expectedTypeExpression + ") returned 'null'.");
}
return this.protobufMessageConverter.fromMessage(message, targetClass);
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2023 the original author or 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
*
* https://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.springframework.integration.transformer;
import org.springframework.integration.transformer.support.ProtoHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.ProtobufMessageConverter;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.util.Assert;
/**
* A Protocol Buffer transformer for generated {@link com.google.protobuf.Message} objects.
* <p>
* If the content type is set to {@code application/x-protobuf} (default if no content type),
* then the output message payload is of type byte array.
* <p>
* If the content type is set to {@code application/json} and
* the {@code com.google.protobuf:protobuf-java-util} dependency is on the
* classpath, the output message payload if of type String.
*
* @author Christian Tzolov
*
* @since 6.1
*/
public class ToProtobufTransformer extends AbstractTransformer {
private final ProtobufMessageConverter protobufMessageConverter;
public ToProtobufTransformer() {
this(new ProtobufMessageConverter());
}
public ToProtobufTransformer(ProtobufMessageConverter protobufMessageConverter) {
Assert.notNull(protobufMessageConverter, "'protobufMessageConverter' must not be null");
this.protobufMessageConverter = protobufMessageConverter;
}
@Override
protected Object doTransform(Message<?> message) {
Assert.isInstanceOf(com.google.protobuf.Message.class, message.getPayload(),
"Payload must be an implementation of 'com.google.protobuf.Message'");
MessageHeaderAccessor accessor = new MessageHeaderAccessor(message);
accessor.setHeader(ProtoHeaders.TYPE, message.getPayload().getClass().getName());
if (!message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) {
accessor.setContentType(ProtobufMessageConverter.PROTOBUF);
}
return this.protobufMessageConverter.toMessage(message.getPayload(), accessor.getMessageHeaders());
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2023 the original author or 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
*
* https://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.springframework.integration.transformer.support;
/**
* Pre-defined names and prefixes for Protocol Buffers related headers.
*
* @author Christian Tzolov
*
* @since 6.1
*/
public final class ProtoHeaders {
private ProtoHeaders() {
}
/**
* The prefix for Protocol Buffers specific message headers.
*/
public static final String PREFIX = "proto_";
/**
* The {@code com.google.protobuf.Message} type. By default, it's the fully qualified
* {@code com.google.protobuf.Message} type but can be a key that is mapped to the actual type.
*/
public static final String TYPE = PREFIX + "type";
}

View File

@@ -0,0 +1,240 @@
/*
* Copyright 2023 the original author or 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
*
* https://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.springframework.integration.transformer;
import java.util.Collections;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.transformer.proto.TestClass1;
import org.springframework.integration.transformer.proto.TestClass2;
import org.springframework.integration.transformer.support.ProtoHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
/**
*
* @author Christian Tzolov
*
* @since 6.1
*/
@SpringJUnitConfig
public class ProtoTests {
@Test
void testTransformers(@Autowired ProtoConfig config) {
TestClass1 test = TestClass1.newBuilder()
.setBar("foo")
.setQux(678)
.build();
config.in1().send(new GenericMessage<>(test));
assertThat(config.tapped().receive(0))
.isNotNull()
.extracting(Message::getPayload)
.isInstanceOf(byte[].class);
Message<?> received = config.out().receive(0);
assertThat(received)
.isNotNull()
.extracting(Message::getPayload)
.isEqualTo(test)
.isNotSameAs(test);
assertThat(received.getHeaders().get("flow")).isEqualTo("flow1");
}
@Test
void testTransformersJson(@Autowired ProtoConfig config) {
TestClass1 test = TestClass1.newBuilder()
.setBar("foo")
.setQux(678)
.build();
config.in1().send(new GenericMessage<>(test,
Collections.singletonMap(MessageHeaders.CONTENT_TYPE, "application/json")));
assertThat(config.tapped().receive(0))
.isNotNull()
.extracting(Message::getPayload)
.isInstanceOf(String.class)
.isEqualTo("{\n \"bar\": \"foo\",\n \"qux\": 678\n}");
Message<?> received = config.out().receive(0);
assertThat(received)
.isNotNull()
.extracting(Message::getPayload)
.isEqualTo(test)
.isNotSameAs(test);
assertThat(received.getHeaders().get("flow")).isEqualTo("flow1");
}
@Test
void testMultiTypeTransformers(@Autowired ProtoConfig config) {
TestClass1 test = TestClass1.newBuilder()
.setBar("foo")
.setQux(678)
.build();
config.in2().send(new GenericMessage<>(test));
assertThat(config.tapped().receive(0))
.isNotNull()
.extracting(Message::getPayload)
.isInstanceOf(byte[].class);
Message<?> received = config.out().receive(0);
assertThat(received)
.isNotNull()
.extracting(Message::getPayload)
.isNotEqualTo(test)
.isInstanceOf(TestClass2.class);
assertThat(received.getHeaders().get("flow")).isEqualTo("flow2");
}
@Test
void testMultiTypeTransformersClassName(@Autowired ProtoConfig config) {
TestClass1 test = TestClass1.newBuilder()
.setBar("foo")
.setQux(678)
.build();
config.in3().send(new GenericMessage<>(test));
assertThat(config.tapped().receive(0))
.isNotNull()
.extracting(Message::getPayload)
.isInstanceOf(byte[].class);
Message<?> received = config.out().receive(0);
assertThat(received)
.isNotNull()
.extracting(Message::getPayload)
.isNotEqualTo(test)
.isInstanceOf(TestClass2.class);
assertThat(received.getHeaders().get("flow")).isEqualTo("flow3");
}
@Test
void testTransformersNoHeaderPresent(@Autowired ProtoConfig config) {
TestClass1 test = TestClass1.newBuilder()
.setBar("foo")
.setQux(678)
.build();
config.in4().send(new GenericMessage<>(test));
assertThat(config.tapped().receive(0))
.isNotNull()
.extracting(Message::getPayload)
.isInstanceOf(byte[].class);
Message<?> received = config.out().receive(0);
assertThat(received)
.isNotNull()
.extracting(Message::getPayload)
.isEqualTo(test)
.isNotSameAs(test);
assertThat(received.getHeaders().get("flow")).isEqualTo("flow4");
}
@Configuration
@EnableIntegration
public static class ProtoConfig {
@Bean
public IntegrationFlow flow1() {
return IntegrationFlow.from(in1())
.transform(new ToProtobufTransformer())
.wireTap(tapped())
.transform(new FromProtobufTransformer())
.enrichHeaders(h -> h.header("flow", "flow1"))
.channel(out())
.get();
}
@Bean
public IntegrationFlow flow2() {
return IntegrationFlow.from(in2())
.transform(new ToProtobufTransformer())
.wireTap(tapped())
.enrichHeaders(h -> h.header(ProtoHeaders.TYPE, TestClass2.class, true))
.transform(new FromProtobufTransformer())
.enrichHeaders(h -> h.header("flow", "flow2"))
.channel(out())
.get();
}
@Bean
public IntegrationFlow flow3() {
return IntegrationFlow.from(in3())
.transform(new ToProtobufTransformer())
.wireTap(tapped())
.enrichHeaders(h -> h.header(ProtoHeaders.TYPE, TestClass2.class.getName(),
true))
.transform(new FromProtobufTransformer())
.enrichHeaders(h -> h.header("flow", "flow3"))
.channel(out())
.get();
}
@Bean
public IntegrationFlow flow4() {
return IntegrationFlow.from(in4())
.transform(new ToProtobufTransformer())
.wireTap(tapped())
.enrichHeaders(h -> h.header(ProtoHeaders.TYPE, null, true)
.shouldSkipNulls(false))
.transform(new FromProtobufTransformer()
.setExpectedType(TestClass1.class))
.enrichHeaders(h -> h.header("flow", "flow4"))
.channel(out())
.get();
}
@Bean
public DirectChannel in1() {
return new DirectChannel();
}
@Bean
public DirectChannel in2() {
return new DirectChannel();
}
@Bean
public DirectChannel in3() {
return new DirectChannel();
}
@Bean
public DirectChannel in4() {
return new DirectChannel();
}
@Bean
public PollableChannel tapped() {
return new QueueChannel();
}
@Bean
public PollableChannel out() {
return new QueueChannel();
}
}
}

View File

@@ -0,0 +1,671 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: ProtoTest.proto
package org.springframework.integration.transformer.proto;
/**
* Protobuf type {@code tutorial.TestClass1}
*/
public final class TestClass1 extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:tutorial.TestClass1)
TestClass1OrBuilder {
private static final long serialVersionUID = 0L;
// Use TestClass1.newBuilder() to construct.
private TestClass1(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private TestClass1() {
bar_ = "";
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new TestClass1();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private TestClass1(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
this();
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
int mutable_bitField0_ = 0;
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
case 10: {
com.google.protobuf.ByteString bs = input.readBytes();
bitField0_ |= 0x00000001;
bar_ = bs;
break;
}
case 16: {
bitField0_ |= 0x00000002;
qux_ = input.readInt32();
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass1_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass1_fieldAccessorTable
.ensureFieldAccessorsInitialized(
org.springframework.integration.transformer.proto.TestClass1.class, org.springframework.integration.transformer.proto.TestClass1.Builder.class);
}
private int bitField0_;
public static final int BAR_FIELD_NUMBER = 1;
private volatile java.lang.Object bar_;
/**
* <code>optional string bar = 1;</code>
* @return Whether the bar field is set.
*/
public boolean hasBar() {
return ((bitField0_ & 0x00000001) != 0);
}
/**
* <code>optional string bar = 1;</code>
* @return The bar.
*/
public java.lang.String getBar() {
java.lang.Object ref = bar_;
if (ref instanceof java.lang.String) {
return (java.lang.String) ref;
} else {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
bar_ = s;
}
return s;
}
}
/**
* <code>optional string bar = 1;</code>
* @return The bytes for bar.
*/
public com.google.protobuf.ByteString
getBarBytes() {
java.lang.Object ref = bar_;
if (ref instanceof java.lang.String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
bar_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
public static final int QUX_FIELD_NUMBER = 2;
private int qux_;
/**
* <code>optional int32 qux = 2;</code>
* @return Whether the qux field is set.
*/
public boolean hasQux() {
return ((bitField0_ & 0x00000002) != 0);
}
/**
* <code>optional int32 qux = 2;</code>
* @return The qux.
*/
public int getQux() {
return qux_;
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
memoizedIsInitialized = 1;
return true;
}
@java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
if (((bitField0_ & 0x00000001) != 0)) {
com.google.protobuf.GeneratedMessageV3.writeString(output, 1, bar_);
}
if (((bitField0_ & 0x00000002) != 0)) {
output.writeInt32(2, qux_);
}
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
if (((bitField0_ & 0x00000001) != 0)) {
size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, bar_);
}
if (((bitField0_ & 0x00000002) != 0)) {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(2, qux_);
}
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
}
@java.lang.Override
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof org.springframework.integration.transformer.proto.TestClass1)) {
return super.equals(obj);
}
org.springframework.integration.transformer.proto.TestClass1 other = (org.springframework.integration.transformer.proto.TestClass1) obj;
if (hasBar() != other.hasBar()) return false;
if (hasBar()) {
if (!getBar()
.equals(other.getBar())) return false;
}
if (hasQux() != other.hasQux()) return false;
if (hasQux()) {
if (getQux()
!= other.getQux()) return false;
}
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode();
if (hasBar()) {
hash = (37 * hash) + BAR_FIELD_NUMBER;
hash = (53 * hash) + getBar().hashCode();
}
if (hasQux()) {
hash = (37 * hash) + QUX_FIELD_NUMBER;
hash = (53 * hash) + getQux();
}
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(
java.nio.ByteBuffer data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static org.springframework.integration.transformer.proto.TestClass1 parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
@java.lang.Override
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder() {
return DEFAULT_INSTANCE.toBuilder();
}
public static Builder newBuilder(org.springframework.integration.transformer.proto.TestClass1 prototype) {
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
}
@java.lang.Override
public Builder toBuilder() {
return this == DEFAULT_INSTANCE
? new Builder() : new Builder().mergeFrom(this);
}
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* Protobuf type {@code tutorial.TestClass1}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:tutorial.TestClass1)
org.springframework.integration.transformer.proto.TestClass1OrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass1_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass1_fieldAccessorTable
.ensureFieldAccessorsInitialized(
org.springframework.integration.transformer.proto.TestClass1.class, org.springframework.integration.transformer.proto.TestClass1.Builder.class);
}
// Construct using org.springframework.integration.transformer.proto.TestClass1.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessageV3
.alwaysUseFieldBuilders) {
}
}
@java.lang.Override
public Builder clear() {
super.clear();
bar_ = "";
bitField0_ = (bitField0_ & ~0x00000001);
qux_ = 0;
bitField0_ = (bitField0_ & ~0x00000002);
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass1_descriptor;
}
@java.lang.Override
public org.springframework.integration.transformer.proto.TestClass1 getDefaultInstanceForType() {
return org.springframework.integration.transformer.proto.TestClass1.getDefaultInstance();
}
@java.lang.Override
public org.springframework.integration.transformer.proto.TestClass1 build() {
org.springframework.integration.transformer.proto.TestClass1 result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public org.springframework.integration.transformer.proto.TestClass1 buildPartial() {
org.springframework.integration.transformer.proto.TestClass1 result = new org.springframework.integration.transformer.proto.TestClass1(this);
int from_bitField0_ = bitField0_;
int to_bitField0_ = 0;
if (((from_bitField0_ & 0x00000001) != 0)) {
to_bitField0_ |= 0x00000001;
}
result.bar_ = bar_;
if (((from_bitField0_ & 0x00000002) != 0)) {
result.qux_ = qux_;
to_bitField0_ |= 0x00000002;
}
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
}
@java.lang.Override
public Builder clone() {
return super.clone();
}
@java.lang.Override
public Builder setField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.setField(field, value);
}
@java.lang.Override
public Builder clearField(
com.google.protobuf.Descriptors.FieldDescriptor field) {
return super.clearField(field);
}
@java.lang.Override
public Builder clearOneof(
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
return super.clearOneof(oneof);
}
@java.lang.Override
public Builder setRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
int index, java.lang.Object value) {
return super.setRepeatedField(field, index, value);
}
@java.lang.Override
public Builder addRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.addRepeatedField(field, value);
}
@java.lang.Override
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof org.springframework.integration.transformer.proto.TestClass1) {
return mergeFrom((org.springframework.integration.transformer.proto.TestClass1)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(org.springframework.integration.transformer.proto.TestClass1 other) {
if (other == org.springframework.integration.transformer.proto.TestClass1.getDefaultInstance()) return this;
if (other.hasBar()) {
bitField0_ |= 0x00000001;
bar_ = other.bar_;
onChanged();
}
if (other.hasQux()) {
setQux(other.getQux());
}
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
}
@java.lang.Override
public final boolean isInitialized() {
return true;
}
@java.lang.Override
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
org.springframework.integration.transformer.proto.TestClass1 parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (org.springframework.integration.transformer.proto.TestClass1) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int bitField0_;
private java.lang.Object bar_ = "";
/**
* <code>optional string bar = 1;</code>
* @return Whether the bar field is set.
*/
public boolean hasBar() {
return ((bitField0_ & 0x00000001) != 0);
}
/**
* <code>optional string bar = 1;</code>
* @return The bar.
*/
public java.lang.String getBar() {
java.lang.Object ref = bar_;
if (!(ref instanceof java.lang.String)) {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
bar_ = s;
}
return s;
} else {
return (java.lang.String) ref;
}
}
/**
* <code>optional string bar = 1;</code>
* @return The bytes for bar.
*/
public com.google.protobuf.ByteString
getBarBytes() {
java.lang.Object ref = bar_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
bar_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
/**
* <code>optional string bar = 1;</code>
* @param value The bar to set.
* @return This builder for chaining.
*/
public Builder setBar(
java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000001;
bar_ = value;
onChanged();
return this;
}
/**
* <code>optional string bar = 1;</code>
* @return This builder for chaining.
*/
public Builder clearBar() {
bitField0_ = (bitField0_ & ~0x00000001);
bar_ = getDefaultInstance().getBar();
onChanged();
return this;
}
/**
* <code>optional string bar = 1;</code>
* @param value The bytes for bar to set.
* @return This builder for chaining.
*/
public Builder setBarBytes(
com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000001;
bar_ = value;
onChanged();
return this;
}
private int qux_ ;
/**
* <code>optional int32 qux = 2;</code>
* @return Whether the qux field is set.
*/
public boolean hasQux() {
return ((bitField0_ & 0x00000002) != 0);
}
/**
* <code>optional int32 qux = 2;</code>
* @return The qux.
*/
public int getQux() {
return qux_;
}
/**
* <code>optional int32 qux = 2;</code>
* @param value The qux to set.
* @return This builder for chaining.
*/
public Builder setQux(int value) {
bitField0_ |= 0x00000002;
qux_ = value;
onChanged();
return this;
}
/**
* <code>optional int32 qux = 2;</code>
* @return This builder for chaining.
*/
public Builder clearQux() {
bitField0_ = (bitField0_ & ~0x00000002);
qux_ = 0;
onChanged();
return this;
}
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.setUnknownFields(unknownFields);
}
@java.lang.Override
public final Builder mergeUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.mergeUnknownFields(unknownFields);
}
// @@protoc_insertion_point(builder_scope:tutorial.TestClass1)
}
// @@protoc_insertion_point(class_scope:tutorial.TestClass1)
private static final org.springframework.integration.transformer.proto.TestClass1 DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new org.springframework.integration.transformer.proto.TestClass1();
}
public static org.springframework.integration.transformer.proto.TestClass1 getDefaultInstance() {
return DEFAULT_INSTANCE;
}
@java.lang.Deprecated public static final com.google.protobuf.Parser<TestClass1>
PARSER = new com.google.protobuf.AbstractParser<TestClass1>() {
@java.lang.Override
public TestClass1 parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new TestClass1(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<TestClass1> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<TestClass1> getParserForType() {
return PARSER;
}
@java.lang.Override
public org.springframework.integration.transformer.proto.TestClass1 getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}

View File

@@ -0,0 +1,37 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: ProtoTest.proto
package org.springframework.integration.transformer.proto;
public interface TestClass1OrBuilder extends
// @@protoc_insertion_point(interface_extends:tutorial.TestClass1)
com.google.protobuf.MessageOrBuilder {
/**
* <code>optional string bar = 1;</code>
* @return Whether the bar field is set.
*/
boolean hasBar();
/**
* <code>optional string bar = 1;</code>
* @return The bar.
*/
java.lang.String getBar();
/**
* <code>optional string bar = 1;</code>
* @return The bytes for bar.
*/
com.google.protobuf.ByteString
getBarBytes();
/**
* <code>optional int32 qux = 2;</code>
* @return Whether the qux field is set.
*/
boolean hasQux();
/**
* <code>optional int32 qux = 2;</code>
* @return The qux.
*/
int getQux();
}

View File

@@ -0,0 +1,671 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: ProtoTest.proto
package org.springframework.integration.transformer.proto;
/**
* Protobuf type {@code tutorial.TestClass2}
*/
public final class TestClass2 extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:tutorial.TestClass2)
TestClass2OrBuilder {
private static final long serialVersionUID = 0L;
// Use TestClass2.newBuilder() to construct.
private TestClass2(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private TestClass2() {
bar_ = "";
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new TestClass2();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private TestClass2(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
this();
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
int mutable_bitField0_ = 0;
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
com.google.protobuf.UnknownFieldSet.newBuilder();
try {
boolean done = false;
while (!done) {
int tag = input.readTag();
switch (tag) {
case 0:
done = true;
break;
case 10: {
com.google.protobuf.ByteString bs = input.readBytes();
bitField0_ |= 0x00000001;
bar_ = bs;
break;
}
case 16: {
bitField0_ |= 0x00000002;
qux_ = input.readInt32();
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e).setUnfinishedMessage(this);
} finally {
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass2_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass2_fieldAccessorTable
.ensureFieldAccessorsInitialized(
org.springframework.integration.transformer.proto.TestClass2.class, org.springframework.integration.transformer.proto.TestClass2.Builder.class);
}
private int bitField0_;
public static final int BAR_FIELD_NUMBER = 1;
private volatile java.lang.Object bar_;
/**
* <code>optional string bar = 1;</code>
* @return Whether the bar field is set.
*/
public boolean hasBar() {
return ((bitField0_ & 0x00000001) != 0);
}
/**
* <code>optional string bar = 1;</code>
* @return The bar.
*/
public java.lang.String getBar() {
java.lang.Object ref = bar_;
if (ref instanceof java.lang.String) {
return (java.lang.String) ref;
} else {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
bar_ = s;
}
return s;
}
}
/**
* <code>optional string bar = 1;</code>
* @return The bytes for bar.
*/
public com.google.protobuf.ByteString
getBarBytes() {
java.lang.Object ref = bar_;
if (ref instanceof java.lang.String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
bar_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
public static final int QUX_FIELD_NUMBER = 2;
private int qux_;
/**
* <code>optional int32 qux = 2;</code>
* @return Whether the qux field is set.
*/
public boolean hasQux() {
return ((bitField0_ & 0x00000002) != 0);
}
/**
* <code>optional int32 qux = 2;</code>
* @return The qux.
*/
public int getQux() {
return qux_;
}
private byte memoizedIsInitialized = -1;
@java.lang.Override
public final boolean isInitialized() {
byte isInitialized = memoizedIsInitialized;
if (isInitialized == 1) return true;
if (isInitialized == 0) return false;
memoizedIsInitialized = 1;
return true;
}
@java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
if (((bitField0_ & 0x00000001) != 0)) {
com.google.protobuf.GeneratedMessageV3.writeString(output, 1, bar_);
}
if (((bitField0_ & 0x00000002) != 0)) {
output.writeInt32(2, qux_);
}
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
if (((bitField0_ & 0x00000001) != 0)) {
size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, bar_);
}
if (((bitField0_ & 0x00000002) != 0)) {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(2, qux_);
}
size += unknownFields.getSerializedSize();
memoizedSize = size;
return size;
}
@java.lang.Override
public boolean equals(final java.lang.Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof org.springframework.integration.transformer.proto.TestClass2)) {
return super.equals(obj);
}
org.springframework.integration.transformer.proto.TestClass2 other = (org.springframework.integration.transformer.proto.TestClass2) obj;
if (hasBar() != other.hasBar()) return false;
if (hasBar()) {
if (!getBar()
.equals(other.getBar())) return false;
}
if (hasQux() != other.hasQux()) return false;
if (hasQux()) {
if (getQux()
!= other.getQux()) return false;
}
if (!unknownFields.equals(other.unknownFields)) return false;
return true;
}
@java.lang.Override
public int hashCode() {
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode();
if (hasBar()) {
hash = (37 * hash) + BAR_FIELD_NUMBER;
hash = (53 * hash) + getBar().hashCode();
}
if (hasQux()) {
hash = (37 * hash) + QUX_FIELD_NUMBER;
hash = (53 * hash) + getQux();
}
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(
java.nio.ByteBuffer data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(
com.google.protobuf.ByteString data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseDelimitedFrom(
java.io.InputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static org.springframework.integration.transformer.proto.TestClass2 parseFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input, extensionRegistry);
}
@java.lang.Override
public Builder newBuilderForType() { return newBuilder(); }
public static Builder newBuilder() {
return DEFAULT_INSTANCE.toBuilder();
}
public static Builder newBuilder(org.springframework.integration.transformer.proto.TestClass2 prototype) {
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
}
@java.lang.Override
public Builder toBuilder() {
return this == DEFAULT_INSTANCE
? new Builder() : new Builder().mergeFrom(this);
}
@java.lang.Override
protected Builder newBuilderForType(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
Builder builder = new Builder(parent);
return builder;
}
/**
* Protobuf type {@code tutorial.TestClass2}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:tutorial.TestClass2)
org.springframework.integration.transformer.proto.TestClass2OrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass2_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass2_fieldAccessorTable
.ensureFieldAccessorsInitialized(
org.springframework.integration.transformer.proto.TestClass2.class, org.springframework.integration.transformer.proto.TestClass2.Builder.class);
}
// Construct using org.springframework.integration.transformer.proto.TestClass2.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
}
private Builder(
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
super(parent);
maybeForceBuilderInitialization();
}
private void maybeForceBuilderInitialization() {
if (com.google.protobuf.GeneratedMessageV3
.alwaysUseFieldBuilders) {
}
}
@java.lang.Override
public Builder clear() {
super.clear();
bar_ = "";
bitField0_ = (bitField0_ & ~0x00000001);
qux_ = 0;
bitField0_ = (bitField0_ & ~0x00000002);
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return org.springframework.integration.transformer.proto.TestProtos.internal_static_tutorial_TestClass2_descriptor;
}
@java.lang.Override
public org.springframework.integration.transformer.proto.TestClass2 getDefaultInstanceForType() {
return org.springframework.integration.transformer.proto.TestClass2.getDefaultInstance();
}
@java.lang.Override
public org.springframework.integration.transformer.proto.TestClass2 build() {
org.springframework.integration.transformer.proto.TestClass2 result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public org.springframework.integration.transformer.proto.TestClass2 buildPartial() {
org.springframework.integration.transformer.proto.TestClass2 result = new org.springframework.integration.transformer.proto.TestClass2(this);
int from_bitField0_ = bitField0_;
int to_bitField0_ = 0;
if (((from_bitField0_ & 0x00000001) != 0)) {
to_bitField0_ |= 0x00000001;
}
result.bar_ = bar_;
if (((from_bitField0_ & 0x00000002) != 0)) {
result.qux_ = qux_;
to_bitField0_ |= 0x00000002;
}
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
}
@java.lang.Override
public Builder clone() {
return super.clone();
}
@java.lang.Override
public Builder setField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.setField(field, value);
}
@java.lang.Override
public Builder clearField(
com.google.protobuf.Descriptors.FieldDescriptor field) {
return super.clearField(field);
}
@java.lang.Override
public Builder clearOneof(
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
return super.clearOneof(oneof);
}
@java.lang.Override
public Builder setRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
int index, java.lang.Object value) {
return super.setRepeatedField(field, index, value);
}
@java.lang.Override
public Builder addRepeatedField(
com.google.protobuf.Descriptors.FieldDescriptor field,
java.lang.Object value) {
return super.addRepeatedField(field, value);
}
@java.lang.Override
public Builder mergeFrom(com.google.protobuf.Message other) {
if (other instanceof org.springframework.integration.transformer.proto.TestClass2) {
return mergeFrom((org.springframework.integration.transformer.proto.TestClass2)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(org.springframework.integration.transformer.proto.TestClass2 other) {
if (other == org.springframework.integration.transformer.proto.TestClass2.getDefaultInstance()) return this;
if (other.hasBar()) {
bitField0_ |= 0x00000001;
bar_ = other.bar_;
onChanged();
}
if (other.hasQux()) {
setQux(other.getQux());
}
this.mergeUnknownFields(other.unknownFields);
onChanged();
return this;
}
@java.lang.Override
public final boolean isInitialized() {
return true;
}
@java.lang.Override
public Builder mergeFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws java.io.IOException {
org.springframework.integration.transformer.proto.TestClass2 parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (org.springframework.integration.transformer.proto.TestClass2) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int bitField0_;
private java.lang.Object bar_ = "";
/**
* <code>optional string bar = 1;</code>
* @return Whether the bar field is set.
*/
public boolean hasBar() {
return ((bitField0_ & 0x00000001) != 0);
}
/**
* <code>optional string bar = 1;</code>
* @return The bar.
*/
public java.lang.String getBar() {
java.lang.Object ref = bar_;
if (!(ref instanceof java.lang.String)) {
com.google.protobuf.ByteString bs =
(com.google.protobuf.ByteString) ref;
java.lang.String s = bs.toStringUtf8();
if (bs.isValidUtf8()) {
bar_ = s;
}
return s;
} else {
return (java.lang.String) ref;
}
}
/**
* <code>optional string bar = 1;</code>
* @return The bytes for bar.
*/
public com.google.protobuf.ByteString
getBarBytes() {
java.lang.Object ref = bar_;
if (ref instanceof String) {
com.google.protobuf.ByteString b =
com.google.protobuf.ByteString.copyFromUtf8(
(java.lang.String) ref);
bar_ = b;
return b;
} else {
return (com.google.protobuf.ByteString) ref;
}
}
/**
* <code>optional string bar = 1;</code>
* @param value The bar to set.
* @return This builder for chaining.
*/
public Builder setBar(
java.lang.String value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000001;
bar_ = value;
onChanged();
return this;
}
/**
* <code>optional string bar = 1;</code>
* @return This builder for chaining.
*/
public Builder clearBar() {
bitField0_ = (bitField0_ & ~0x00000001);
bar_ = getDefaultInstance().getBar();
onChanged();
return this;
}
/**
* <code>optional string bar = 1;</code>
* @param value The bytes for bar to set.
* @return This builder for chaining.
*/
public Builder setBarBytes(
com.google.protobuf.ByteString value) {
if (value == null) {
throw new NullPointerException();
}
bitField0_ |= 0x00000001;
bar_ = value;
onChanged();
return this;
}
private int qux_ ;
/**
* <code>optional int32 qux = 2;</code>
* @return Whether the qux field is set.
*/
public boolean hasQux() {
return ((bitField0_ & 0x00000002) != 0);
}
/**
* <code>optional int32 qux = 2;</code>
* @return The qux.
*/
public int getQux() {
return qux_;
}
/**
* <code>optional int32 qux = 2;</code>
* @param value The qux to set.
* @return This builder for chaining.
*/
public Builder setQux(int value) {
bitField0_ |= 0x00000002;
qux_ = value;
onChanged();
return this;
}
/**
* <code>optional int32 qux = 2;</code>
* @return This builder for chaining.
*/
public Builder clearQux() {
bitField0_ = (bitField0_ & ~0x00000002);
qux_ = 0;
onChanged();
return this;
}
@java.lang.Override
public final Builder setUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.setUnknownFields(unknownFields);
}
@java.lang.Override
public final Builder mergeUnknownFields(
final com.google.protobuf.UnknownFieldSet unknownFields) {
return super.mergeUnknownFields(unknownFields);
}
// @@protoc_insertion_point(builder_scope:tutorial.TestClass2)
}
// @@protoc_insertion_point(class_scope:tutorial.TestClass2)
private static final org.springframework.integration.transformer.proto.TestClass2 DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new org.springframework.integration.transformer.proto.TestClass2();
}
public static org.springframework.integration.transformer.proto.TestClass2 getDefaultInstance() {
return DEFAULT_INSTANCE;
}
@java.lang.Deprecated public static final com.google.protobuf.Parser<TestClass2>
PARSER = new com.google.protobuf.AbstractParser<TestClass2>() {
@java.lang.Override
public TestClass2 parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new TestClass2(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<TestClass2> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<TestClass2> getParserForType() {
return PARSER;
}
@java.lang.Override
public org.springframework.integration.transformer.proto.TestClass2 getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}

View File

@@ -0,0 +1,37 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: ProtoTest.proto
package org.springframework.integration.transformer.proto;
public interface TestClass2OrBuilder extends
// @@protoc_insertion_point(interface_extends:tutorial.TestClass2)
com.google.protobuf.MessageOrBuilder {
/**
* <code>optional string bar = 1;</code>
* @return Whether the bar field is set.
*/
boolean hasBar();
/**
* <code>optional string bar = 1;</code>
* @return The bar.
*/
java.lang.String getBar();
/**
* <code>optional string bar = 1;</code>
* @return The bytes for bar.
*/
com.google.protobuf.ByteString
getBarBytes();
/**
* <code>optional int32 qux = 2;</code>
* @return Whether the qux field is set.
*/
boolean hasQux();
/**
* <code>optional int32 qux = 2;</code>
* @return The qux.
*/
int getQux();
}

View File

@@ -0,0 +1,61 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: ProtoTest.proto
package org.springframework.integration.transformer.proto;
public final class TestProtos {
private TestProtos() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistryLite registry) {
}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions(
(com.google.protobuf.ExtensionRegistryLite) registry);
}
static final com.google.protobuf.Descriptors.Descriptor
internal_static_tutorial_TestClass1_descriptor;
static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_tutorial_TestClass1_fieldAccessorTable;
static final com.google.protobuf.Descriptors.Descriptor
internal_static_tutorial_TestClass2_descriptor;
static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_tutorial_TestClass2_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
return descriptor;
}
private static com.google.protobuf.Descriptors.FileDescriptor
descriptor;
static {
java.lang.String[] descriptorData = {
"\n\017ProtoTest.proto\022\010tutorial\"&\n\nTestClass" +
"1\022\013\n\003bar\030\001 \001(\t\022\013\n\003qux\030\002 \001(\005\"&\n\nTestClass" +
"2\022\013\n\003bar\030\001 \001(\t\022\013\n\003qux\030\002 \001(\005BA\n1org.sprin" +
"gframework.integration.transformer.proto" +
"B\nTestProtosP\001"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
});
internal_static_tutorial_TestClass1_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_tutorial_TestClass1_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_tutorial_TestClass1_descriptor,
new java.lang.String[] { "Bar", "Qux", });
internal_static_tutorial_TestClass2_descriptor =
getDescriptor().getMessageTypes().get(1);
internal_static_tutorial_TestClass2_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_tutorial_TestClass2_descriptor,
new java.lang.String[] { "Bar", "Qux", });
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@@ -0,0 +1,17 @@
syntax = "proto2";
package tutorial;
option java_multiple_files = true;
option java_package = "org.springframework.integration.transformer.proto";
option java_outer_classname = "TestProtos";
message TestClass1 {
optional string bar = 1;
optional int32 qux = 2;
}
message TestClass2 {
optional string bar = 1;
optional int32 qux = 2;
}

View File

@@ -13,4 +13,5 @@
<suppress files="[\\/]test[\\/]" checks="EqualsHashCode"/>
<suppress files="[\\/]test[\\/]" checks="Atclause*"/>
<suppress files="[\\/]test[\\/]" checks="InterfaceIsType"/>
<suppress files="org[\\/]springframework[\\/]integration[\\/]transformer[\\/]proto" checks=".*"/>
</suppressions>

View File

@@ -249,8 +249,8 @@ Spring Integration provides namespace support for Map-to-Object, as the followin
====
[source,xml]
----
<int:map-to-object-transformer input-channel="input"
output-channel="output"
<int:map-to-object-transformer input-channel="input"
output-channel="output"
type="org.something.Person"/>
----
====
@@ -258,7 +258,7 @@ Spring Integration provides namespace support for Map-to-Object, as the followin
Alternatively, you could use a `ref` attribute and a prototype-scoped bean, as the following example shows:
[source,xml]
----
<int:map-to-object-transformer input-channel="inputA"
<int:map-to-object-transformer input-channel="inputA"
output-channel="outputA"
ref="person"/>
<bean id="person" class="org.something.Person" scope="prototype"/>
@@ -267,7 +267,7 @@ Alternatively, you could use a `ref` attribute and a prototype-scoped bean, as t
NOTE: The 'ref' and 'type' attributes are mutually exclusive.
Also, if you use the 'ref' attribute, you must point to a 'prototype' scoped bean.
Otherwise, a `BeanCreationException` is thrown.
Otherwise, a `BeanCreationException` is thrown.
Starting with version 5.0, you can supply the `ObjectToMapTransformer` with a customized `JsonObjectMapper` -- for when you need special formats for dates or nulls for empty collections (and other uses).
See <<json-transformers>> for more information about `JsonObjectMapper` implementations.
@@ -446,6 +446,64 @@ If the expression returns `null`, the `defaultType` is used.
The `SimpleToAvroTransformer` also has a `setTypeExpression` method.
This allows decoupling of the producer and consumer where the sender can set the header to some token representing the type and the consumer then maps that token to a type.
[[Protobuf-transformers]]
===== Protocol Buffers Transformers
Version 6.1 adds support for transforming from and to https://protobuf.dev/[Protocol Buffers] data content.
The `ToProtobufTransformer` transforms a `com.google.protobuf.Message` message payloads into native byte array or json text payloads.
The `application/x-protobuf` content type (used by default) produces byte array output payload.
If the content type is `application/json` add the `com.google.protobuf:protobuf-java-util` if found on the classpath, then the output is text json payload.
If the content type header is not set the `ToProtobufTransformer` defaults to `application/x-protobuf`.
The `FromProtobufTransformer` transforms byte array or text protobuf payload (depending on the content type) back into `com.google.protobuf.Message` instances.
The `FromProtobufTransformer` should specify either an expected class type explicitly (use the `setExpectedType` method) or use a SpEL expression to determine the type to deserialize using the `setExpectedTypeExpression` method.
The default SpEL expression is `headers[proto_type]` (`ProtoHeaders.TYPE`) which is populated by the `ToProtobufTransformer` with the fully qualified class name of the source `com.google.protobuf.Message` class.
For example, compiling the following IDL:
====
[source,proto]
----
syntax = "proto2";
package tutorial;
option java_multiple_files = true;
option java_package = "org.example";
option java_outer_classname = "MyProtos";
message MyMessageClass {
optional string foo = 1;
optional string bar = 2;
}
----
====
will generate a new `org.example.MyMessageClass` class.
Then use the:
====
[source,java]
----
// Transforms a MyMessageClass instance into a byte array.
ToProtobufTransformer toTransformer = new ToProtobufTransformer();
MyMessageClass test = MyMessageClass.newBuilder()
.setFoo("foo")
.setBar("bar")
.build();
// message1 payload is byte array protocol buffer wire format.
Message message1 = toTransformer.transform(new GenericMessage<>(test));
// Transforms a byte array payload into a MyMessageClass instance.
FromProtobufTransformer fromTransformer = new FromProtobufTransformer();
// message2 payload == test
Message message2 = fromTransformer.transform(message1);
----
====
[[transformer-annotation]]
==== Configuring a Transformer with Annotations

View File

@@ -27,6 +27,10 @@ See <<./zip.adoc#zip,Zip Support>> for more information.
[[x6.1-general]]
=== General Changes
- Added support for transforming to/from Protocol Buffers.
See <<./transformer.adoc#Protobuf-transformers, Protocol Buffers Transformers>> for more information.
[[x6.1-web-sockets]]
=== Web Sockets Changes