From 09b6f2315c909b19d5922a43680f1e8fbc7728a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=88=E9=93=AD?= Date: Wed, 28 Feb 2024 14:23:25 +0800 Subject: [PATCH] support for https://github.com/sofastack/sofa-rpc/issues/1398 --- bom/pom.xml | 8 ++ codec/codec-api/pom.xml | 5 ++ .../rpc/codec/biz2/Bzip2RpcCompressor.java | 76 +++++++++++++++++++ .../rpc/codec/gzip/GzipRpcCompressor.java | 70 +++++++++++++++++ .../com.alipay.sofa.rpc.codec.Compressor | 4 +- .../codec/biz2/Bzip2RpcCompressorTest.java | 51 +++++++++++++ .../rpc/codec/gzip/GzipRpcCompressorTest.java | 52 +++++++++++++ 7 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 codec/codec-api/src/main/java/com/alipay/sofa/rpc/codec/biz2/Bzip2RpcCompressor.java create mode 100644 codec/codec-api/src/main/java/com/alipay/sofa/rpc/codec/gzip/GzipRpcCompressor.java create mode 100644 codec/codec-api/src/test/java/com/alipay/sofa/rpc/codec/biz2/Bzip2RpcCompressorTest.java create mode 100644 codec/codec-api/src/test/java/com/alipay/sofa/rpc/codec/gzip/GzipRpcCompressorTest.java diff --git a/bom/pom.xml b/bom/pom.xml index a97d8cc8f..895ebbfb5 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -60,6 +60,8 @@ true true + + 1.25.0 @@ -598,6 +600,12 @@ 0.16.0 test + + + org.apache.commons + commons-compress + ${commons_compress_version} + diff --git a/codec/codec-api/pom.xml b/codec/codec-api/pom.xml index 47b42b4fe..921fa0e31 100644 --- a/codec/codec-api/pom.xml +++ b/codec/codec-api/pom.xml @@ -38,6 +38,11 @@ junit test + + + org.apache.commons + commons-compress + diff --git a/codec/codec-api/src/main/java/com/alipay/sofa/rpc/codec/biz2/Bzip2RpcCompressor.java b/codec/codec-api/src/main/java/com/alipay/sofa/rpc/codec/biz2/Bzip2RpcCompressor.java new file mode 100644 index 000000000..6199e3b95 --- /dev/null +++ b/codec/codec-api/src/main/java/com/alipay/sofa/rpc/codec/biz2/Bzip2RpcCompressor.java @@ -0,0 +1,76 @@ +/* + * 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 com.alipay.sofa.rpc.codec.biz2; + +import com.alipay.sofa.rpc.codec.Compressor; +import com.alipay.sofa.rpc.ext.Extension; +import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; +import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +/** + * bzip2 compressor, faster compression efficiency + * + * @author chengming + * @version Bzip2RpcCompressor.java, v 0.1 2024年02月28日 10:45 AM chengming + * @link https://commons.apache.org/proper/commons-compress/ + */ +@Extension(value = "bzip2", code = 3) +public class Bzip2RpcCompressor implements Compressor { + + @Override + public byte[] compress(byte[] src) { + if (null == src || 0 == src.length) { + return new byte[0]; + } + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + BZip2CompressorOutputStream cos; + try { + cos = new BZip2CompressorOutputStream(out); + cos.write(src); + cos.close(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + + return out.toByteArray(); + } + + @Override + public byte[] deCompress(byte[] src) { + if (null == src || 0 == src.length) { + return new byte[0]; + } + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(src); + try { + BZip2CompressorInputStream unZip = new BZip2CompressorInputStream(in); + byte[] buffer = new byte[2048]; + int n; + while ((n = unZip.read(buffer)) >= 0) { + out.write(buffer, 0, n); + } + } catch (Exception e) { + throw new IllegalStateException(e); + } + return out.toByteArray(); + } +} \ No newline at end of file diff --git a/codec/codec-api/src/main/java/com/alipay/sofa/rpc/codec/gzip/GzipRpcCompressor.java b/codec/codec-api/src/main/java/com/alipay/sofa/rpc/codec/gzip/GzipRpcCompressor.java new file mode 100644 index 000000000..fb30fbcd3 --- /dev/null +++ b/codec/codec-api/src/main/java/com/alipay/sofa/rpc/codec/gzip/GzipRpcCompressor.java @@ -0,0 +1,70 @@ +/* + * 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 com.alipay.sofa.rpc.codec.gzip; + +import com.alipay.sofa.rpc.codec.Compressor; +import com.alipay.sofa.rpc.ext.Extension; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +/** + * @author chengming + * @version GzipRpcCompressor.java, v 0.1 2024年02月28日 11:25 AM chengming + */ +@Extension(value = "bzip2", code = 4) +public class GzipRpcCompressor implements Compressor { + + @Override + public byte[] compress(byte[] src) { + if (null == src || 0 == src.length) { + return new byte[0]; + } + + ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); + try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteOutStream)) { + gzipOutputStream.write(src); + } catch (Exception exception) { + throw new IllegalStateException(exception); + } + + return byteOutStream.toByteArray(); + } + + @Override + public byte[] deCompress(byte[] src) { + if (null == src || 0 == src.length) { + return new byte[0]; + } + + ByteArrayInputStream byteInStream = new ByteArrayInputStream(src); + ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(); + try (GZIPInputStream gzipInputStream = new GZIPInputStream(byteInStream)) { + int readByteNum; + byte[] bufferArr = new byte[256]; + while ((readByteNum = gzipInputStream.read(bufferArr)) >= 0) { + byteOutStream.write(bufferArr, 0, readByteNum); + } + } catch (Exception exception) { + throw new IllegalStateException(exception); + } + + return byteOutStream.toByteArray(); + } +} \ No newline at end of file diff --git a/codec/codec-api/src/main/resources/META-INF/services/sofa-rpc/com.alipay.sofa.rpc.codec.Compressor b/codec/codec-api/src/main/resources/META-INF/services/sofa-rpc/com.alipay.sofa.rpc.codec.Compressor index a0d34faa1..6e5c5a33f 100644 --- a/codec/codec-api/src/main/resources/META-INF/services/sofa-rpc/com.alipay.sofa.rpc.codec.Compressor +++ b/codec/codec-api/src/main/resources/META-INF/services/sofa-rpc/com.alipay.sofa.rpc.codec.Compressor @@ -1 +1,3 @@ -snappy=com.alipay.sofa.rpc.codec.snappy.SnappyRpcCompressor \ No newline at end of file +snappy=com.alipay.sofa.rpc.codec.snappy.SnappyRpcCompressor +bzip2=com.alipay.sofa.rpc.codec.biz2.Bzip2RpcCompressor +gzip=com.alipay.sofa.rpc.codec.gzip.GzipRpcCompressor \ No newline at end of file diff --git a/codec/codec-api/src/test/java/com/alipay/sofa/rpc/codec/biz2/Bzip2RpcCompressorTest.java b/codec/codec-api/src/test/java/com/alipay/sofa/rpc/codec/biz2/Bzip2RpcCompressorTest.java new file mode 100644 index 000000000..3e9112e35 --- /dev/null +++ b/codec/codec-api/src/test/java/com/alipay/sofa/rpc/codec/biz2/Bzip2RpcCompressorTest.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.rpc.codec.biz2; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.UnsupportedEncodingException; + +/** + * @author chengming + * @version Bzip2RpcCompressorTest.java, v 0.1 2024年02月28日 2:19 PM chengming + */ +public class Bzip2RpcCompressorTest { + + private static final String TEST_STR; + + static { + StringBuilder builder = new StringBuilder(); + int charNum = 1000000; + for (int i = 0; i < charNum; i++) { + builder.append("a"); + } + + TEST_STR = builder.toString(); + } + + @Test + public void testCompression() throws UnsupportedEncodingException { + Bzip2RpcCompressor compressor = new Bzip2RpcCompressor(); + byte[] bs = compressor.compress(TEST_STR.getBytes("utf-8")); + Assert.assertNotNull(TEST_STR); + + String s1 = new String(compressor.deCompress(bs), "utf-8"); + Assert.assertEquals(TEST_STR, s1); + } +} \ No newline at end of file diff --git a/codec/codec-api/src/test/java/com/alipay/sofa/rpc/codec/gzip/GzipRpcCompressorTest.java b/codec/codec-api/src/test/java/com/alipay/sofa/rpc/codec/gzip/GzipRpcCompressorTest.java new file mode 100644 index 000000000..440f86fe8 --- /dev/null +++ b/codec/codec-api/src/test/java/com/alipay/sofa/rpc/codec/gzip/GzipRpcCompressorTest.java @@ -0,0 +1,52 @@ +/* + * 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 com.alipay.sofa.rpc.codec.gzip; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.UnsupportedEncodingException; + +/** + * @author chengming + * @version GzipRpcCompressorTest.java, v 0.1 2024年02月28日 2:09 PM chengming + */ +public class GzipRpcCompressorTest { + + private static final String TEST_STR; + + static { + StringBuilder builder = new StringBuilder(); + int charNum = 1000000; + for (int i = 0; i < charNum; i++) { + builder.append("a"); + } + + TEST_STR = builder.toString(); + } + + @Test + public void testCompression() throws UnsupportedEncodingException { + GzipRpcCompressor compressor = new GzipRpcCompressor(); + byte[] bs = compressor.compress(TEST_STR.getBytes("utf-8")); + Assert.assertNotNull(TEST_STR); + + String s1 = new String(compressor.deCompress(bs), "utf-8"); + Assert.assertEquals(TEST_STR, s1); + } + +}