Skip to content

Commit 455d29a

Browse files
vio-linbeiwei30
authored andcommitted
[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
1 parent f2bed88 commit 455d29a

File tree

18 files changed

+4051
-3
lines changed

18 files changed

+4051
-3
lines changed

dubbo-all/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,13 @@
387387
<scope>compile</scope>
388388
<optional>true</optional>
389389
</dependency>
390+
<dependency>
391+
<groupId>org.apache.dubbo</groupId>
392+
<artifactId>dubbo-serialization-protobuf-json</artifactId>
393+
<version>${project.version}</version>
394+
<scope>compile</scope>
395+
<optional>true</optional>
396+
</dependency>
390397
<dependency>
391398
<groupId>org.apache.dubbo</groupId>
392399
<artifactId>dubbo-configcenter-api</artifactId>
@@ -585,6 +592,7 @@
585592
<include>org.apache.dubbo:dubbo-serialization-jdk</include>
586593
<include>org.apache.dubbo:dubbo-serialization-protostuff</include>
587594
<include>org.apache.dubbo:dubbo-serialization-gson</include>
595+
<include>org.apache.dubbo:dubbo-serialization-googlePb</include>
588596
<include>org.apache.dubbo:dubbo-configcenter-api</include>
589597
<include>org.apache.dubbo:dubbo-configcenter-definition</include>
590598
<include>org.apache.dubbo:dubbo-configcenter-apollo</include>

dubbo-bom/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,11 @@
342342
<artifactId>dubbo-serialization-gson</artifactId>
343343
<version>${project.version}</version>
344344
</dependency>
345+
<dependency>
346+
<groupId>org.apache.dubbo</groupId>
347+
<artifactId>dubbo-serialization-protobuf-json</artifactId>
348+
<version>${project.version}</version>
349+
</dependency>
345350
<dependency>
346351
<groupId>org.apache.dubbo</groupId>
347352
<artifactId>dubbo-compatible</artifactId>

dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,8 @@ public class Constants {
727727

728728
public static final String GENERIC_SERIALIZATION_BEAN = "bean";
729729

730+
public static final String GENERIC_SERIALIZATION_PROTOBUF = "protobuf-json";
731+
730732
public static final String DUBBO_IP_TO_REGISTRY = "DUBBO_IP_TO_REGISTRY";
731733

732734
public static final String DUBBO_PORT_TO_REGISTRY = "DUBBO_PORT_TO_REGISTRY";

dubbo-dependencies-bom/pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
<cxf_version>3.1.15</cxf_version>
109109
<thrift_version>0.12.0</thrift_version>
110110
<hessian_version>4.0.38</hessian_version>
111+
<protobuf-java_version>3.6.0</protobuf-java_version>
111112
<servlet_version>3.1.0</servlet_version>
112113
<jetty_version>9.4.11.v20180605</jetty_version>
113114
<validation_version>1.1.0.Final</validation_version>
@@ -271,6 +272,16 @@
271272
<artifactId>hessian-lite</artifactId>
272273
<version>${hessian_lite_version}</version>
273274
</dependency>
275+
<dependency>
276+
<groupId>com.google.protobuf</groupId>
277+
<artifactId>protobuf-java</artifactId>
278+
<version>${protobuf-java_version}</version>
279+
</dependency>
280+
<dependency>
281+
<groupId>com.google.protobuf</groupId>
282+
<artifactId>protobuf-java-util</artifactId>
283+
<version>${protobuf-java_version}</version>
284+
</dependency>
274285
<dependency>
275286
<groupId>javax.servlet</groupId>
276287
<artifactId>javax.servlet-api</artifactId>

dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
7676
} else if (ProtocolUtils.isJavaGenericSerialization(generic)) {
7777
for (int i = 0; i < args.length; i++) {
7878
if (byte[].class == args[i].getClass()) {
79-
try(UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) {
79+
try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) {
8080
args[i] = ExtensionLoader.getExtensionLoader(Serialization.class)
8181
.getExtension(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA)
8282
.deserialize(null, is).readObject();
@@ -107,6 +107,26 @@ public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
107107
args[i].getClass().getName());
108108
}
109109
}
110+
} else if (ProtocolUtils.isProtobufGenericSerialization(generic)) {
111+
// as proto3 only accept one protobuf parameter
112+
if (args.length == 1 && args[0] instanceof String) {
113+
try (UnsafeByteArrayInputStream is =
114+
new UnsafeByteArrayInputStream(((String) args[0]).getBytes())) {
115+
args[0] = ExtensionLoader.getExtensionLoader(Serialization.class)
116+
.getExtension("" + Constants.GENERIC_SERIALIZATION_PROTOBUF)
117+
.deserialize(null, is).readObject(method.getParameterTypes()[0]);
118+
} catch (Exception e) {
119+
throw new RpcException("Deserialize argument failed.", e);
120+
}
121+
} else {
122+
throw new RpcException(
123+
"Generic serialization [" +
124+
Constants.GENERIC_SERIALIZATION_PROTOBUF +
125+
"] only support one" + String.class.getName() +
126+
" argument and your message size is " +
127+
args.length + " and type is" +
128+
args[0].getClass().getName());
129+
}
110130
}
111131
Result result = invoker.invoke(new RpcInvocation(method, args, inv.getAttachments()));
112132
if (result.hasException()
@@ -121,10 +141,25 @@ public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
121141
.serialize(null, os).writeObject(result.getValue());
122142
return new RpcResult(os.toByteArray());
123143
} catch (IOException e) {
124-
throw new RpcException("Serialize result failed.", e);
144+
throw new RpcException(
145+
"Generic serialization [" +
146+
Constants.GENERIC_SERIALIZATION_NATIVE_JAVA +
147+
"] serialize result failed.", e);
125148
}
126149
} else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
127150
return new RpcResult(JavaBeanSerializeUtil.serialize(result.getValue(), JavaBeanAccessor.METHOD));
151+
} else if (ProtocolUtils.isProtobufGenericSerialization(generic)) {
152+
try {
153+
UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512);
154+
ExtensionLoader.getExtensionLoader(Serialization.class)
155+
.getExtension(Constants.GENERIC_SERIALIZATION_PROTOBUF)
156+
.serialize(null, os).writeObject(result.getValue());
157+
return new RpcResult(os.toString());
158+
} catch (IOException e) {
159+
throw new RpcException("Generic serialization [" +
160+
Constants.GENERIC_SERIALIZATION_PROTOBUF +
161+
"] serialize result failed.", e);
162+
}
128163
} else {
129164
return new RpcResult(PojoUtils.generalize(result.getValue()));
130165
}

dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/ProtocolUtils.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ public static boolean isGeneric(String generic) {
5151
&& !"".equals(generic)
5252
&& (Constants.GENERIC_SERIALIZATION_DEFAULT.equalsIgnoreCase(generic) /* Normal generalization cal */
5353
|| Constants.GENERIC_SERIALIZATION_NATIVE_JAVA.equalsIgnoreCase(generic) /* Streaming generalization call supporting jdk serialization */
54-
|| Constants.GENERIC_SERIALIZATION_BEAN.equalsIgnoreCase(generic));
54+
|| Constants.GENERIC_SERIALIZATION_BEAN.equalsIgnoreCase(generic)
55+
|| Constants.GENERIC_SERIALIZATION_PROTOBUF.equalsIgnoreCase(generic));
5556
}
5657

5758
public static boolean isDefaultGenericSerialization(String generic) {
@@ -67,4 +68,8 @@ public static boolean isJavaGenericSerialization(String generic) {
6768
public static boolean isBeanGenericSerialization(String generic) {
6869
return isGeneric(generic) && Constants.GENERIC_SERIALIZATION_BEAN.equals(generic);
6970
}
71+
72+
public static boolean isProtobufGenericSerialization(String generic) {
73+
return isGeneric(generic) && Constants.GENERIC_SERIALIZATION_PROTOBUF.equals(generic);
74+
}
7075
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<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">
18+
<modelVersion>4.0.0</modelVersion>
19+
<parent>
20+
<artifactId>dubbo-serialization</artifactId>
21+
<groupId>org.apache.dubbo</groupId>
22+
<version>${revision}</version>
23+
</parent>
24+
<artifactId>dubbo-serialization-protobuf-json</artifactId>
25+
<packaging>jar</packaging>
26+
<name>${project.artifactId}</name>
27+
<description>The protobuf serialization module of dubbo project</description>
28+
<properties>
29+
<skip_maven_deploy>false</skip_maven_deploy>
30+
</properties>
31+
<dependencies>
32+
<dependency>
33+
<groupId>org.apache.dubbo</groupId>
34+
<artifactId>dubbo-serialization-api</artifactId>
35+
<version>${project.parent.version}</version>
36+
</dependency>
37+
<dependency>
38+
<groupId>com.google.protobuf</groupId>
39+
<artifactId>protobuf-java</artifactId>
40+
</dependency>
41+
<dependency>
42+
<groupId>com.google.protobuf</groupId>
43+
<artifactId>protobuf-java-util</artifactId>
44+
</dependency>
45+
</dependencies>
46+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.dubbo.common.serialize.protobuf.support;
18+
19+
import org.apache.dubbo.common.serialize.ObjectInput;
20+
21+
import java.io.BufferedReader;
22+
import java.io.EOFException;
23+
import java.io.IOException;
24+
import java.io.InputStream;
25+
import java.io.InputStreamReader;
26+
import java.lang.reflect.Type;
27+
28+
/**
29+
* GenericGoogleProtobuf object input implementation
30+
*/
31+
public class GenericProtobufObjectInput implements ObjectInput {
32+
private final BufferedReader reader;
33+
34+
public GenericProtobufObjectInput(InputStream in) {
35+
this.reader = new BufferedReader(new InputStreamReader(in));
36+
}
37+
38+
@Override
39+
public boolean readBool() throws IOException {
40+
return read(boolean.class);
41+
}
42+
43+
@Override
44+
public byte readByte() throws IOException {
45+
return read(byte.class);
46+
}
47+
48+
@Override
49+
public short readShort() throws IOException {
50+
return read(short.class);
51+
}
52+
53+
@Override
54+
public int readInt() throws IOException {
55+
return read(int.class);
56+
}
57+
58+
@Override
59+
public long readLong() throws IOException {
60+
return read(long.class);
61+
}
62+
63+
@Override
64+
public float readFloat() throws IOException {
65+
return read(float.class);
66+
}
67+
68+
@Override
69+
public double readDouble() throws IOException {
70+
return read(double.class);
71+
}
72+
73+
@Override
74+
public String readUTF() throws IOException {
75+
return read(String.class);
76+
}
77+
78+
@Override
79+
public byte[] readBytes() throws IOException {
80+
return readLine().getBytes();
81+
}
82+
83+
@Override
84+
public Object readObject() throws IOException {
85+
return read(String.class);
86+
}
87+
88+
@Override
89+
public <T> T readObject(Class<T> cls) throws IOException {
90+
return read(cls);
91+
}
92+
93+
@Override
94+
@SuppressWarnings("unchecked")
95+
public <T> T readObject(Class<T> cls, Type type) throws IOException {
96+
return readObject(cls);
97+
}
98+
99+
private String readLine() throws IOException {
100+
String line = reader.readLine();
101+
if (line == null || line.trim().length() == 0) {
102+
throw new EOFException();
103+
}
104+
return line;
105+
}
106+
107+
private <T> T read(Class<T> cls) throws IOException {
108+
if (!ProtobufUtils.isSupported(cls)) {
109+
throw new IllegalArgumentException("This serialization only support google protobuf entity, the class is :" + cls.getName());
110+
}
111+
112+
String json = readLine();
113+
return ProtobufUtils.deserialize(json, cls);
114+
}
115+
}

0 commit comments

Comments
 (0)