From 50ef46d2c4067498fbf4b490b1e8acef2df5185e Mon Sep 17 00:00:00 2001 From: zhouhaocheng Date: Thu, 27 Apr 2017 14:55:44 +0800 Subject: [PATCH 1/3] add protobuf codec/serialization support and testcase --- motan-extension/codec-extension/pom.xml | 23 + .../weibo/api/motan/codec/ProtobufCodec.java | 362 +++ .../services/com.weibo.api.motan.codec.Codec | 17 + motan-extension/pom.xml | 15 +- .../serialization-extension/pom.xml | 33 +- .../serialize/ProtobufSerialization.java | 127 + .../com.weibo.api.motan.codec.Serialization | 3 +- .../serialize/protobuf/HelloService.java | 37 + .../serialize/protobuf/HelloServiceImpl.java | 70 + .../serialize/protobuf/TestProtoBuf.java | 123 + .../serialize/protobuf/gen/UserProto.java | 2049 +++++++++++++++++ .../src/test/resources/protobuf/User.proto | 18 + .../src/test/resources/protobuf/User2.proto | 17 + 13 files changed, 2878 insertions(+), 16 deletions(-) create mode 100644 motan-extension/codec-extension/pom.xml create mode 100644 motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java create mode 100644 motan-extension/codec-extension/src/main/resources/META-INF/services/com.weibo.api.motan.codec.Codec create mode 100644 motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java create mode 100644 motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloService.java create mode 100644 motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloServiceImpl.java create mode 100644 motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java create mode 100644 motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/gen/UserProto.java create mode 100644 motan-extension/serialization-extension/src/test/resources/protobuf/User.proto create mode 100644 motan-extension/serialization-extension/src/test/resources/protobuf/User2.proto diff --git a/motan-extension/codec-extension/pom.xml b/motan-extension/codec-extension/pom.xml new file mode 100644 index 000000000..edef40a19 --- /dev/null +++ b/motan-extension/codec-extension/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + com.weibo + motan-extension + 0.3.1-SNAPSHOT + + codec-extension + codec-extension + https://github.com/weibocom/motan + + UTF-8 + + + + com.google.protobuf + protobuf-java + 3.2.0 + + + diff --git a/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java b/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java new file mode 100644 index 000000000..a6abcc46b --- /dev/null +++ b/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java @@ -0,0 +1,362 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * 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 + * + * 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 com.weibo.api.motan.codec; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import com.weibo.api.motan.common.MotanConstants; +import com.weibo.api.motan.common.URLParamType; +import com.weibo.api.motan.core.extension.ExtensionLoader; +import com.weibo.api.motan.core.extension.SpiMeta; +import com.weibo.api.motan.exception.MotanErrorMsgConstant; +import com.weibo.api.motan.exception.MotanFrameworkException; +import com.weibo.api.motan.protocol.rpc.RpcProtocolVersion; +import com.weibo.api.motan.rpc.DefaultRequest; +import com.weibo.api.motan.rpc.DefaultResponse; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.transport.Channel; +import com.weibo.api.motan.util.ByteUtil; +import com.weibo.api.motan.util.ExceptionUtil; +import com.weibo.api.motan.util.ReflectUtil; + +/** + * protobuf2/3兼容codec + * + * @author zhouhaocheng + * + */ +@SpiMeta(name = "protobuf") +public class ProtobufCodec implements Codec { + private static final short MAGIC = (short) 0xF0F0; + + private static final byte MASK = 0x07; + + @Override + public byte[] encode(Channel channel, Object message) throws IOException { + if (message instanceof Request) { + return encodeRequest(channel, (Request) message); + } + + if (message instanceof Response) { + return encodeResponse(channel, (Response) message); + } + return null; + } + + /** + * request body 数据: + * + *
+	 *
+	 *   body:
+	 *
+	 *   byte[] data :
+	 *
+	 *          serialize(interface_name, method_name, method_param_desc, method_param_value, attachments_size, attachments_value)
+	 *
+	 *   method_param_desc:  for_each (string.append(method_param_interface_name))
+	 *
+	 *   method_param_value: for_each (method_param_name, method_param_value)
+	 *
+	 *   attachments_value:  for_each (attachment_name, attachment_value)
+	 *
+	 * 
+ * + * @param request + * @return + * @throws IOException + */ + private byte[] encodeRequest(Channel channel, Request request) throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(outputStream); + output.writeStringNoTag(request.getInterfaceName()); + output.writeStringNoTag(request.getMethodName()); + output.writeStringNoTag(request.getParamtersDesc()); + + Serialization serialization = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension( + channel.getUrl().getParameter(URLParamType.serialize.getName(), URLParamType.serialize.getValue())); + + if (request.getArguments() != null && request.getArguments().length > 0) { + for (Object obj : request.getArguments()) { + output.writeByteArrayNoTag(serialization.serialize(obj)); + } + } + + if (request.getAttachments() == null || request.getAttachments().isEmpty()) { + // empty attachments + output.writeUInt32NoTag(0); + } else { + output.writeUInt32NoTag(request.getAttachments().size()); + for (Map.Entry entry : request.getAttachments().entrySet()) { + output.writeStringNoTag(entry.getKey()); + output.writeStringNoTag(entry.getValue()); + } + } + + output.flush(); + byte[] body = outputStream.toByteArray(); + + byte flag = MotanConstants.FLAG_REQUEST; + + return encode(body, flag, request.getRequestId()); + } + + /** + * response body 数据: + * + *
+	 *
+	 * body:
+	 *
+	 *   byte[] :  serialize (result) or serialize (exception)
+	 *
+	 * 
+ * + * @param channel + * @param value + * @return + * @throws IOException + */ + private byte[] encodeResponse(Channel channel, Response value) throws IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(outputStream); + Serialization serialization = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension( + channel.getUrl().getParameter(URLParamType.serialize.getName(), URLParamType.serialize.getValue())); + + byte flag = 0; + + output.writeUInt64NoTag(value.getProcessTime()); + + if (value.getException() != null) { + output.writeStringNoTag(value.getException().getClass().getName()); + output.writeByteArrayNoTag(serialization.serialize(value.getException())); + flag = MotanConstants.FLAG_RESPONSE_EXCEPTION; + } else if (value.getValue() == null) { + flag = MotanConstants.FLAG_RESPONSE_VOID; + } else { + output.writeStringNoTag(value.getValue().getClass().getName()); + output.writeByteArrayNoTag(serialization.serialize(value.getValue())); + flag = MotanConstants.FLAG_RESPONSE; + } + + output.flush(); + + byte[] body = outputStream.toByteArray(); + + return encode(body, flag, value.getRequestId()); + } + + @Override + public Object decode(Channel channel, String remoteIp, byte[] data) throws IOException { + if (data.length <= RpcProtocolVersion.VERSION_1.getHeaderLength()) { + throw new MotanFrameworkException("decode error: format problem", + MotanErrorMsgConstant.FRAMEWORK_DECODE_ERROR); + } + + short type = ByteUtil.bytes2short(data, 0); + + if (type != MAGIC) { + throw new MotanFrameworkException("decode error: magic error", + MotanErrorMsgConstant.FRAMEWORK_DECODE_ERROR); + } + + if (data[2] != RpcProtocolVersion.VERSION_1.getVersion()) { + throw new MotanFrameworkException("decode error: version error", + MotanErrorMsgConstant.FRAMEWORK_DECODE_ERROR); + } + + int bodyLength = ByteUtil.bytes2int(data, 12); + + if (RpcProtocolVersion.VERSION_1.getHeaderLength() + bodyLength != data.length) { + throw new MotanFrameworkException("decode error: content length error", + MotanErrorMsgConstant.FRAMEWORK_DECODE_ERROR); + } + + byte flag = data[3]; + byte dataType = (byte) (flag & MASK); + boolean isResponse = (dataType != MotanConstants.FLAG_REQUEST); + + byte[] body = new byte[bodyLength]; + + System.arraycopy(data, RpcProtocolVersion.VERSION_1.getHeaderLength(), body, 0, bodyLength); + + long requestId = ByteUtil.bytes2long(data, 4); + Serialization serialization = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension( + channel.getUrl().getParameter(URLParamType.serialize.getName(), URLParamType.serialize.getValue())); + + try { + if (isResponse) { // response + return decodeResponse(body, dataType, requestId, serialization); + } else { + return decodeRequest(body, requestId, serialization); + } + } catch (ClassNotFoundException e) { + throw new MotanFrameworkException( + "decode " + (isResponse ? "response" : "request") + " error: class not found", e, + MotanErrorMsgConstant.FRAMEWORK_DECODE_ERROR); + } catch (Exception e) { + if (ExceptionUtil.isMotanException(e)) { + throw (RuntimeException) e; + } else { + throw new MotanFrameworkException("decode error: isResponse=" + isResponse, e, + MotanErrorMsgConstant.FRAMEWORK_DECODE_ERROR); + } + } + } + + private Object decodeRequest(byte[] body, long requestId, Serialization serialization) + throws IOException, ClassNotFoundException { + CodedInputStream input = CodedInputStream.newInstance(body); + + String interfaceName = input.readString(); + String methodName = input.readString(); + String paramtersDesc = input.readString(); + + DefaultRequest rpcRequest = new DefaultRequest(); + rpcRequest.setRequestId(requestId); + rpcRequest.setInterfaceName(interfaceName); + rpcRequest.setMethodName(methodName); + rpcRequest.setParamtersDesc(paramtersDesc); + rpcRequest.setArguments(decodeRequestParameter(input, paramtersDesc, serialization)); + rpcRequest.setAttachments(decodeRequestAttachments(input)); + + return rpcRequest; + } + + private Object[] decodeRequestParameter(CodedInputStream input, String parameterDesc, Serialization serialization) + throws IOException, ClassNotFoundException { + if (parameterDesc == null || parameterDesc.equals("")) { + return null; + } + + Class[] classTypes = ReflectUtil.forNames(parameterDesc); + + Object[] paramObjs = new Object[classTypes.length]; + + for (int i = 0; i < classTypes.length; i++) { + paramObjs[i] = serialization.deserialize(input.readByteArray(), classTypes[i]); + } + + return paramObjs; + } + + private Map decodeRequestAttachments(CodedInputStream input) + throws IOException, ClassNotFoundException { + int size = input.readUInt32(); + + if (size <= 0) { + return null; + } + + Map attachments = new HashMap(); + + for (int i = 0; i < size; i++) { + attachments.put(input.readString(), input.readString()); + } + + return attachments; + } + + private Object decodeResponse(byte[] body, byte dataType, long requestId, Serialization serialization) + throws IOException, ClassNotFoundException { + + CodedInputStream input = CodedInputStream.newInstance(body); + long processTime = input.readInt64(); + + DefaultResponse response = new DefaultResponse(); + response.setRequestId(requestId); + response.setProcessTime(processTime); + + if (dataType == MotanConstants.FLAG_RESPONSE_VOID) { + return response; + } + + String className = input.readString(); + Class clz = ReflectUtil.forName(className); + + Object result = serialization.deserialize(input.readByteArray(), clz); + + if (dataType == MotanConstants.FLAG_RESPONSE) { + response.setValue(result); + } else if (dataType == MotanConstants.FLAG_RESPONSE_EXCEPTION) { + response.setException((Exception) result); + } else { + throw new MotanFrameworkException("decode error: response dataType not support " + dataType, + MotanErrorMsgConstant.FRAMEWORK_DECODE_ERROR); + } + + response.setRequestId(requestId); + + return response; + } + + /** + * 数据协议: + * + *
+	 *
+	 * header:  16个字节
+	 *
+	 * 0-15 bit     :  magic
+	 * 16-23 bit    :  version
+	 * 24-31 bit    :  extend flag , 其中: 29-30 bit: event 可支持4种event,比如normal, exception等,  31 bit : 0 is request , 1 is response
+	 * 32-95 bit    :  request id
+	 * 96-127 bit   :  body content length
+	 *
+	 * 
+ * + * @param body + * @param flag + * @param requestId + * @return + * @throws IOException + */ + private byte[] encode(byte[] body, byte flag, long requestId) throws IOException { + byte[] header = new byte[RpcProtocolVersion.VERSION_1.getHeaderLength()]; + int offset = 0; + + // 0 - 15 bit : magic + ByteUtil.short2bytes(MAGIC, header, offset); + offset += 2; + + // 16 - 23 bit : version + header[offset++] = RpcProtocolVersion.VERSION_1.getVersion(); + + // 24 - 31 bit : extend flag + header[offset++] = flag; + + // 32 - 95 bit : requestId + ByteUtil.long2bytes(requestId, header, offset); + offset += 8; + + // 96 - 127 bit : body content length + ByteUtil.int2bytes(body.length, header, offset); + + byte[] data = new byte[header.length + body.length]; + + System.arraycopy(header, 0, data, 0, header.length); + System.arraycopy(body, 0, data, header.length, body.length); + + return data; + } + +} diff --git a/motan-extension/codec-extension/src/main/resources/META-INF/services/com.weibo.api.motan.codec.Codec b/motan-extension/codec-extension/src/main/resources/META-INF/services/com.weibo.api.motan.codec.Codec new file mode 100644 index 000000000..5523d225b --- /dev/null +++ b/motan-extension/codec-extension/src/main/resources/META-INF/services/com.weibo.api.motan.codec.Codec @@ -0,0 +1,17 @@ +# +# Copyright 2009-2016 Weibo, Inc. +# +# 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 +# +# 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. +# + +com.weibo.api.motan.codec.ProtobufCodec diff --git a/motan-extension/pom.xml b/motan-extension/pom.xml index b13753528..259e95605 100644 --- a/motan-extension/pom.xml +++ b/motan-extension/pom.xml @@ -1,11 +1,11 @@ - @@ -33,5 +33,6 @@ serialization-extension protocol-extension filter-extension + codec-extension \ No newline at end of file diff --git a/motan-extension/serialization-extension/pom.xml b/motan-extension/serialization-extension/pom.xml index e5cd2f6d3..6432ed0b9 100644 --- a/motan-extension/serialization-extension/pom.xml +++ b/motan-extension/serialization-extension/pom.xml @@ -1,13 +1,13 @@ - - + @@ -24,6 +24,12 @@ UTF-8 + + junit + junit + 4.12 + test + org.hprose hprose-java @@ -34,5 +40,16 @@ motan-core ${project.version} + + com.weibo + motan-transport-netty + ${project.version} + test + + + com.google.protobuf + protobuf-java + 3.2.0 + diff --git a/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java b/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java new file mode 100644 index 000000000..43f52b107 --- /dev/null +++ b/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java @@ -0,0 +1,127 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * 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 + * + * 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 com.weibo.api.motan.serialize; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Method; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import com.google.protobuf.MessageLite; +import com.weibo.api.motan.codec.Serialization; +import com.weibo.api.motan.core.extension.SpiMeta; +import com.weibo.api.motan.exception.MotanFrameworkException; + +/** + * protobuf序列化器,支持基本数据类型及其包装类、String、Throwable、Protobuf2/3对象 + * + * @author zhouhaocheng + * + */ +@SpiMeta(name = "protobuf") +public class ProtobufSerialization implements Serialization { + + @Override + public byte[] serialize(Object obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(baos); + output.writeBoolNoTag(obj == null); + if (obj == null) { + output.flush(); + return baos.toByteArray(); + } + + Class clazz = obj.getClass(); + if (clazz == int.class || clazz == Integer.class) { + output.writeSInt32NoTag((Integer) obj); + } else if (clazz == long.class || clazz == Long.class) { + output.writeSInt64NoTag((Long) obj); + } else if (clazz == boolean.class || clazz == Boolean.class) { + output.writeBoolNoTag((Boolean) obj); + } else if (clazz == byte.class || clazz == Byte.class) { + output.writeRawByte((Byte) obj); + } else if (clazz == char.class || clazz == Character.class) { + output.writeSInt32NoTag((Character) obj); + } else if (clazz == double.class || clazz == Double.class) { + output.writeDoubleNoTag((Double) obj); + } else if (clazz == float.class || clazz == Float.class) { + output.writeFloatNoTag((Float) obj); + } else if (clazz == String.class) { + output.writeStringNoTag(obj.toString()); + } else if (MessageLite.class.isAssignableFrom(clazz)) { + baos.write(MessageLite.class.cast(obj).toByteArray()); + } else if (Throwable.class.isAssignableFrom(clazz)) { + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + } else { + throw new IllegalArgumentException("can't serialize " + clazz); + } + + output.flush(); + return baos.toByteArray(); + } + + @SuppressWarnings("unchecked") + @Override + public T deserialize(byte[] bytes, Class clazz) throws IOException { + if (bytes[0] == 1) + return null; + + Object value = null; + CodedInputStream in = CodedInputStream.newInstance(bytes, 1, bytes.length - 1); + if (clazz == int.class || clazz == Integer.class) { + value = in.readSInt32(); + } else if (clazz == long.class || clazz == Long.class) { + value = in.readSInt64(); + } else if (clazz == boolean.class || clazz == Boolean.class) { + value = in.readBool(); + } else if (clazz == byte.class || clazz == Byte.class) { + value = in.readRawByte(); + } else if (clazz == char.class || clazz == Character.class) { + value = (char) in.readSInt32(); + } else if (clazz == double.class || clazz == Double.class) { + value = in.readDouble(); + } else if (clazz == float.class || clazz == Float.class) { + value = in.readFloat(); + } else if (clazz == String.class) { + value = in.readString(); + } else if (MessageLite.class.isAssignableFrom(clazz)) { + try { + Method method = clazz.getDeclaredMethod("parseFrom", InputStream.class); + value = method.invoke(null, new ByteArrayInputStream(bytes, 0, bytes.length - 1)); + } catch (Exception e) { + throw new MotanFrameworkException(e); + } + } else if (Throwable.class.isAssignableFrom(clazz)) { + try { + ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes, 0, bytes.length - 1)); + value = ois.readObject(); + } catch (ClassNotFoundException e) { + throw new MotanFrameworkException(e); + } + } else { + throw new IllegalArgumentException("can't serialize " + clazz); + } + + return (T) value; + } + +} diff --git a/motan-extension/serialization-extension/src/main/resources/META-INF/services/com.weibo.api.motan.codec.Serialization b/motan-extension/serialization-extension/src/main/resources/META-INF/services/com.weibo.api.motan.codec.Serialization index 6a42d9ac1..67302ad3b 100644 --- a/motan-extension/serialization-extension/src/main/resources/META-INF/services/com.weibo.api.motan.codec.Serialization +++ b/motan-extension/serialization-extension/src/main/resources/META-INF/services/com.weibo.api.motan.codec.Serialization @@ -14,4 +14,5 @@ # limitations under the License. # -com.weibo.api.motan.serialize.HproseSerialization \ No newline at end of file +com.weibo.api.motan.serialize.HproseSerialization +com.weibo.api.motan.serialize.ProtobufSerialization \ No newline at end of file diff --git a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloService.java b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloService.java new file mode 100644 index 000000000..141684b70 --- /dev/null +++ b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloService.java @@ -0,0 +1,37 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * 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 + * + * 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 com.weibo.api.motan.serialize.protobuf; + +import com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address; +import com.weibo.api.motan.serialize.protobuf.gen.UserProto.User; + +public interface HelloService{ + + Address queryByUid(int uid); + + Long boxIfNotZero(int value); + + boolean isUserAddress(User user, Address address); + + void testException(); + + boolean isNull(User user); + + User copy(User origin); + + String sumAsString(int a, int b); + +} diff --git a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloServiceImpl.java b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloServiceImpl.java new file mode 100644 index 000000000..8efbf49d0 --- /dev/null +++ b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloServiceImpl.java @@ -0,0 +1,70 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * 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 + * + * 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 com.weibo.api.motan.serialize.protobuf; + +import com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address; +import com.weibo.api.motan.serialize.protobuf.gen.UserProto.User; + +public class HelloServiceImpl implements HelloService{ + + @Override + public String sumAsString(int a, int b){ + return String.valueOf(a + b); + } + + @Override + public Long boxIfNotZero(int value){ + return value == 0 ? null : (long) value; + } + + @Override + public Address queryByUid(int uid){ + return Address.newBuilder() + .setId(uid) + .setProvince("北京") + .setCity("北京") + .setStreet("无") + .setPhone("1233444") + .build(); + } + + @Override + public boolean isUserAddress(User user, Address address){ + for(Address item : user.getAddressList()){ + if(item.getId() == address.getId()){ + return true; + } + } + + return false; + } + + @Override + public boolean isNull(User user){ + return user == null; + } + + @Override + public void testException(){ + throw new UnsupportedOperationException(); + } + + @Override + public User copy(User origin){ + return origin; + } + +} diff --git a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java new file mode 100644 index 000000000..0006aa394 --- /dev/null +++ b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java @@ -0,0 +1,123 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * 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 + * + * 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 com.weibo.api.motan.serialize.protobuf; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.weibo.api.motan.config.ProtocolConfig; +import com.weibo.api.motan.config.RefererConfig; +import com.weibo.api.motan.config.RegistryConfig; +import com.weibo.api.motan.config.ServiceConfig; +import com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address; +import com.weibo.api.motan.serialize.protobuf.gen.UserProto.User; + +public class TestProtoBuf{ + private ServiceConfig serviceConfig; + private RefererConfig refererConfig; + + @Before + public void setUp(){ + ProtocolConfig protocolConfig = new ProtocolConfig(); + protocolConfig.setId("testMotan"); + protocolConfig.setName("motan"); + protocolConfig.setSerialization("protobuf"); + protocolConfig.setCodec("motan"); + + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("127.0.0.1"); + registryConfig.setPort(8002); + + serviceConfig = new ServiceConfig(); + serviceConfig.setRef(new HelloServiceImpl()); + serviceConfig.setInterface(HelloService.class); + serviceConfig.setProtocol(protocolConfig); + serviceConfig.setExport("testMotan:8002"); + serviceConfig.setRegistry(registryConfig); + serviceConfig.setShareChannel(true); + + serviceConfig.export(); + + refererConfig = new RefererConfig(); + refererConfig.setDirectUrl("127.0.0.1:8002"); + refererConfig.setProtocol(protocolConfig); + refererConfig.setInterface(HelloService.class); + + refererConfig.getRef(); + } + + @Test + public void testPrimitiveType(){ + HelloService service = refererConfig.getRef(); + + Assert.assertEquals("-1", service.sumAsString(Integer.MAX_VALUE, Integer.MIN_VALUE)); + Assert.assertEquals("-1", service.sumAsString(-2, 1)); + + Assert.assertEquals((Long) 100L, service.boxIfNotZero(100)); + Assert.assertNull(service.boxIfNotZero(0)); + } + + @Test(expected = UnsupportedOperationException.class) + public void testException(){ + HelloService service = refererConfig.getRef(); + service.testException(); + } + + @Test + public void testNull(){ + HelloService service = refererConfig.getRef(); + + Assert.assertTrue(service.isNull(null)); + + User user = User.newBuilder() + .setId(120) + .setName("zhou") + .build(); + + Assert.assertFalse(service.isNull(user)); + } + + @Test + public void testProtobuf(){ + HelloService service = refererConfig.getRef(); + Address address = service.queryByUid(1); + Assert.assertEquals(1, address.getId()); + + User user = User.newBuilder() + .setId(120) + .setName("zhou") + .setGender(false) + .addAddress(address) + .build(); + + Assert.assertTrue(service.isUserAddress(user, address)); + + User newOne = service.copy(user); + Assert.assertEquals(user.getId(), newOne.getId()); + Assert.assertEquals(user.getName(), newOne.getName()); + Assert.assertEquals(user.getGender(), newOne.getGender()); + Assert.assertEquals(user.getAddress(0).getId(), newOne.getAddress(0).getId()); + } + + @After + public void tearDown(){ + refererConfig.destroy(); + serviceConfig.unexport(); + } + +} diff --git a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/gen/UserProto.java b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/gen/UserProto.java new file mode 100644 index 000000000..4e00d1b8e --- /dev/null +++ b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/gen/UserProto.java @@ -0,0 +1,2049 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: User.proto + +package com.weibo.api.motan.serialize.protobuf.gen; + +public final class UserProto { + private UserProto() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + public interface UserOrBuilder extends + // @@protoc_insertion_point(interface_extends:User) + com.google.protobuf.MessageOrBuilder { + + /** + * int32 id = 1; + */ + int getId(); + + /** + * string name = 2; + */ + java.lang.String getName(); + /** + * string name = 2; + */ + com.google.protobuf.ByteString + getNameBytes(); + + /** + * bool gender = 3; + */ + boolean getGender(); + + /** + * repeated .Address address = 4; + */ + java.util.List + getAddressList(); + /** + * repeated .Address address = 4; + */ + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address getAddress(int index); + /** + * repeated .Address address = 4; + */ + int getAddressCount(); + /** + * repeated .Address address = 4; + */ + java.util.List + getAddressOrBuilderList(); + /** + * repeated .Address address = 4; + */ + com.weibo.api.motan.serialize.protobuf.gen.UserProto.AddressOrBuilder getAddressOrBuilder( + int index); + } + /** + * Protobuf type {@code User} + */ + public static final class User extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:User) + UserOrBuilder { + // Use User.newBuilder() to construct. + private User(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private User() { + id_ = 0; + name_ = ""; + gender_ = false; + address_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private User( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 8: { + + id_ = input.readInt32(); + break; + } + case 18: { + java.lang.String s = input.readStringRequireUtf8(); + + name_ = s; + break; + } + case 24: { + + gender_ = input.readBool(); + break; + } + case 34: { + if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + address_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000008; + } + address_.add( + input.readMessage(com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.parser(), extensionRegistry)); + 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 { + if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + address_ = java.util.Collections.unmodifiableList(address_); + } + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_User_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_User_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.weibo.api.motan.serialize.protobuf.gen.UserProto.User.class, com.weibo.api.motan.serialize.protobuf.gen.UserProto.User.Builder.class); + } + + private int bitField0_; + public static final int ID_FIELD_NUMBER = 1; + private int id_; + /** + * int32 id = 1; + */ + public int getId() { + return id_; + } + + public static final int NAME_FIELD_NUMBER = 2; + private volatile java.lang.Object name_; + /** + * string name = 2; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + 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(); + name_ = s; + return s; + } + } + /** + * string name = 2; + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int GENDER_FIELD_NUMBER = 3; + private boolean gender_; + /** + * bool gender = 3; + */ + public boolean getGender() { + return gender_; + } + + public static final int ADDRESS_FIELD_NUMBER = 4; + private java.util.List address_; + /** + * repeated .Address address = 4; + */ + public java.util.List getAddressList() { + return address_; + } + /** + * repeated .Address address = 4; + */ + public java.util.List + getAddressOrBuilderList() { + return address_; + } + /** + * repeated .Address address = 4; + */ + public int getAddressCount() { + return address_.size(); + } + /** + * repeated .Address address = 4; + */ + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address getAddress(int index) { + return address_.get(index); + } + /** + * repeated .Address address = 4; + */ + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.AddressOrBuilder getAddressOrBuilder( + int index) { + return address_.get(index); + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (id_ != 0) { + output.writeInt32(1, id_); + } + if (!getNameBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, name_); + } + if (gender_ != false) { + output.writeBool(3, gender_); + } + for (int i = 0; i < address_.size(); i++) { + output.writeMessage(4, address_.get(i)); + } + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (id_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, id_); + } + if (!getNameBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, name_); + } + if (gender_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(3, gender_); + } + for (int i = 0; i < address_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, address_.get(i)); + } + memoizedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.weibo.api.motan.serialize.protobuf.gen.UserProto.User)) { + return super.equals(obj); + } + com.weibo.api.motan.serialize.protobuf.gen.UserProto.User other = (com.weibo.api.motan.serialize.protobuf.gen.UserProto.User) obj; + + boolean result = true; + result = result && (getId() + == other.getId()); + result = result && getName() + .equals(other.getName()); + result = result && (getGender() + == other.getGender()); + result = result && getAddressList() + .equals(other.getAddressList()); + return result; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ID_FIELD_NUMBER; + hash = (53 * hash) + getId(); + hash = (37 * hash) + NAME_FIELD_NUMBER; + hash = (53 * hash) + getName().hashCode(); + hash = (37 * hash) + GENDER_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getGender()); + if (getAddressCount() > 0) { + hash = (37 * hash) + ADDRESS_FIELD_NUMBER; + hash = (53 * hash) + getAddressList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User 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 com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User 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 com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.weibo.api.motan.serialize.protobuf.gen.UserProto.User prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + 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 User} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:User) + com.weibo.api.motan.serialize.protobuf.gen.UserProto.UserOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_User_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_User_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.weibo.api.motan.serialize.protobuf.gen.UserProto.User.class, com.weibo.api.motan.serialize.protobuf.gen.UserProto.User.Builder.class); + } + + // Construct using com.weibo.api.motan.serialize.protobuf.gen.UserProto.User.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getAddressFieldBuilder(); + } + } + public Builder clear() { + super.clear(); + id_ = 0; + + name_ = ""; + + gender_ = false; + + if (addressBuilder_ == null) { + address_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + } else { + addressBuilder_.clear(); + } + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_User_descriptor; + } + + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.User getDefaultInstanceForType() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.User.getDefaultInstance(); + } + + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.User build() { + com.weibo.api.motan.serialize.protobuf.gen.UserProto.User result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.User buildPartial() { + com.weibo.api.motan.serialize.protobuf.gen.UserProto.User result = new com.weibo.api.motan.serialize.protobuf.gen.UserProto.User(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + result.id_ = id_; + result.name_ = name_; + result.gender_ = gender_; + if (addressBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008)) { + address_ = java.util.Collections.unmodifiableList(address_); + bitField0_ = (bitField0_ & ~0x00000008); + } + result.address_ = address_; + } else { + result.address_ = addressBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.weibo.api.motan.serialize.protobuf.gen.UserProto.User) { + return mergeFrom((com.weibo.api.motan.serialize.protobuf.gen.UserProto.User)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.weibo.api.motan.serialize.protobuf.gen.UserProto.User other) { + if (other == com.weibo.api.motan.serialize.protobuf.gen.UserProto.User.getDefaultInstance()) return this; + if (other.getId() != 0) { + setId(other.getId()); + } + if (!other.getName().isEmpty()) { + name_ = other.name_; + onChanged(); + } + if (other.getGender() != false) { + setGender(other.getGender()); + } + if (addressBuilder_ == null) { + if (!other.address_.isEmpty()) { + if (address_.isEmpty()) { + address_ = other.address_; + bitField0_ = (bitField0_ & ~0x00000008); + } else { + ensureAddressIsMutable(); + address_.addAll(other.address_); + } + onChanged(); + } + } else { + if (!other.address_.isEmpty()) { + if (addressBuilder_.isEmpty()) { + addressBuilder_.dispose(); + addressBuilder_ = null; + address_ = other.address_; + bitField0_ = (bitField0_ & ~0x00000008); + addressBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getAddressFieldBuilder() : null; + } else { + addressBuilder_.addAllMessages(other.address_); + } + } + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.weibo.api.motan.serialize.protobuf.gen.UserProto.User parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.weibo.api.motan.serialize.protobuf.gen.UserProto.User) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private int id_ ; + /** + * int32 id = 1; + */ + public int getId() { + return id_; + } + /** + * int32 id = 1; + */ + public Builder setId(int value) { + + id_ = value; + onChanged(); + return this; + } + /** + * int32 id = 1; + */ + public Builder clearId() { + + id_ = 0; + onChanged(); + return this; + } + + private java.lang.Object name_ = ""; + /** + * string name = 2; + */ + public java.lang.String getName() { + java.lang.Object ref = name_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + name_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string name = 2; + */ + public com.google.protobuf.ByteString + getNameBytes() { + java.lang.Object ref = name_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + name_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string name = 2; + */ + public Builder setName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + name_ = value; + onChanged(); + return this; + } + /** + * string name = 2; + */ + public Builder clearName() { + + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + /** + * string name = 2; + */ + public Builder setNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + name_ = value; + onChanged(); + return this; + } + + private boolean gender_ ; + /** + * bool gender = 3; + */ + public boolean getGender() { + return gender_; + } + /** + * bool gender = 3; + */ + public Builder setGender(boolean value) { + + gender_ = value; + onChanged(); + return this; + } + /** + * bool gender = 3; + */ + public Builder clearGender() { + + gender_ = false; + onChanged(); + return this; + } + + private java.util.List address_ = + java.util.Collections.emptyList(); + private void ensureAddressIsMutable() { + if (!((bitField0_ & 0x00000008) == 0x00000008)) { + address_ = new java.util.ArrayList(address_); + bitField0_ |= 0x00000008; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder, com.weibo.api.motan.serialize.protobuf.gen.UserProto.AddressOrBuilder> addressBuilder_; + + /** + * repeated .Address address = 4; + */ + public java.util.List getAddressList() { + if (addressBuilder_ == null) { + return java.util.Collections.unmodifiableList(address_); + } else { + return addressBuilder_.getMessageList(); + } + } + /** + * repeated .Address address = 4; + */ + public int getAddressCount() { + if (addressBuilder_ == null) { + return address_.size(); + } else { + return addressBuilder_.getCount(); + } + } + /** + * repeated .Address address = 4; + */ + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address getAddress(int index) { + if (addressBuilder_ == null) { + return address_.get(index); + } else { + return addressBuilder_.getMessage(index); + } + } + /** + * repeated .Address address = 4; + */ + public Builder setAddress( + int index, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address value) { + if (addressBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressIsMutable(); + address_.set(index, value); + onChanged(); + } else { + addressBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public Builder setAddress( + int index, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder builderForValue) { + if (addressBuilder_ == null) { + ensureAddressIsMutable(); + address_.set(index, builderForValue.build()); + onChanged(); + } else { + addressBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public Builder addAddress(com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address value) { + if (addressBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressIsMutable(); + address_.add(value); + onChanged(); + } else { + addressBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public Builder addAddress( + int index, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address value) { + if (addressBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressIsMutable(); + address_.add(index, value); + onChanged(); + } else { + addressBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public Builder addAddress( + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder builderForValue) { + if (addressBuilder_ == null) { + ensureAddressIsMutable(); + address_.add(builderForValue.build()); + onChanged(); + } else { + addressBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public Builder addAddress( + int index, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder builderForValue) { + if (addressBuilder_ == null) { + ensureAddressIsMutable(); + address_.add(index, builderForValue.build()); + onChanged(); + } else { + addressBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public Builder addAllAddress( + java.lang.Iterable values) { + if (addressBuilder_ == null) { + ensureAddressIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, address_); + onChanged(); + } else { + addressBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public Builder clearAddress() { + if (addressBuilder_ == null) { + address_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + } else { + addressBuilder_.clear(); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public Builder removeAddress(int index) { + if (addressBuilder_ == null) { + ensureAddressIsMutable(); + address_.remove(index); + onChanged(); + } else { + addressBuilder_.remove(index); + } + return this; + } + /** + * repeated .Address address = 4; + */ + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder getAddressBuilder( + int index) { + return getAddressFieldBuilder().getBuilder(index); + } + /** + * repeated .Address address = 4; + */ + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.AddressOrBuilder getAddressOrBuilder( + int index) { + if (addressBuilder_ == null) { + return address_.get(index); } else { + return addressBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .Address address = 4; + */ + public java.util.List + getAddressOrBuilderList() { + if (addressBuilder_ != null) { + return addressBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(address_); + } + } + /** + * repeated .Address address = 4; + */ + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder addAddressBuilder() { + return getAddressFieldBuilder().addBuilder( + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.getDefaultInstance()); + } + /** + * repeated .Address address = 4; + */ + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder addAddressBuilder( + int index) { + return getAddressFieldBuilder().addBuilder( + index, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.getDefaultInstance()); + } + /** + * repeated .Address address = 4; + */ + public java.util.List + getAddressBuilderList() { + return getAddressFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder, com.weibo.api.motan.serialize.protobuf.gen.UserProto.AddressOrBuilder> + getAddressFieldBuilder() { + if (addressBuilder_ == null) { + addressBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder, com.weibo.api.motan.serialize.protobuf.gen.UserProto.AddressOrBuilder>( + address_, + ((bitField0_ & 0x00000008) == 0x00000008), + getParentForChildren(), + isClean()); + address_ = null; + } + return addressBuilder_; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:User) + } + + // @@protoc_insertion_point(class_scope:User) + private static final com.weibo.api.motan.serialize.protobuf.gen.UserProto.User DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.weibo.api.motan.serialize.protobuf.gen.UserProto.User(); + } + + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.User getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public User parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new User(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.User getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AddressOrBuilder extends + // @@protoc_insertion_point(interface_extends:Address) + com.google.protobuf.MessageOrBuilder { + + /** + * int32 id = 1; + */ + int getId(); + + /** + * string province = 2; + */ + java.lang.String getProvince(); + /** + * string province = 2; + */ + com.google.protobuf.ByteString + getProvinceBytes(); + + /** + * string city = 3; + */ + java.lang.String getCity(); + /** + * string city = 3; + */ + com.google.protobuf.ByteString + getCityBytes(); + + /** + * string street = 4; + */ + java.lang.String getStreet(); + /** + * string street = 4; + */ + com.google.protobuf.ByteString + getStreetBytes(); + + /** + * string phone = 5; + */ + java.lang.String getPhone(); + /** + * string phone = 5; + */ + com.google.protobuf.ByteString + getPhoneBytes(); + } + /** + * Protobuf type {@code Address} + */ + public static final class Address extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:Address) + AddressOrBuilder { + // Use Address.newBuilder() to construct. + private Address(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Address() { + id_ = 0; + province_ = ""; + city_ = ""; + street_ = ""; + phone_ = ""; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private Address( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 8: { + + id_ = input.readInt32(); + break; + } + case 18: { + java.lang.String s = input.readStringRequireUtf8(); + + province_ = s; + break; + } + case 26: { + java.lang.String s = input.readStringRequireUtf8(); + + city_ = s; + break; + } + case 34: { + java.lang.String s = input.readStringRequireUtf8(); + + street_ = s; + break; + } + case 42: { + java.lang.String s = input.readStringRequireUtf8(); + + phone_ = s; + 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 { + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_Address_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_Address_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.class, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder.class); + } + + public static final int ID_FIELD_NUMBER = 1; + private int id_; + /** + * int32 id = 1; + */ + public int getId() { + return id_; + } + + public static final int PROVINCE_FIELD_NUMBER = 2; + private volatile java.lang.Object province_; + /** + * string province = 2; + */ + public java.lang.String getProvince() { + java.lang.Object ref = province_; + 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(); + province_ = s; + return s; + } + } + /** + * string province = 2; + */ + public com.google.protobuf.ByteString + getProvinceBytes() { + java.lang.Object ref = province_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + province_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CITY_FIELD_NUMBER = 3; + private volatile java.lang.Object city_; + /** + * string city = 3; + */ + public java.lang.String getCity() { + java.lang.Object ref = city_; + 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(); + city_ = s; + return s; + } + } + /** + * string city = 3; + */ + public com.google.protobuf.ByteString + getCityBytes() { + java.lang.Object ref = city_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + city_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int STREET_FIELD_NUMBER = 4; + private volatile java.lang.Object street_; + /** + * string street = 4; + */ + public java.lang.String getStreet() { + java.lang.Object ref = street_; + 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(); + street_ = s; + return s; + } + } + /** + * string street = 4; + */ + public com.google.protobuf.ByteString + getStreetBytes() { + java.lang.Object ref = street_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + street_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PHONE_FIELD_NUMBER = 5; + private volatile java.lang.Object phone_; + /** + * string phone = 5; + */ + public java.lang.String getPhone() { + java.lang.Object ref = phone_; + 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(); + phone_ = s; + return s; + } + } + /** + * string phone = 5; + */ + public com.google.protobuf.ByteString + getPhoneBytes() { + java.lang.Object ref = phone_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + phone_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (id_ != 0) { + output.writeInt32(1, id_); + } + if (!getProvinceBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, province_); + } + if (!getCityBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, city_); + } + if (!getStreetBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, street_); + } + if (!getPhoneBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, phone_); + } + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (id_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, id_); + } + if (!getProvinceBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, province_); + } + if (!getCityBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, city_); + } + if (!getStreetBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, street_); + } + if (!getPhoneBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, phone_); + } + memoizedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address)) { + return super.equals(obj); + } + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address other = (com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address) obj; + + boolean result = true; + result = result && (getId() + == other.getId()); + result = result && getProvince() + .equals(other.getProvince()); + result = result && getCity() + .equals(other.getCity()); + result = result && getStreet() + .equals(other.getStreet()); + result = result && getPhone() + .equals(other.getPhone()); + return result; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ID_FIELD_NUMBER; + hash = (53 * hash) + getId(); + hash = (37 * hash) + PROVINCE_FIELD_NUMBER; + hash = (53 * hash) + getProvince().hashCode(); + hash = (37 * hash) + CITY_FIELD_NUMBER; + hash = (53 * hash) + getCity().hashCode(); + hash = (37 * hash) + STREET_FIELD_NUMBER; + hash = (53 * hash) + getStreet().hashCode(); + hash = (37 * hash) + PHONE_FIELD_NUMBER; + hash = (53 * hash) + getPhone().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address 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 com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address 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 com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + 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 Address} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:Address) + com.weibo.api.motan.serialize.protobuf.gen.UserProto.AddressOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_Address_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_Address_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.class, com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.Builder.class); + } + + // Construct using com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + id_ = 0; + + province_ = ""; + + city_ = ""; + + street_ = ""; + + phone_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.internal_static_Address_descriptor; + } + + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address getDefaultInstanceForType() { + return com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.getDefaultInstance(); + } + + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address build() { + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address buildPartial() { + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address result = new com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address(this); + result.id_ = id_; + result.province_ = province_; + result.city_ = city_; + result.street_ = street_; + result.phone_ = phone_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address) { + return mergeFrom((com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address other) { + if (other == com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address.getDefaultInstance()) return this; + if (other.getId() != 0) { + setId(other.getId()); + } + if (!other.getProvince().isEmpty()) { + province_ = other.province_; + onChanged(); + } + if (!other.getCity().isEmpty()) { + city_ = other.city_; + onChanged(); + } + if (!other.getStreet().isEmpty()) { + street_ = other.street_; + onChanged(); + } + if (!other.getPhone().isEmpty()) { + phone_ = other.phone_; + onChanged(); + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private int id_ ; + /** + * int32 id = 1; + */ + public int getId() { + return id_; + } + /** + * int32 id = 1; + */ + public Builder setId(int value) { + + id_ = value; + onChanged(); + return this; + } + /** + * int32 id = 1; + */ + public Builder clearId() { + + id_ = 0; + onChanged(); + return this; + } + + private java.lang.Object province_ = ""; + /** + * string province = 2; + */ + public java.lang.String getProvince() { + java.lang.Object ref = province_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + province_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string province = 2; + */ + public com.google.protobuf.ByteString + getProvinceBytes() { + java.lang.Object ref = province_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + province_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string province = 2; + */ + public Builder setProvince( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + province_ = value; + onChanged(); + return this; + } + /** + * string province = 2; + */ + public Builder clearProvince() { + + province_ = getDefaultInstance().getProvince(); + onChanged(); + return this; + } + /** + * string province = 2; + */ + public Builder setProvinceBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + province_ = value; + onChanged(); + return this; + } + + private java.lang.Object city_ = ""; + /** + * string city = 3; + */ + public java.lang.String getCity() { + java.lang.Object ref = city_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + city_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string city = 3; + */ + public com.google.protobuf.ByteString + getCityBytes() { + java.lang.Object ref = city_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + city_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string city = 3; + */ + public Builder setCity( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + city_ = value; + onChanged(); + return this; + } + /** + * string city = 3; + */ + public Builder clearCity() { + + city_ = getDefaultInstance().getCity(); + onChanged(); + return this; + } + /** + * string city = 3; + */ + public Builder setCityBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + city_ = value; + onChanged(); + return this; + } + + private java.lang.Object street_ = ""; + /** + * string street = 4; + */ + public java.lang.String getStreet() { + java.lang.Object ref = street_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + street_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string street = 4; + */ + public com.google.protobuf.ByteString + getStreetBytes() { + java.lang.Object ref = street_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + street_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string street = 4; + */ + public Builder setStreet( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + street_ = value; + onChanged(); + return this; + } + /** + * string street = 4; + */ + public Builder clearStreet() { + + street_ = getDefaultInstance().getStreet(); + onChanged(); + return this; + } + /** + * string street = 4; + */ + public Builder setStreetBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + street_ = value; + onChanged(); + return this; + } + + private java.lang.Object phone_ = ""; + /** + * string phone = 5; + */ + public java.lang.String getPhone() { + java.lang.Object ref = phone_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + phone_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string phone = 5; + */ + public com.google.protobuf.ByteString + getPhoneBytes() { + java.lang.Object ref = phone_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + phone_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string phone = 5; + */ + public Builder setPhone( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + phone_ = value; + onChanged(); + return this; + } + /** + * string phone = 5; + */ + public Builder clearPhone() { + + phone_ = getDefaultInstance().getPhone(); + onChanged(); + return this; + } + /** + * string phone = 5; + */ + public Builder setPhoneBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + phone_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:Address) + } + + // @@protoc_insertion_point(class_scope:Address) + private static final com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address(); + } + + public static com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser
+ PARSER = new com.google.protobuf.AbstractParser
() { + public Address parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Address(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser
parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser
getParserForType() { + return PARSER; + } + + public com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_User_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_User_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_Address_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_Address_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\nUser.proto\"K\n\004User\022\n\n\002id\030\001 \001(\005\022\014\n\004name" + + "\030\002 \001(\t\022\016\n\006gender\030\003 \001(\010\022\031\n\007address\030\004 \003(\0132" + + "\010.Address\"T\n\007Address\022\n\n\002id\030\001 \001(\005\022\020\n\010prov" + + "ince\030\002 \001(\t\022\014\n\004city\030\003 \001(\t\022\016\n\006street\030\004 \001(\t" + + "\022\r\n\005phone\030\005 \001(\tB7\n*com.weibo.api.motan.s" + + "erialize.protobuf.genB\tUserProtob\006proto3" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + internal_static_User_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_User_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_User_descriptor, + new java.lang.String[] { "Id", "Name", "Gender", "Address", }); + internal_static_Address_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_Address_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_Address_descriptor, + new java.lang.String[] { "Id", "Province", "City", "Street", "Phone", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/motan-extension/serialization-extension/src/test/resources/protobuf/User.proto b/motan-extension/serialization-extension/src/test/resources/protobuf/User.proto new file mode 100644 index 000000000..6791ac8be --- /dev/null +++ b/motan-extension/serialization-extension/src/test/resources/protobuf/User.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +option java_package = "com.weibo.api.motan.serialize.protobuf.gen"; +option java_outer_classname = "UserProto"; + +message User{ + int32 id = 1; + string name = 2; + bool gender = 3; + repeated Address address = 4; +} + +message Address{ + int32 id = 1; + string province = 2; + string city = 3; + string street = 4; + string phone = 5; +} diff --git a/motan-extension/serialization-extension/src/test/resources/protobuf/User2.proto b/motan-extension/serialization-extension/src/test/resources/protobuf/User2.proto new file mode 100644 index 000000000..4b3bbd4ab --- /dev/null +++ b/motan-extension/serialization-extension/src/test/resources/protobuf/User2.proto @@ -0,0 +1,17 @@ +option java_package = "com.weibo.api.motan.serialize.protobuf.gen2"; +option java_outer_classname = "UserProto2"; + +message User{ + required int32 id = 1; + required string name = 2; + optional bool gender = 3; + repeated Address address = 4; +} + +message Address{ + required int32 id = 1; + optional string province = 2; + optional string city = 3; + optional string street = 4; + required string phone = 5; +} From c3711ebf38458987a81ca095ad892d7f3512d065 Mon Sep 17 00:00:00 2001 From: zhouhaocheng Date: Fri, 28 Apr 2017 10:27:54 +0800 Subject: [PATCH 2/3] fix serilize short bug,format test code style --- motan-extension/codec-extension/pom.xml | 9 + .../weibo/api/motan/codec/ProtobufCodec.java | 12 +- .../serialize/ProtobufSerialization.java | 4 + .../serialize/protobuf/HelloService.java | 16 +- .../serialize/protobuf/HelloServiceImpl.java | 75 ++++---- .../serialize/protobuf/TestProtoBuf.java | 176 +++++++++--------- 6 files changed, 144 insertions(+), 148 deletions(-) diff --git a/motan-extension/codec-extension/pom.xml b/motan-extension/codec-extension/pom.xml index edef40a19..9a1228f6f 100644 --- a/motan-extension/codec-extension/pom.xml +++ b/motan-extension/codec-extension/pom.xml @@ -1,4 +1,13 @@ + + 4.0.0 diff --git a/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java b/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java index a6abcc46b..3e97a9de7 100644 --- a/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java +++ b/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java @@ -195,9 +195,8 @@ public Object decode(Channel channel, String remoteIp, byte[] data) throws IOExc byte dataType = (byte) (flag & MASK); boolean isResponse = (dataType != MotanConstants.FLAG_REQUEST); - byte[] body = new byte[bodyLength]; - - System.arraycopy(data, RpcProtocolVersion.VERSION_1.getHeaderLength(), body, 0, bodyLength); + CodedInputStream body = CodedInputStream.newInstance(data, RpcProtocolVersion.VERSION_1.getHeaderLength(), + bodyLength); long requestId = ByteUtil.bytes2long(data, 4); Serialization serialization = ExtensionLoader.getExtensionLoader(Serialization.class).getExtension( @@ -223,10 +222,8 @@ public Object decode(Channel channel, String remoteIp, byte[] data) throws IOExc } } - private Object decodeRequest(byte[] body, long requestId, Serialization serialization) + private Object decodeRequest(CodedInputStream input, long requestId, Serialization serialization) throws IOException, ClassNotFoundException { - CodedInputStream input = CodedInputStream.newInstance(body); - String interfaceName = input.readString(); String methodName = input.readString(); String paramtersDesc = input.readString(); @@ -276,10 +273,9 @@ private Map decodeRequestAttachments(CodedInputStream input) return attachments; } - private Object decodeResponse(byte[] body, byte dataType, long requestId, Serialization serialization) + private Object decodeResponse(CodedInputStream input, byte dataType, long requestId, Serialization serialization) throws IOException, ClassNotFoundException { - CodedInputStream input = CodedInputStream.newInstance(body); long processTime = input.readInt64(); DefaultResponse response = new DefaultResponse(); diff --git a/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java b/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java index 43f52b107..51a217867 100644 --- a/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java +++ b/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java @@ -60,6 +60,8 @@ public byte[] serialize(Object obj) throws IOException { output.writeRawByte((Byte) obj); } else if (clazz == char.class || clazz == Character.class) { output.writeSInt32NoTag((Character) obj); + } else if (clazz == short.class || clazz == Short.class) { + output.writeSInt32NoTag((Short) obj); } else if (clazz == double.class || clazz == Double.class) { output.writeDoubleNoTag((Double) obj); } else if (clazz == float.class || clazz == Float.class) { @@ -97,6 +99,8 @@ public T deserialize(byte[] bytes, Class clazz) throws IOException { value = in.readRawByte(); } else if (clazz == char.class || clazz == Character.class) { value = (char) in.readSInt32(); + } else if (clazz == short.class || clazz == Short.class) { + value = (short) in.readSInt32(); } else if (clazz == double.class || clazz == Double.class) { value = in.readDouble(); } else if (clazz == float.class || clazz == Float.class) { diff --git a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloService.java b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloService.java index 141684b70..ebf633244 100644 --- a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloService.java +++ b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloService.java @@ -18,20 +18,20 @@ import com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address; import com.weibo.api.motan.serialize.protobuf.gen.UserProto.User; -public interface HelloService{ +public interface HelloService { - Address queryByUid(int uid); + Address queryByUid(int uid); - Long boxIfNotZero(int value); + Long boxIfNotZero(int value); - boolean isUserAddress(User user, Address address); + boolean isUserAddress(User user, Address address); - void testException(); + void testException(); - boolean isNull(User user); + boolean isNull(User user); - User copy(User origin); + User copy(User origin); - String sumAsString(int a, int b); + String sumAsString(int a, int b); } diff --git a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloServiceImpl.java b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloServiceImpl.java index 8efbf49d0..47504a71c 100644 --- a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloServiceImpl.java +++ b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/HelloServiceImpl.java @@ -18,53 +18,48 @@ import com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address; import com.weibo.api.motan.serialize.protobuf.gen.UserProto.User; -public class HelloServiceImpl implements HelloService{ +public class HelloServiceImpl implements HelloService { - @Override - public String sumAsString(int a, int b){ - return String.valueOf(a + b); - } + @Override + public String sumAsString(int a, int b) { + return String.valueOf(a + b); + } - @Override - public Long boxIfNotZero(int value){ - return value == 0 ? null : (long) value; - } + @Override + public Long boxIfNotZero(int value) { + return value == 0 ? null : (long) value; + } - @Override - public Address queryByUid(int uid){ - return Address.newBuilder() - .setId(uid) - .setProvince("北京") - .setCity("北京") - .setStreet("无") - .setPhone("1233444") - .build(); - } + @Override + public Address queryByUid(int uid) { + return Address.newBuilder().setId(uid).setProvince("北京").setCity("北京").setStreet("无").setPhone("1233444") + .build(); + } - @Override - public boolean isUserAddress(User user, Address address){ - for(Address item : user.getAddressList()){ - if(item.getId() == address.getId()){ - return true; - } - } + @Override + public boolean isUserAddress(User user, Address address) { + for (Address item : user.getAddressList()) { + if (item.getId() == address.getId()) { + return true; + } + } - return false; - } + return false; + } - @Override - public boolean isNull(User user){ - return user == null; - } + @Override + public boolean isNull(User user) { + return user == null; + } - @Override - public void testException(){ - throw new UnsupportedOperationException(); - } + @Override + public void testException() { + throw new UnsupportedOperationException(); + } - @Override - public User copy(User origin){ - return origin; - } + @Override + public User copy(User origin) { + return origin; + } } diff --git a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java index 0006aa394..048fe62d9 100644 --- a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java +++ b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java @@ -27,97 +27,89 @@ import com.weibo.api.motan.serialize.protobuf.gen.UserProto.Address; import com.weibo.api.motan.serialize.protobuf.gen.UserProto.User; -public class TestProtoBuf{ - private ServiceConfig serviceConfig; - private RefererConfig refererConfig; - - @Before - public void setUp(){ - ProtocolConfig protocolConfig = new ProtocolConfig(); - protocolConfig.setId("testMotan"); - protocolConfig.setName("motan"); - protocolConfig.setSerialization("protobuf"); - protocolConfig.setCodec("motan"); - - RegistryConfig registryConfig = new RegistryConfig(); - registryConfig.setAddress("127.0.0.1"); - registryConfig.setPort(8002); - - serviceConfig = new ServiceConfig(); - serviceConfig.setRef(new HelloServiceImpl()); - serviceConfig.setInterface(HelloService.class); - serviceConfig.setProtocol(protocolConfig); - serviceConfig.setExport("testMotan:8002"); - serviceConfig.setRegistry(registryConfig); - serviceConfig.setShareChannel(true); - - serviceConfig.export(); - - refererConfig = new RefererConfig(); - refererConfig.setDirectUrl("127.0.0.1:8002"); - refererConfig.setProtocol(protocolConfig); - refererConfig.setInterface(HelloService.class); - - refererConfig.getRef(); - } - - @Test - public void testPrimitiveType(){ - HelloService service = refererConfig.getRef(); - - Assert.assertEquals("-1", service.sumAsString(Integer.MAX_VALUE, Integer.MIN_VALUE)); - Assert.assertEquals("-1", service.sumAsString(-2, 1)); - - Assert.assertEquals((Long) 100L, service.boxIfNotZero(100)); - Assert.assertNull(service.boxIfNotZero(0)); - } - - @Test(expected = UnsupportedOperationException.class) - public void testException(){ - HelloService service = refererConfig.getRef(); - service.testException(); - } - - @Test - public void testNull(){ - HelloService service = refererConfig.getRef(); - - Assert.assertTrue(service.isNull(null)); - - User user = User.newBuilder() - .setId(120) - .setName("zhou") - .build(); - - Assert.assertFalse(service.isNull(user)); - } - - @Test - public void testProtobuf(){ - HelloService service = refererConfig.getRef(); - Address address = service.queryByUid(1); - Assert.assertEquals(1, address.getId()); - - User user = User.newBuilder() - .setId(120) - .setName("zhou") - .setGender(false) - .addAddress(address) - .build(); - - Assert.assertTrue(service.isUserAddress(user, address)); - - User newOne = service.copy(user); - Assert.assertEquals(user.getId(), newOne.getId()); - Assert.assertEquals(user.getName(), newOne.getName()); - Assert.assertEquals(user.getGender(), newOne.getGender()); - Assert.assertEquals(user.getAddress(0).getId(), newOne.getAddress(0).getId()); - } - - @After - public void tearDown(){ - refererConfig.destroy(); - serviceConfig.unexport(); - } +public class TestProtoBuf { + private ServiceConfig serviceConfig; + private RefererConfig refererConfig; + + @Before + public void setUp() { + ProtocolConfig protocolConfig = new ProtocolConfig(); + protocolConfig.setId("testMotan"); + protocolConfig.setName("motan"); + protocolConfig.setSerialization("protobuf"); + protocolConfig.setCodec("motan"); + + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("127.0.0.1"); + registryConfig.setPort(8002); + + serviceConfig = new ServiceConfig(); + serviceConfig.setRef(new HelloServiceImpl()); + serviceConfig.setInterface(HelloService.class); + serviceConfig.setProtocol(protocolConfig); + serviceConfig.setExport("testMotan:8002"); + serviceConfig.setRegistry(registryConfig); + serviceConfig.setShareChannel(true); + + serviceConfig.export(); + + refererConfig = new RefererConfig(); + refererConfig.setDirectUrl("127.0.0.1:8002"); + refererConfig.setProtocol(protocolConfig); + refererConfig.setInterface(HelloService.class); + + refererConfig.getRef(); + } + + @Test + public void testPrimitiveType() { + HelloService service = refererConfig.getRef(); + + Assert.assertEquals("-1", service.sumAsString(Integer.MAX_VALUE, Integer.MIN_VALUE)); + Assert.assertEquals("-1", service.sumAsString(-2, 1)); + + Assert.assertEquals((Long) 100L, service.boxIfNotZero(100)); + Assert.assertNull(service.boxIfNotZero(0)); + } + + @Test(expected = UnsupportedOperationException.class) + public void testException() { + HelloService service = refererConfig.getRef(); + service.testException(); + } + + @Test + public void testNull() { + HelloService service = refererConfig.getRef(); + + Assert.assertTrue(service.isNull(null)); + + User user = User.newBuilder().setId(120).setName("zhou").build(); + + Assert.assertFalse(service.isNull(user)); + } + + @Test + public void testProtobuf() { + HelloService service = refererConfig.getRef(); + Address address = service.queryByUid(1); + Assert.assertEquals(1, address.getId()); + + User user = User.newBuilder().setId(120).setName("zhou").setGender(false).addAddress(address).build(); + + Assert.assertTrue(service.isUserAddress(user, address)); + + User newOne = service.copy(user); + Assert.assertEquals(user.getId(), newOne.getId()); + Assert.assertEquals(user.getName(), newOne.getName()); + Assert.assertEquals(user.getGender(), newOne.getGender()); + Assert.assertEquals(user.getAddress(0).getId(), newOne.getAddress(0).getId()); + } + + @After + public void tearDown() { + refererConfig.destroy(); + serviceConfig.unexport(); + } } From ffc69541ba5d2235f4620f63e8d2e3161b9a2e83 Mon Sep 17 00:00:00 2001 From: zhou Date: Thu, 11 May 2017 20:58:43 +0800 Subject: [PATCH 3/3] modify MessageLite serialize/deserialize code --- .../weibo/api/motan/codec/ProtobufCodec.java | 24 +++++++++++++------ .../serialize/ProtobufSerialization.java | 12 ++++++---- .../serialize/protobuf/TestProtoBuf.java | 9 ++----- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java b/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java index 3e97a9de7..116f846c4 100644 --- a/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java +++ b/motan-extension/codec-extension/src/main/java/com/weibo/api/motan/codec/ProtobufCodec.java @@ -39,7 +39,7 @@ import com.weibo.api.motan.util.ReflectUtil; /** - * protobuf2/3兼容codec + * protobuf2/3兼容codec,序列化时不允许attachments中有键或值为null * * @author zhouhaocheng * @@ -52,14 +52,23 @@ public class ProtobufCodec implements Codec { @Override public byte[] encode(Channel channel, Object message) throws IOException { - if (message instanceof Request) { - return encodeRequest(channel, (Request) message); + try { + if (message instanceof Request) { + return encodeRequest(channel, (Request) message); + } else if (message instanceof Response) { + return encodeResponse(channel, (Response) message); + } + } catch (Exception e) { + if (ExceptionUtil.isMotanException(e)) { + throw (RuntimeException) e; + } else { + throw new MotanFrameworkException("encode error: isResponse=" + (message instanceof Response), e, + MotanErrorMsgConstant.FRAMEWORK_ENCODE_ERROR); + } } - if (message instanceof Response) { - return encodeResponse(channel, (Response) message); - } - return null; + throw new MotanFrameworkException("encode error: message type not support, " + message.getClass(), + MotanErrorMsgConstant.FRAMEWORK_ENCODE_ERROR); } /** @@ -107,6 +116,7 @@ private byte[] encodeRequest(Channel channel, Request request) throws IOExceptio } else { output.writeUInt32NoTag(request.getAttachments().size()); for (Map.Entry entry : request.getAttachments().entrySet()) { + //此处不允许attachement键值为null output.writeStringNoTag(entry.getKey()); output.writeStringNoTag(entry.getValue()); } diff --git a/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java b/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java index 51a217867..638fa8ef4 100644 --- a/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java +++ b/motan-extension/serialization-extension/src/main/java/com/weibo/api/motan/serialize/ProtobufSerialization.java @@ -18,7 +18,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Method; @@ -69,10 +68,11 @@ public byte[] serialize(Object obj) throws IOException { } else if (clazz == String.class) { output.writeStringNoTag(obj.toString()); } else if (MessageLite.class.isAssignableFrom(clazz)) { - baos.write(MessageLite.class.cast(obj).toByteArray()); + output.writeMessageNoTag((MessageLite) obj); } else if (Throwable.class.isAssignableFrom(clazz)) { ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj); + oos.flush(); } else { throw new IllegalArgumentException("can't serialize " + clazz); } @@ -109,8 +109,10 @@ public T deserialize(byte[] bytes, Class clazz) throws IOException { value = in.readString(); } else if (MessageLite.class.isAssignableFrom(clazz)) { try { - Method method = clazz.getDeclaredMethod("parseFrom", InputStream.class); - value = method.invoke(null, new ByteArrayInputStream(bytes, 0, bytes.length - 1)); + Method method = clazz.getDeclaredMethod("newBuilder"); + MessageLite.Builder builder = (MessageLite.Builder) method.invoke(null); + in.readMessage(builder, null); + value = builder.build(); } catch (Exception e) { throw new MotanFrameworkException(e); } @@ -122,7 +124,7 @@ public T deserialize(byte[] bytes, Class clazz) throws IOException { throw new MotanFrameworkException(e); } } else { - throw new IllegalArgumentException("can't serialize " + clazz); + throw new IllegalArgumentException("can't deserialize " + clazz); } return (T) value; diff --git a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java index 048fe62d9..767444bfc 100644 --- a/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java +++ b/motan-extension/serialization-extension/src/test/java/com/weibo/api/motan/serialize/protobuf/TestProtoBuf.java @@ -30,6 +30,7 @@ public class TestProtoBuf { private ServiceConfig serviceConfig; private RefererConfig refererConfig; + private HelloService service; @Before public void setUp() { @@ -58,13 +59,11 @@ public void setUp() { refererConfig.setProtocol(protocolConfig); refererConfig.setInterface(HelloService.class); - refererConfig.getRef(); + service = refererConfig.getRef(); } @Test public void testPrimitiveType() { - HelloService service = refererConfig.getRef(); - Assert.assertEquals("-1", service.sumAsString(Integer.MAX_VALUE, Integer.MIN_VALUE)); Assert.assertEquals("-1", service.sumAsString(-2, 1)); @@ -74,14 +73,11 @@ public void testPrimitiveType() { @Test(expected = UnsupportedOperationException.class) public void testException() { - HelloService service = refererConfig.getRef(); service.testException(); } @Test public void testNull() { - HelloService service = refererConfig.getRef(); - Assert.assertTrue(service.isNull(null)); User user = User.newBuilder().setId(120).setName("zhou").build(); @@ -91,7 +87,6 @@ public void testNull() { @Test public void testProtobuf() { - HelloService service = refererConfig.getRef(); Address address = service.queryByUid(1); Assert.assertEquals(1, address.getId());