[Dubbo-3829] support google pb generic invocation (#3975)

* modify generic filter to support google pb service test.

* save

* save code

* save genericFilter 改写完毕

* save

* add Licensed

* fix some problem after code review

* change directory name after change module name
This commit is contained in:
violin 2019-05-08 16:25:46 +08:00 committed by Ian Luo
parent f2bed88616
commit 455d29a224
18 changed files with 4051 additions and 3 deletions

View File

@ -387,6 +387,13 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-protobuf-json</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-api</artifactId>
@ -585,6 +592,7 @@
<include>org.apache.dubbo:dubbo-serialization-jdk</include>
<include>org.apache.dubbo:dubbo-serialization-protostuff</include>
<include>org.apache.dubbo:dubbo-serialization-gson</include>
<include>org.apache.dubbo:dubbo-serialization-googlePb</include>
<include>org.apache.dubbo:dubbo-configcenter-api</include>
<include>org.apache.dubbo:dubbo-configcenter-definition</include>
<include>org.apache.dubbo:dubbo-configcenter-apollo</include>

View File

@ -342,6 +342,11 @@
<artifactId>dubbo-serialization-gson</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-protobuf-json</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-compatible</artifactId>

View File

@ -727,6 +727,8 @@ public class Constants {
public static final String GENERIC_SERIALIZATION_BEAN = "bean";
public static final String GENERIC_SERIALIZATION_PROTOBUF = "protobuf-json";
public static final String DUBBO_IP_TO_REGISTRY = "DUBBO_IP_TO_REGISTRY";
public static final String DUBBO_PORT_TO_REGISTRY = "DUBBO_PORT_TO_REGISTRY";

View File

@ -108,6 +108,7 @@
<cxf_version>3.1.15</cxf_version>
<thrift_version>0.12.0</thrift_version>
<hessian_version>4.0.38</hessian_version>
<protobuf-java_version>3.6.0</protobuf-java_version>
<servlet_version>3.1.0</servlet_version>
<jetty_version>9.4.11.v20180605</jetty_version>
<validation_version>1.1.0.Final</validation_version>
@ -271,6 +272,16 @@
<artifactId>hessian-lite</artifactId>
<version>${hessian_lite_version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>${protobuf-java_version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>${protobuf-java_version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>

View File

@ -76,7 +76,7 @@ public class GenericFilter implements Filter {
} else if (ProtocolUtils.isJavaGenericSerialization(generic)) {
for (int i = 0; i < args.length; i++) {
if (byte[].class == args[i].getClass()) {
try(UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) {
try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) {
args[i] = ExtensionLoader.getExtensionLoader(Serialization.class)
.getExtension(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA)
.deserialize(null, is).readObject();
@ -107,6 +107,26 @@ public class GenericFilter implements Filter {
args[i].getClass().getName());
}
}
} else if (ProtocolUtils.isProtobufGenericSerialization(generic)) {
// as proto3 only accept one protobuf parameter
if (args.length == 1 && args[0] instanceof String) {
try (UnsafeByteArrayInputStream is =
new UnsafeByteArrayInputStream(((String) args[0]).getBytes())) {
args[0] = ExtensionLoader.getExtensionLoader(Serialization.class)
.getExtension("" + Constants.GENERIC_SERIALIZATION_PROTOBUF)
.deserialize(null, is).readObject(method.getParameterTypes()[0]);
} catch (Exception e) {
throw new RpcException("Deserialize argument failed.", e);
}
} else {
throw new RpcException(
"Generic serialization [" +
Constants.GENERIC_SERIALIZATION_PROTOBUF +
"] only support one" + String.class.getName() +
" argument and your message size is " +
args.length + " and type is" +
args[0].getClass().getName());
}
}
Result result = invoker.invoke(new RpcInvocation(method, args, inv.getAttachments()));
if (result.hasException()
@ -121,10 +141,25 @@ public class GenericFilter implements Filter {
.serialize(null, os).writeObject(result.getValue());
return new RpcResult(os.toByteArray());
} catch (IOException e) {
throw new RpcException("Serialize result failed.", e);
throw new RpcException(
"Generic serialization [" +
Constants.GENERIC_SERIALIZATION_NATIVE_JAVA +
"] serialize result failed.", e);
}
} else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
return new RpcResult(JavaBeanSerializeUtil.serialize(result.getValue(), JavaBeanAccessor.METHOD));
} else if (ProtocolUtils.isProtobufGenericSerialization(generic)) {
try {
UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512);
ExtensionLoader.getExtensionLoader(Serialization.class)
.getExtension(Constants.GENERIC_SERIALIZATION_PROTOBUF)
.serialize(null, os).writeObject(result.getValue());
return new RpcResult(os.toString());
} catch (IOException e) {
throw new RpcException("Generic serialization [" +
Constants.GENERIC_SERIALIZATION_PROTOBUF +
"] serialize result failed.", e);
}
} else {
return new RpcResult(PojoUtils.generalize(result.getValue()));
}

View File

@ -51,7 +51,8 @@ public class ProtocolUtils {
&& !"".equals(generic)
&& (Constants.GENERIC_SERIALIZATION_DEFAULT.equalsIgnoreCase(generic) /* Normal generalization cal */
|| Constants.GENERIC_SERIALIZATION_NATIVE_JAVA.equalsIgnoreCase(generic) /* Streaming generalization call supporting jdk serialization */
|| Constants.GENERIC_SERIALIZATION_BEAN.equalsIgnoreCase(generic));
|| Constants.GENERIC_SERIALIZATION_BEAN.equalsIgnoreCase(generic)
|| Constants.GENERIC_SERIALIZATION_PROTOBUF.equalsIgnoreCase(generic));
}
public static boolean isDefaultGenericSerialization(String generic) {
@ -67,4 +68,8 @@ public class ProtocolUtils {
public static boolean isBeanGenericSerialization(String generic) {
return isGeneric(generic) && Constants.GENERIC_SERIALIZATION_BEAN.equals(generic);
}
public static boolean isProtobufGenericSerialization(String generic) {
return isGeneric(generic) && Constants.GENERIC_SERIALIZATION_PROTOBUF.equals(generic);
}
}

View File

@ -0,0 +1,46 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>dubbo-serialization</artifactId>
<groupId>org.apache.dubbo</groupId>
<version>${revision}</version>
</parent>
<artifactId>dubbo-serialization-protobuf-json</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The protobuf serialization module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,115 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.protobuf.support;
import org.apache.dubbo.common.serialize.ObjectInput;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
/**
* GenericGoogleProtobuf object input implementation
*/
public class GenericProtobufObjectInput implements ObjectInput {
private final BufferedReader reader;
public GenericProtobufObjectInput(InputStream in) {
this.reader = new BufferedReader(new InputStreamReader(in));
}
@Override
public boolean readBool() throws IOException {
return read(boolean.class);
}
@Override
public byte readByte() throws IOException {
return read(byte.class);
}
@Override
public short readShort() throws IOException {
return read(short.class);
}
@Override
public int readInt() throws IOException {
return read(int.class);
}
@Override
public long readLong() throws IOException {
return read(long.class);
}
@Override
public float readFloat() throws IOException {
return read(float.class);
}
@Override
public double readDouble() throws IOException {
return read(double.class);
}
@Override
public String readUTF() throws IOException {
return read(String.class);
}
@Override
public byte[] readBytes() throws IOException {
return readLine().getBytes();
}
@Override
public Object readObject() throws IOException {
return read(String.class);
}
@Override
public <T> T readObject(Class<T> cls) throws IOException {
return read(cls);
}
@Override
@SuppressWarnings("unchecked")
public <T> T readObject(Class<T> cls, Type type) throws IOException {
return readObject(cls);
}
private String readLine() throws IOException {
String line = reader.readLine();
if (line == null || line.trim().length() == 0) {
throw new EOFException();
}
return line;
}
private <T> T read(Class<T> cls) throws IOException {
if (!ProtobufUtils.isSupported(cls)) {
throw new IllegalArgumentException("This serialization only support google protobuf entity, the class is :" + cls.getName());
}
String json = readLine();
return ProtobufUtils.deserialize(json, cls);
}
}

View File

@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.protobuf.support;
import org.apache.dubbo.common.serialize.ObjectOutput;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
/**
* GenericGoogleProtobuf object output implementation
*/
public class GenericProtobufObjectOutput implements ObjectOutput {
private final PrintWriter writer;
public GenericProtobufObjectOutput(OutputStream out) {
this.writer = new PrintWriter(new OutputStreamWriter(out));
}
@Override
public void writeBool(boolean v) throws IOException {
writeObject(v);
}
@Override
public void writeByte(byte v) throws IOException {
writeObject(v);
}
@Override
public void writeShort(short v) throws IOException {
writeObject(v);
}
@Override
public void writeInt(int v) throws IOException {
writeObject(v);
}
@Override
public void writeLong(long v) throws IOException {
writeObject(v);
}
@Override
public void writeFloat(float v) throws IOException {
writeObject(v);
}
@Override
public void writeDouble(double v) throws IOException {
writeObject(v);
}
@Override
public void writeUTF(String v) throws IOException {
writeObject(v);
}
@Override
public void writeBytes(byte[] b) {
writer.println(new String(b));
}
@Override
public void writeBytes(byte[] b, int off, int len) {
writer.println(new String(b, off, len));
}
@Override
public void writeObject(Object obj) throws IOException {
if (obj == null) {
throw new IllegalArgumentException("This serialization only support google protobuf object, the object is : null");
}
if (!ProtobufUtils.isSupported(obj.getClass())) {
throw new IllegalArgumentException("This serialization only support google protobuf object, the object class is: " + obj.getClass().getName());
}
writer.write(ProtobufUtils.serialize(obj));
writer.println();
writer.flush();
}
@Override
public void flushBuffer() {
writer.flush();
}
}

View File

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.protobuf.support;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.serialize.ObjectInput;
import org.apache.dubbo.common.serialize.ObjectOutput;
import org.apache.dubbo.common.serialize.Serialization;
import java.io.InputStream;
import java.io.OutputStream;
/**
* This serizalization is use for google protobuf generic reference.
* The entity be transported between client and server by json string.
*
*/
public class GenericProtobufSerialization implements Serialization {
@Override
public byte getContentTypeId() {
return 21;
}
@Override
public String getContentType() {
return "text/json";
}
@Override
public ObjectOutput serialize(URL url, OutputStream output) {
return new GenericProtobufObjectOutput(output);
}
@Override
public ObjectInput deserialize(URL url, InputStream input) {
return new GenericProtobufObjectInput(input);
}
}

View File

@ -0,0 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.protobuf.support;
import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.GeneratedMessageV3.Builder;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageOrBuilder;
import com.google.protobuf.util.JsonFormat;
import com.google.protobuf.util.JsonFormat.Printer;
import java.lang.reflect.Method;
public class ProtobufUtils {
static boolean isSupported(Class<?> clazz) {
if (clazz == null) {
return false;
}
if (GeneratedMessageV3.class.isAssignableFrom(clazz)) {
return true;
}
return false;
}
static <T> T deserialize(String json, Class<T> requestClass) throws InvalidProtocolBufferException {
Builder builder;
try {
builder = getMessageBuilder(requestClass);
} catch (Exception e) {
throw new IllegalArgumentException("Get google protobuf message builder from " + requestClass.getName() + "failed", e);
}
JsonFormat.parser().merge(json, builder);
return (T) builder.build();
}
static String serialize(Object value) throws InvalidProtocolBufferException {
Printer printer = JsonFormat.printer().omittingInsignificantWhitespace();
return printer.print((MessageOrBuilder) value);
}
private static Builder getMessageBuilder(Class<?> requestType) throws Exception {
Method method = requestType.getMethod("newBuilder");
return (Builder) method.invoke(null, null);
}
}

View File

@ -0,0 +1 @@
protobuf-json=org.apache.dubbo.common.serialize.protobuf.support.GenericProtobufSerialization

View File

@ -77,5 +77,10 @@
<artifactId>dubbo-serialization-avro</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-protobuf-json</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.protobuf.support;
import org.apache.dubbo.common.serialize.protobuf.support.model.GooglePB;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class GenericProtobufObjectOutputTest {
private ByteArrayOutputStream byteArrayOutputStream;
private GenericProtobufObjectOutput genericProtobufObjectOutput;
private GenericProtobufObjectInput genericProtobufObjectInput;
private ByteArrayInputStream byteArrayInputStream;
@BeforeEach
public void setUp() {
this.byteArrayOutputStream = new ByteArrayOutputStream();
this.genericProtobufObjectOutput = new GenericProtobufObjectOutput(byteArrayOutputStream);
}
@Test
public void testWriteObjectNull() throws IOException {
assertThrows(IllegalArgumentException.class, () -> {
this.genericProtobufObjectOutput.writeObject(null);
});
}
@Test
public void testWriteGooglePbObject() throws IOException {
Random random = new Random();
final int bound = 100000;
List<GooglePB.PhoneNumber> phoneNumberList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
phoneNumberList.add(GooglePB.PhoneNumber.newBuilder().setNumber(random.nextInt(bound) + "").setType(GooglePB.PhoneType.forNumber(random.nextInt(GooglePB.PhoneType.values().length - 1))).build());
}
Map<String, GooglePB.PhoneNumber> phoneNumberMap = new HashMap<>();
for (int i = 0; i < 5; i++) {
phoneNumberMap.put("phoneNumber" + i, GooglePB.PhoneNumber.newBuilder().setNumber(random.nextInt(bound) + "").setType(GooglePB.PhoneType.forNumber(random.nextInt(GooglePB.PhoneType.values().length - 1))).build());
}
GooglePB.PBRequestType request = GooglePB.PBRequestType.newBuilder()
.setAge(15).setCash(10).setMoney(16.0).setNum(100L)
.addAllPhone(phoneNumberList).putAllDoubleMap(phoneNumberMap).build();
this.genericProtobufObjectOutput.writeObject(request);
this.flushToInput();
assertThat(genericProtobufObjectInput.readObject(GooglePB.PBRequestType.class), is(request));
}
private void flushToInput() {
this.genericProtobufObjectOutput.flushBuffer();
this.byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
this.genericProtobufObjectInput = new GenericProtobufObjectInput(byteArrayInputStream);
}
}

View File

@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.serialize.protobuf.support;
import org.apache.dubbo.common.serialize.base.AbstractSerializationTest;
import org.apache.dubbo.common.serialize.protostuff.ProtostuffSerialization;
public class GenericProtobufSerializationTest extends AbstractSerializationTest {
{
serialization = new ProtostuffSerialization();
}
}

View File

@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
syntax = "proto2";
package org.apache.dubbo.common.serialize.protobuf.model;
message PBRequestType {
optional double money = 1;
optional float cash = 2;
optional int32 age = 3;
optional int64 num = 4;
optional bool sex = 5;
optional string name = 6;
optional bytes msg = 7;
repeated org.apache.dubbo.common.serialize.protobuf.model.PhoneNumber phone = 8;
map<string, PhoneNumber> doubleMap = 9;
}
message PBResponseType {
optional string msg = 1;
optional org.apache.dubbo.common.serialize.protobuf.model.PBRequestType CDubboPBRequestType = 3;
}
message PhoneNumber {
required string number = 1;
optional org.apache.dubbo.common.serialize.protobuf.model.PhoneType type = 2 [default = HOME];
}
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
service CDubboPBService {
rpc sayHello (org.apache.dubbo.common.serialize.protobuf.model.PBRequestType) returns (org.apache.dubbo.common.serialize.protobuf.model.PBResponseType);
}

View File

@ -39,6 +39,7 @@
<module>dubbo-serialization-avro</module>
<module>dubbo-serialization-test</module>
<module>dubbo-serialization-gson</module>
<module>dubbo-serialization-protobuf-json</module>
<module>dubbo-serialization-native-hession</module>
</modules>
</project>