From edb7bed9e86d76c09495bcbfee0317d26f7906bb Mon Sep 17 00:00:00 2001 From: zrlw Date: Tue, 14 Sep 2021 17:04:24 +0800 Subject: [PATCH 01/34] add ServiceConfigURLDelegate for protostuff --- .../dubbo-serialization-protostuff/pom.xml | 54 + .../protostuff/ProtostuffObjectInput.java | 136 ++ .../protostuff/ProtostuffObjectOutput.java | 130 ++ .../protostuff/ProtostuffSerialization.java | 58 + .../common/serialize/protostuff/Wrapper.java | 33 + .../delegate/ServiceConfigURLDelegate.java | 57 + .../protostuff/delegate/SqlDateDelegate.java | 55 + .../protostuff/delegate/TimeDelegate.java | 57 + .../delegate/TimestampDelegate.java | 57 + .../protostuff/utils/WrapperUtils.java | 118 ++ ...pache.dubbo.common.serialize.Serialization | 1 + .../dubbo-serialization-test/pom.xml | 7 +- .../AbstractSerializationPersonFailTest.java | 141 ++ .../AbstractSerializationPersonOkTest.java | 92 ++ .../base/AbstractSerializationTest.java | 1188 +++++++++++++++++ .../ProtostuffObjectOutputTest.java | 259 ++++ .../ProtostuffSerializationTest.java | 27 + dubbo-serialization-extensions/pom.xml | 1 + 18 files changed, 2470 insertions(+), 1 deletion(-) create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/pom.xml create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffSerialization.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/Wrapper.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/ServiceConfigURLDelegate.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/SqlDateDelegate.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/TimeDelegate.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/TimestampDelegate.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/utils/WrapperUtils.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization create mode 100644 dubbo-serialization-extensions/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/base/AbstractSerializationPersonFailTest.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/base/AbstractSerializationPersonOkTest.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/base/AbstractSerializationTest.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutputTest.java create mode 100644 dubbo-serialization-extensions/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffSerializationTest.java diff --git a/dubbo-serialization-extensions/dubbo-serialization-protostuff/pom.xml b/dubbo-serialization-extensions/dubbo-serialization-protostuff/pom.xml new file mode 100644 index 000000000..720355884 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-protostuff/pom.xml @@ -0,0 +1,54 @@ + + + + 4.0.0 + + org.apache.dubbo.extensions + dubbo-serialization-extensions + ${revision} + ../pom.xml + + + dubbo-serialization-protostuff + jar + ${project.artifactId} + The protostuff serialization module of dubbo project + + + 1.5.9 + false + + + + + org.apache.dubbo + dubbo-serialization-api + + + io.protostuff + protostuff-core + ${protostuff.version} + + + io.protostuff + protostuff-runtime + ${protostuff.version} + + + + diff --git a/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java new file mode 100644 index 000000000..e8307748d --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectInput.java @@ -0,0 +1,136 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.common.serialize.protostuff; + +import io.protostuff.GraphIOUtil; +import io.protostuff.Schema; +import io.protostuff.runtime.RuntimeSchema; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Type; +import org.apache.dubbo.common.serialize.ObjectInput; +import org.apache.dubbo.common.serialize.protostuff.utils.WrapperUtils; + +/** + * Protostuff object input implementation + */ +public class ProtostuffObjectInput implements ObjectInput { + + private DataInputStream dis; + + public ProtostuffObjectInput(InputStream inputStream) { + dis = new DataInputStream(inputStream); + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + @Override + public Object readObject() throws IOException, ClassNotFoundException { + int classNameLength = dis.readInt(); + int bytesLength = dis.readInt(); + + if (classNameLength < 0 || bytesLength < 0) { + throw new IOException(); + } + + byte[] classNameBytes = new byte[classNameLength]; + dis.readFully(classNameBytes, 0, classNameLength); + + byte[] bytes = new byte[bytesLength]; + dis.readFully(bytes, 0, bytesLength); + + String className = new String(classNameBytes); + Class clazz = Class.forName(className); + + Object result; + if (WrapperUtils.needWrapper(clazz)) { + Schema schema = RuntimeSchema.getSchema(Wrapper.class); + Wrapper wrapper = schema.newMessage(); + GraphIOUtil.mergeFrom(bytes, wrapper, schema); + result = wrapper.getData(); + } else { + Schema schema = RuntimeSchema.getSchema(clazz); + result = schema.newMessage(); + GraphIOUtil.mergeFrom(bytes, result, schema); + } + + return result; + } + + @SuppressWarnings("unchecked") + @Override + public T readObject(Class clazz) throws IOException, ClassNotFoundException { + return (T) readObject(); + } + + @Override + public T readObject(Class cls, Type type) throws IOException, ClassNotFoundException { + return readObject(cls); + } + + @Override + public boolean readBool() throws IOException { + return dis.readBoolean(); + } + + @Override + public byte readByte() throws IOException { + return dis.readByte(); + } + + @Override + public short readShort() throws IOException { + return dis.readShort(); + } + + @Override + public int readInt() throws IOException { + return dis.readInt(); + } + + @Override + public long readLong() throws IOException { + return dis.readLong(); + } + + @Override + public float readFloat() throws IOException { + return dis.readFloat(); + } + + @Override + public double readDouble() throws IOException { + return dis.readDouble(); + } + + @Override + public String readUTF() throws IOException { + int length = dis.readInt(); + byte[] bytes = new byte[length]; + dis.read(bytes, 0, length); + return new String(bytes); + } + + @Override + public byte[] readBytes() throws IOException { + int length = dis.readInt(); + byte[] bytes = new byte[length]; + dis.read(bytes, 0, length); + return bytes; + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java new file mode 100644 index 000000000..ab94d3ba8 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffObjectOutput.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.common.serialize.protostuff; + +import io.protostuff.GraphIOUtil; +import io.protostuff.LinkedBuffer; +import io.protostuff.Schema; +import io.protostuff.runtime.RuntimeSchema; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import org.apache.dubbo.common.serialize.ObjectOutput; +import org.apache.dubbo.common.serialize.protostuff.utils.WrapperUtils; + +/** + * Protostuff object output implementation + */ +public class ProtostuffObjectOutput implements ObjectOutput { + + private LinkedBuffer buffer = LinkedBuffer.allocate(); + private DataOutputStream dos; + + public ProtostuffObjectOutput(OutputStream outputStream) { + dos = new DataOutputStream(outputStream); + } + + @SuppressWarnings("unchecked") + @Override + public void writeObject(Object obj) throws IOException { + + byte[] bytes; + byte[] classNameBytes; + + try { + if (obj == null || WrapperUtils.needWrapper(obj)) { + Schema schema = RuntimeSchema.getSchema(Wrapper.class); + Wrapper wrapper = new Wrapper(obj); + bytes = GraphIOUtil.toByteArray(wrapper, schema, buffer); + classNameBytes = Wrapper.class.getName().getBytes(); + } else { + Schema schema = RuntimeSchema.getSchema(obj.getClass()); + bytes = GraphIOUtil.toByteArray(obj, schema, buffer); + classNameBytes = obj.getClass().getName().getBytes(); + } + } finally { + buffer.clear(); + } + + dos.writeInt(classNameBytes.length); + dos.writeInt(bytes.length); + dos.write(classNameBytes); + dos.write(bytes); + } + + @Override + public void writeBool(boolean v) throws IOException { + dos.writeBoolean(v); + } + + @Override + public void writeByte(byte v) throws IOException { + dos.writeByte(v); + } + + @Override + public void writeShort(short v) throws IOException { + dos.writeShort(v); + } + + @Override + public void writeInt(int v) throws IOException { + dos.writeInt(v); + } + + @Override + public void writeLong(long v) throws IOException { + dos.writeLong(v); + } + + @Override + public void writeFloat(float v) throws IOException { + dos.writeFloat(v); + } + + @Override + public void writeDouble(double v) throws IOException { + dos.writeDouble(v); + } + + @Override + public void writeUTF(String v) throws IOException { + byte[] bytes = v.getBytes(); + dos.writeInt(bytes.length); + dos.write(bytes); + } + + @Override + public void writeBytes(byte[] v) throws IOException { + dos.writeInt(v.length); + dos.write(v); + } + + @Override + public void writeBytes(byte[] v, int off, int len) throws IOException { + dos.writeInt(len); + byte[] bytes = new byte[len]; + System.arraycopy(v, off, bytes, 0, len); + dos.write(bytes); + } + + @Override + public void flushBuffer() throws IOException { + dos.flush(); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffSerialization.java b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffSerialization.java new file mode 100644 index 000000000..5218cef98 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/ProtostuffSerialization.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.common.serialize.protostuff; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.serialize.ObjectInput; +import org.apache.dubbo.common.serialize.ObjectOutput; +import org.apache.dubbo.common.serialize.Serialization; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import static org.apache.dubbo.common.serialize.Constants.PROTOSTUFF_SERIALIZATION_ID; + +/** + * Protostuff serialization implementation + * + *
+ *     e.g. <dubbo:protocol serialization="protostuff" />
+ * 
+ */ +public class ProtostuffSerialization implements Serialization { + @Override + public byte getContentTypeId() { + return PROTOSTUFF_SERIALIZATION_ID; + } + + @Override + public String getContentType() { + return "x-application/protostuff"; + } + + @Override + public ObjectOutput serialize(URL url, OutputStream output) throws IOException { + return new ProtostuffObjectOutput(output); + } + + @Override + public ObjectInput deserialize(URL url, InputStream input) throws IOException { + return new ProtostuffObjectInput(input); + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/Wrapper.java b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/Wrapper.java new file mode 100644 index 000000000..9b56b43fa --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/Wrapper.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.common.serialize.protostuff; + +/** + * Protostuff can only serialize/deserialize POJOs, for those it can't deal with, use this Wrapper. + */ +public class Wrapper { + private T data; + + Wrapper(T data) { + this.data = data; + } + + Object getData() { + return data; + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/ServiceConfigURLDelegate.java b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/ServiceConfigURLDelegate.java new file mode 100644 index 000000000..6ea8b3b25 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/ServiceConfigURLDelegate.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.common.serialize.protostuff.delegate; + +import io.protostuff.Input; +import io.protostuff.Output; +import io.protostuff.Pipe; +import io.protostuff.WireFormat; +import io.protostuff.runtime.Delegate; + +import java.io.IOException; + +import org.apache.dubbo.common.url.component.ServiceConfigURL; + +/** + * Custom {@link org.apache.dubbo.common.url.component.ServiceConfigURL} delegate + */ +public class ServiceConfigURLDelegate implements Delegate { + @Override + public WireFormat.FieldType getFieldType() { + return WireFormat.FieldType.STRING; + } + + @Override + public ServiceConfigURL readFrom(Input input) throws IOException { + return (ServiceConfigURL) org.apache.dubbo.common.URL.valueOf(input.readString()); + } + + @Override + public void writeTo(Output output, int number, ServiceConfigURL value, boolean repeated) throws IOException { + output.writeString(number, value.toFullString(), repeated); + } + + @Override + public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException { + output.writeString(number, input.readString(), repeated); + } + + @Override + public Class typeClass() { + return ServiceConfigURL.class; + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/SqlDateDelegate.java b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/SqlDateDelegate.java new file mode 100644 index 000000000..a1a7a421c --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/SqlDateDelegate.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.common.serialize.protostuff.delegate; + +import io.protostuff.Input; +import io.protostuff.Output; +import io.protostuff.Pipe; +import io.protostuff.WireFormat; +import io.protostuff.runtime.Delegate; + +import java.io.IOException; + +/** + * Custom {@link java.sql.Date} delegate + */ +public class SqlDateDelegate implements Delegate { + @Override + public WireFormat.FieldType getFieldType() { + return WireFormat.FieldType.FIXED64; + } + + @Override + public java.sql.Date readFrom(Input input) throws IOException { + return new java.sql.Date(input.readFixed64()); + } + + @Override + public void writeTo(Output output, int number, java.sql.Date value, boolean repeated) throws IOException { + output.writeFixed64(number, value.getTime(), repeated); + } + + @Override + public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException { + output.writeFixed64(number, input.readFixed64(), repeated); + } + + @Override + public Class typeClass() { + return java.sql.Date.class; + } +} diff --git a/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/TimeDelegate.java b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/TimeDelegate.java new file mode 100644 index 000000000..6ead01827 --- /dev/null +++ b/dubbo-serialization-extensions/dubbo-serialization-protostuff/src/main/java/org/apache/dubbo/common/serialize/protostuff/delegate/TimeDelegate.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.common.serialize.protostuff.delegate; + +import io.protostuff.Input; +import io.protostuff.Output; +import io.protostuff.Pipe; +import io.protostuff.WireFormat; +import io.protostuff.runtime.Delegate; + +import java.io.IOException; +import java.sql.Time; + +/** + * Custom {@link Time} delegate + */ +public class TimeDelegate implements Delegate