diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ad2fafc6c962..33040f7eb7ad 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -141,12 +141,17 @@ jobs:
- name: Start Dubbo Backend
if: matrix.os_name == 'linux_openresty' && (steps.test_env.outputs.type == 'plugin' || steps.test_env.outputs.type == 'last')
run: |
+ cur_dir=$(pwd)
sudo apt update
sudo apt install -y maven
cd t/lib/dubbo-backend
mvn package
cd dubbo-backend-provider/target
java -Djava.net.preferIPv4Stack=true -jar dubbo-demo-provider.one-jar.jar > /tmp/java.log &
+ cd $cur_dir/t/lib/dubbo-serialization-backend
+ mvn package
+ cd dubbo-serialization-backend-provider/target
+ java -Djava.net.preferIPv4Stack=true -jar dubbo-demo-provider.one-jar.jar > /tmp/java2.log &
- name: Build xDS library
if: steps.test_env.outputs.type == 'last'
diff --git a/.github/workflows/centos7-ci.yml b/.github/workflows/centos7-ci.yml
index 319b188497a0..177e9c8fb8d9 100644
--- a/.github/workflows/centos7-ci.yml
+++ b/.github/workflows/centos7-ci.yml
@@ -99,12 +99,18 @@ jobs:
- name: Start Dubbo Backend
run: |
+ cur_dir=$(pwd)
sudo apt update
sudo apt install -y maven
cd t/lib/dubbo-backend
mvn package
cd dubbo-backend-provider/target
java -Djava.net.preferIPv4Stack=true -jar dubbo-demo-provider.one-jar.jar > /tmp/java.log &
+ cd $cur_dir/t/lib/dubbo-serialization-backend
+ mvn package
+ cd dubbo-serialization-backend-provider/target
+ java -Djava.net.preferIPv4Stack=true -jar dubbo-demo-provider.one-jar.jar > /tmp/java2.log &
+
- name: Build xDS library
if: steps.test_env.outputs.type == 'last'
diff --git a/.github/workflows/gm-cron.yaml b/.github/workflows/gm-cron.yaml
index cac652e961de..b4c8f7e438ef 100644
--- a/.github/workflows/gm-cron.yaml
+++ b/.github/workflows/gm-cron.yaml
@@ -124,12 +124,17 @@ jobs:
- name: Start Dubbo Backend
if: steps.test_env.outputs.type == 'plugin'
run: |
+ cur_dir=$(pwd)
sudo apt update
sudo apt install -y maven
cd t/lib/dubbo-backend
mvn package
cd dubbo-backend-provider/target
java -Djava.net.preferIPv4Stack=true -jar dubbo-demo-provider.one-jar.jar > /tmp/java.log &
+ cd $cur_dir/t/lib/dubbo-serialization-backend
+ mvn package
+ cd dubbo-serialization-backend-provider/target
+ java -Djava.net.preferIPv4Stack=true -jar dubbo-demo-provider.one-jar.jar > /tmp/java2.log &
- name: Build xDS library
if: steps.test_env.outputs.type == 'last'
diff --git a/.github/workflows/redhat-ci.yaml b/.github/workflows/redhat-ci.yaml
index 62ca5b662f95..29b907302af5 100644
--- a/.github/workflows/redhat-ci.yaml
+++ b/.github/workflows/redhat-ci.yaml
@@ -95,12 +95,17 @@ jobs:
- name: Start Dubbo Backend
run: |
+ cur_dir=$(pwd)
sudo apt update
sudo apt install -y maven
cd t/lib/dubbo-backend
mvn package
cd dubbo-backend-provider/target
java -Djava.net.preferIPv4Stack=true -jar dubbo-demo-provider.one-jar.jar > /tmp/java.log &
+ cd $cur_dir/t/lib/dubbo-serialization-backend
+ mvn package
+ cd dubbo-serialization-backend-provider/target
+ java -Djava.net.preferIPv4Stack=true -jar dubbo-demo-provider.one-jar.jar > /tmp/java2.log &
- name: Build xDS library
if: steps.test_env.outputs.type == 'last'
diff --git a/.gitignore b/.gitignore
index 49dbbfe5759e..94669c34502a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,8 +59,7 @@ client_body_temp
utils/lj-releng
utils/reindex
*.etcd/
-t/lib/dubbo-backend/dubbo-backend-interface/target/
-t/lib/dubbo-backend/dubbo-backend-provider/target/
+t/lib/dubbo*/**/target/
.idea/
*.iml
\.*
@@ -88,3 +87,5 @@ pack-v*-linux.tgz*
# release tar package
*.tgz
release/*
+
+
diff --git a/apisix/plugins/http-dubbo.lua b/apisix/plugins/http-dubbo.lua
new file mode 100644
index 000000000000..f068654babc4
--- /dev/null
+++ b/apisix/plugins/http-dubbo.lua
@@ -0,0 +1,262 @@
+--
+-- 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.
+--
+
+local require = require
+local core = require("apisix.core")
+local pairs = pairs
+local str_format = string.format
+local bit = require("bit")
+local rshift = bit.rshift
+local band = bit.band
+local char = string.char
+local tostring = tostring
+local ngx = ngx
+local type = type
+local plugin_name = "http-dubbo"
+
+
+local schema = {
+ type = "object",
+ properties = {
+ service_name = {
+ type = "string",
+ minLength = 1,
+ },
+ service_version = {
+ type = "string",
+ pattern = [[^\d+\.\d+\.\d+]],
+ default ="0.0.0"
+ },
+ method = {
+ type = "string",
+ minLength = 1,
+ },
+ params_type_desc = {
+ type = "string",
+ default = ""
+ },
+ serialization_header_key = {
+ type = "string"
+ },
+ serialized = {
+ type = "boolean",
+ default = false
+ },
+ connect_timeout={
+ type = "number",
+ default = 6000
+ },
+ read_timeout={
+ type = "number",
+ default = 6000
+ },
+ send_timeout={
+ type = "number",
+ default = 6000
+ }
+ },
+ required = { "service_name", "method" },
+}
+
+local _M = {
+ version = 0.1,
+ priority = 504,
+ name = plugin_name,
+ schema = schema,
+}
+
+function _M.check_schema(conf)
+ return core.schema.check(schema, conf)
+end
+
+
+local function str_int32(int)
+ return char(band(rshift(int, 24), 0xff),
+ band(rshift(int, 16), 0xff),
+ band(rshift(int, 8), 0xff),
+ band(int, 0xff))
+end
+
+
+local function parse_dubbo_header(header)
+ for i = 1, 16 do
+ local currentByte = header:byte(i)
+ if not currentByte then
+ return nil
+ end
+ end
+
+ local magic_number = str_format("%04x", header:byte(1) * 256 + header:byte(2))
+ local message_flag = header:byte(3)
+ local status = header:byte(4)
+ local request_id = 0
+ for i = 5, 12 do
+ request_id = request_id * 256 + header:byte(i)
+ end
+
+ local byte13Val = header:byte(13) * 256 * 256 * 256
+ local byte14Val = header:byte(14) * 256 * 256
+ local data_length = byte13Val + byte14Val + header:byte(15) * 256 + header:byte(16)
+
+ local is_request = bit.band(bit.rshift(message_flag, 7), 0x01) == 1 and 1 or 0
+ local is_two_way = bit.band(bit.rshift(message_flag, 6), 0x01) == 1 and 1 or 0
+ local is_event = bit.band(bit.rshift(message_flag, 5), 0x01) == 1 and 1 or 0
+
+ return {
+ magic_number = magic_number,
+ message_flag = message_flag,
+ is_request = is_request,
+ is_two_way = is_two_way,
+ is_event = is_event,
+ status = status,
+ request_id = request_id,
+ data_length = data_length
+ }
+end
+
+
+local function string_to_json_string(str)
+ local result = "\""
+ for i = 1, #str do
+ local byte = core.string.sub(str, i, i)
+ if byte == "\\" then
+ result = result .. "\\\\"
+ elseif byte == "\n" then
+ result = result .. "\\n"
+ elseif byte == "\t" then
+ result = result .. "\\t"
+ elseif byte == "\r" then
+ result = result .. "\\r"
+ elseif byte == "\b" then
+ result = result .. "\\b"
+ elseif byte == "\f" then
+ result = result .. "\\f"
+ elseif byte == "\"" then
+ result = result .. "\\\""
+ else
+ result = result .. byte
+ end
+ end
+ return result .. "\""
+end
+
+
+local function get_dubbo_request(conf, ctx)
+ -- use dubbo and fastjson
+ local first_byte4 = "\xda\xbb\xc6\x00"
+
+ local requestId = "\x00\x00\x00\x00\x00\x00\x00\x01"
+ local version = "\"2.0.2\"\n"
+ local service = "\"" .. conf.service_name .. "\"" .. "\n"
+
+ local service_version = "\"" .. conf.service_version .. "\"" .. "\n"
+ local method_name = "\"" .. conf.method .. "\"" .. "\n"
+
+ local params_desc = "\"" .. conf.params_type_desc .. "\"" .. "\n"
+ local params = ""
+ local serialized = conf.serialized
+ if conf.serialization_header_key then
+ local serialization_header = core.request.header(ctx, conf.serialization_header_key)
+ serialized = serialization_header == "true"
+ end
+ if serialized then
+ params = core.request.get_body()
+ if params then
+ local end_of_params = core.string.sub(params, -1)
+ if end_of_params ~= "\n" then
+ params = params .. "\n"
+ end
+ end
+ else
+ local body_data = core.request.get_body()
+ if body_data then
+ local lua_object = core.json.decode(body_data);
+ for _, v in pairs(lua_object) do
+ local pt = type(v)
+ if pt == "nil" then
+ params = params .. "null" .. "\n"
+ elseif pt == "string" then
+ params = params .. string_to_json_string(v) .. "\n"
+ elseif pt == "number" then
+ params = params .. tostring(v) .. "\n"
+ else
+ params = params .. core.json.encode(v) .. "\n"
+ end
+ end
+ end
+
+ end
+ local attachments = "{}\n"
+ if params == nil then
+ params = ""
+ end
+ local payload = #version + #service + #service_version
+ + #method_name + #params_desc + #params + #attachments
+ return {
+ first_byte4,
+ requestId,
+ str_int32(payload),
+ version,
+ service,
+ service_version,
+ method_name,
+ params_desc,
+ params,
+ attachments
+ }
+end
+
+
+function _M.before_proxy(conf, ctx)
+ local sock = ngx.socket.tcp()
+
+ sock:settimeouts(conf.connect_timeout, conf.send_timeout, conf.read_timeout)
+ local ok, err = sock:connect(ctx.picked_server.host, ctx.picked_server.port)
+ if not ok then
+ sock:close()
+ core.log.error("failed to connect to upstream ", err)
+ return 502
+ end
+ local request = get_dubbo_request(conf, ctx)
+ local bytes, _ = sock:send(request)
+ if bytes > 0 then
+ local header, _ = sock:receiveany(16);
+ if header then
+ local header_info = parse_dubbo_header(header)
+ if header_info and header_info.status == 20 then
+ local readline = sock:receiveuntil("\n")
+ local body_status, _, _ = readline()
+ if body_status then
+ local response_status = core.string.sub(body_status, 1, 1)
+ if response_status == "2" or response_status == "5" then
+ sock:close()
+ return 200
+ elseif response_status == "1" or response_status == "4" then
+ local body, _, _ = readline()
+ sock:close()
+ return 200, body
+ end
+ end
+ end
+ end
+ end
+ sock:close()
+ return 500
+
+end
+
+return _M
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index 6636bf096a5c..fcee30871755 100755
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -492,6 +492,7 @@ plugins: # plugin list (sorted by priority)
#- dubbo-proxy # priority: 507
- grpc-transcode # priority: 506
- grpc-web # priority: 505
+ - http-dubbo # priority: 504
- public-api # priority: 501
- prometheus # priority: 500
- datadog # priority: 495
diff --git a/t/admin/plugins.t b/t/admin/plugins.t
index c174d5f29b52..911205f48cb4 100644
--- a/t/admin/plugins.t
+++ b/t/admin/plugins.t
@@ -109,6 +109,7 @@ degraphql
kafka-proxy
grpc-transcode
grpc-web
+http-dubbo
public-api
prometheus
datadog
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/pom.xml b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/pom.xml
new file mode 100644
index 000000000000..883ff366aa1e
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ org.apache.dubbo.backend
+ dubbo-serialization-backend
+ 1.0.0-SNAPSHOT
+ ../pom.xml
+
+ org.apache.dubbo.backend
+ dubbo-serialization-backend-interface
+ 1.0.0-SNAPSHOT
+ jar
+ ${project.artifactId}
+
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+
+
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/src/main/java/org/apache/dubbo/backend/DubboSerializationTestService.java b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/src/main/java/org/apache/dubbo/backend/DubboSerializationTestService.java
new file mode 100644
index 000000000000..fcc2a7143a13
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/src/main/java/org/apache/dubbo/backend/DubboSerializationTestService.java
@@ -0,0 +1,30 @@
+/*
+ * 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.backend;
+
+public interface DubboSerializationTestService {
+
+ PoJo testPoJo(PoJo input);
+
+ PoJo[] testPoJos(PoJo[] input);
+
+ void testVoid();
+
+ void testFailure();
+
+ void testTimeout();
+}
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/src/main/java/org/apache/dubbo/backend/PoJo.java b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/src/main/java/org/apache/dubbo/backend/PoJo.java
new file mode 100644
index 000000000000..150d035a1f6e
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-interface/src/main/java/org/apache/dubbo/backend/PoJo.java
@@ -0,0 +1,140 @@
+/*
+ * 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.backend;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class PoJo {
+ private String aString;
+ private Boolean aBoolean;
+ private Byte aByte;
+ private Character acharacter;
+ private Integer aInt;
+ private Float aFloat;
+ private Double aDouble;
+ private Long aLong;
+ private Short aShort;
+ private String[] strings;
+ private Map stringMap;
+
+ public String getaString() {
+ return aString;
+ }
+
+ public void setaString(String aString) {
+ this.aString = aString;
+ }
+
+ public Boolean getaBoolean() {
+ return aBoolean;
+ }
+
+ public void setaBoolean(Boolean aBoolean) {
+ this.aBoolean = aBoolean;
+ }
+
+ public Byte getaByte() {
+ return aByte;
+ }
+
+ public void setaByte(Byte aByte) {
+ this.aByte = aByte;
+ }
+
+ public Character getAcharacter() {
+ return acharacter;
+ }
+
+ public void setAcharacter(Character acharacter) {
+ this.acharacter = acharacter;
+ }
+
+ public Integer getaInt() {
+ return aInt;
+ }
+
+ public void setaInt(Integer aInt) {
+ this.aInt = aInt;
+ }
+
+ public Float getaFloat() {
+ return aFloat;
+ }
+
+ public void setaFloat(Float aFloat) {
+ this.aFloat = aFloat;
+ }
+
+ public Double getaDouble() {
+ return aDouble;
+ }
+
+ public void setaDouble(Double aDouble) {
+ this.aDouble = aDouble;
+ }
+
+ public Long getaLong() {
+ return aLong;
+ }
+
+ public void setaLong(Long aLong) {
+ this.aLong = aLong;
+ }
+
+ public Short getaShort() {
+ return aShort;
+ }
+
+ public void setaShort(Short aShort) {
+ this.aShort = aShort;
+ }
+
+ public Map getStringMap() {
+ return stringMap;
+ }
+
+ public void setStringMap(Map stringMap) {
+ this.stringMap = stringMap;
+ }
+
+ public String[] getStrings() {
+ return strings;
+ }
+
+ public void setStrings(String[] strings) {
+ this.strings = strings;
+ }
+
+ public static PoJo getTestInstance(){
+ PoJo poJo = new PoJo();
+ poJo.aBoolean =true;
+ poJo.aByte =1;
+ poJo.acharacter ='a';
+ poJo.aInt =2;
+ poJo.aDouble = 1.1;
+ poJo.aFloat =1.2f;
+ poJo.aLong = 3L;
+ poJo.aShort = 4;
+ poJo.aString ="aa";
+ HashMap poJoMap = new HashMap<>();
+ poJoMap.put("key","value");
+ poJo.stringMap = poJoMap;
+ poJo.strings = new String[]{"aa","bb"};
+ return poJo;
+ }
+}
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/pom.xml b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/pom.xml
new file mode 100644
index 000000000000..b5b762f92f52
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/pom.xml
@@ -0,0 +1,97 @@
+
+
+ 4.0.0
+
+ org.apache.dubbo.backend
+ dubbo-serialization-backend
+ 1.0.0-SNAPSHOT
+ ../pom.xml
+
+ org.apache.dubbo.backend
+ dubbo-serialization-backend-provider
+ 1.0.0-SNAPSHOT
+ jar
+ ${project.artifactId}
+
+
+ true
+ 1.7.25
+ 2.12.0
+ 2.7.21
+
+
+
+
+ org.apache.dubbo.backend
+ dubbo-serialization-backend-interface
+ 1.0.0-SNAPSHOT
+
+
+ org.apache.dubbo
+ dubbo
+ ${dubbo.version}
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+
+ dubbo-demo-provider
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ org.apache.dubbo.backend.provider.Provider
+
+
+
+
+
+ com.jolira
+ onejar-maven-plugin
+ 1.4.4
+
+
+
+ one-jar
+
+
+
+
+
+
+
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/java/org/apache/dubbo/backend/provider/DubboSerializationTestServiceImpl.java b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/java/org/apache/dubbo/backend/provider/DubboSerializationTestServiceImpl.java
new file mode 100644
index 000000000000..41e927391a36
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/java/org/apache/dubbo/backend/provider/DubboSerializationTestServiceImpl.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.backend.provider;
+
+import org.apache.dubbo.backend.DubboSerializationTestService;
+import org.apache.dubbo.backend.PoJo;
+import org.apache.dubbo.common.utils.ReflectUtils;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+public class DubboSerializationTestServiceImpl implements DubboSerializationTestService {
+
+ @Override
+ public PoJo testPoJo(PoJo input) {
+ return input;
+ }
+
+ @Override
+ public PoJo[] testPoJos(PoJo[] input) {
+ return input;
+ }
+
+ @Override
+ public void testVoid() {
+ }
+
+ @Override
+ public void testFailure() {
+ throw new RuntimeException("testFailure");
+ }
+
+ @Override
+ public void testTimeout() {
+ try {
+ TimeUnit.SECONDS.sleep(10);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/java/org/apache/dubbo/backend/provider/Provider.java b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/java/org/apache/dubbo/backend/provider/Provider.java
new file mode 100644
index 000000000000..dde4580d570a
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/java/org/apache/dubbo/backend/provider/Provider.java
@@ -0,0 +1,48 @@
+/*
+ * 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.backend.provider;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.dubbo.backend.DubboSerializationTestService;
+import org.apache.dubbo.backend.PoJo;
+import org.apache.dubbo.common.utils.ReflectUtils;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+import java.lang.InterruptedException;
+
+public class Provider {
+
+ /**
+ * To get ipv6 address to work, add
+ * System.setProperty("java.net.preferIPv6Addresses", "true");
+ * before running your application.
+ */
+ public static void main(String[] args) throws Exception {
+
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});
+ String jsonString = JSONObject.toJSONString(PoJo.getTestInstance());
+ System.out.println(jsonString);
+ context.start();
+ while (true) {
+ try {
+ TimeUnit.MINUTES.sleep(1);
+ } catch (InterruptedException ex) {}
+ }
+ }
+}
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/META-INF/spring/dubbo-demo-provider.xml b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/META-INF/spring/dubbo-demo-provider.xml
new file mode 100644
index 000000000000..8dae775e4e49
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/META-INF/spring/dubbo-demo-provider.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/dubbo.properties b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/dubbo.properties
new file mode 100644
index 000000000000..258fd3bf2628
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/dubbo.properties
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+dubbo.application.qos.enable=false
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/log4j.properties b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/log4j.properties
new file mode 100644
index 000000000000..2f4f4addf137
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/src/main/resources/log4j.properties
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+###set log levels###
+log4j.rootLogger=info, stdout
+###output to the console###
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/META-INF/spring/dubbo-demo-provider.xml b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/META-INF/spring/dubbo-demo-provider.xml
new file mode 100644
index 000000000000..8dae775e4e49
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/META-INF/spring/dubbo-demo-provider.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/dubbo.properties b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/dubbo.properties
new file mode 100644
index 000000000000..258fd3bf2628
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/dubbo.properties
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+dubbo.application.qos.enable=false
diff --git a/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/log4j.properties b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/log4j.properties
new file mode 100644
index 000000000000..2f4f4addf137
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/dubbo-serialization-backend-provider/target/classes/log4j.properties
@@ -0,0 +1,23 @@
+#
+# 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.
+#
+###set log levels###
+log4j.rootLogger=info, stdout
+###output to the console###
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
diff --git a/t/lib/dubbo-serialization-backend/pom.xml b/t/lib/dubbo-serialization-backend/pom.xml
new file mode 100644
index 000000000000..fe9f04229975
--- /dev/null
+++ b/t/lib/dubbo-serialization-backend/pom.xml
@@ -0,0 +1,97 @@
+
+
+ 4.0.0
+ org.apache.dubbo.backend
+ dubbo-serialization-backend
+ 1.0.0-SNAPSHOT
+ pom
+ ${project.artifactId}
+ A dubbo backend for test based on dubbo-samples-tengine
+
+ true
+ 2.7.21
+
+
+ dubbo-serialization-backend-interface
+ dubbo-serialization-backend-provider
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 2.1.5.RELEASE
+ pom
+ import
+
+
+ org.apache.dubbo
+ dubbo-dependencies-bom
+ ${dubbo.version}
+ pom
+ import
+
+
+ org.apache.dubbo
+ dubbo
+ ${dubbo.version}
+
+
+ org.springframework
+ spring
+
+
+ javax.servlet
+ servlet-api
+
+
+ log4j
+ log4j
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+ 2.1.5.RELEASE
+
+
+ org.apache.dubbo
+ dubbo-spring-boot-starter
+ 2.7.1
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+
+
diff --git a/t/plugin/http-dubbo.t b/t/plugin/http-dubbo.t
new file mode 100644
index 000000000000..8006f07ab824
--- /dev/null
+++ b/t/plugin/http-dubbo.t
@@ -0,0 +1,179 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_shuffle();
+no_root_location();
+add_block_preprocessor(sub {
+ my ($block) = @_;
+ my $yaml_config = $block->yaml_config // <<_EOC_;
+apisix:
+ node_listen: 1984
+ enable_admin: false
+deployment:
+ role: data_plane
+ role_data_plane:
+ config_provider: yaml
+_EOC_
+
+ $block->set_value("yaml_config", $yaml_config);
+});
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: test_pojo
+--- apisix_yaml
+upstreams:
+ - nodes:
+ - host: 127.0.0.1
+ port: 30880
+ weight: 1
+ type: roundrobin
+ id: 1
+routes:
+ -
+ uri: /t
+ plugins:
+ http-dubbo:
+ service_name: org.apache.dubbo.backend.DubboSerializationTestService
+ params_type_desc: Lorg/apache/dubbo/backend/PoJo;
+ serialized: true
+ method: testPoJo
+ service_version: 1.0.0
+ upstream_id: 1
+#END
+--- request
+POST /t
+{"aBoolean":true,"aByte":1,"aDouble":1.1,"aFloat":1.2,"aInt":2,"aLong":3,"aShort":4,"aString":"aa","acharacter":"a","stringMap":{"key":"value"},"strings":["aa","bb"]}
+--- response_body chomp
+{"aBoolean":true,"aByte":1,"aDouble":1.1,"aFloat":1.2,"aInt":2,"aLong":3,"aShort":4,"aString":"aa","acharacter":"a","stringMap":{"key":"value"},"strings":["aa","bb"]}
+
+
+
+=== TEST 2: test_pojos
+--- apisix_yaml
+upstreams:
+ - nodes:
+ - host: 127.0.0.1
+ port: 30880
+ weight: 1
+ type: roundrobin
+ id: 1
+routes:
+ -
+ uri: /t
+ plugins:
+ http-dubbo:
+ service_name: org.apache.dubbo.backend.DubboSerializationTestService
+ params_type_desc: "[Lorg/apache/dubbo/backend/PoJo;"
+ serialized: true
+ method: testPoJos
+ service_version: 1.0.0
+ upstream_id: 1
+#END
+--- request
+POST /t
+[{"aBoolean":true,"aByte":1,"aDouble":1.1,"aFloat":1.2,"aInt":2,"aLong":3,"aShort":4,"aString":"aa","acharacter":"a","stringMap":{"key":"value"},"strings":["aa","bb"]}]
+--- response_body chomp
+[{"aBoolean":true,"aByte":1,"aDouble":1.1,"aFloat":1.2,"aInt":2,"aLong":3,"aShort":4,"aString":"aa","acharacter":"a","stringMap":{"key":"value"},"strings":["aa","bb"]}]
+
+
+
+=== TEST 3: test_timeout
+--- apisix_yaml
+upstreams:
+ - nodes:
+ - host: 127.0.0.1
+ port: 30881
+ weight: 1
+ type: roundrobin
+ id: 1
+routes:
+ -
+ uri: /t
+ plugins:
+ http-dubbo:
+ service_name: org.apache.dubbo.backend.DubboSerializationTestService
+ params_type_desc: "[Lorg/apache/dubbo/backend/PoJo;"
+ serialized: true
+ method: testPoJos
+ service_version: 1.0.0
+ connect_timeout: 100
+ read_timeout: 100
+ send_timeout: 100
+ upstream_id: 1
+#END
+--- request
+GET /t
+--- error_code: 502
+--- error_log
+failed to connect to upstream
+
+
+
+=== TEST 4: test_void
+--- apisix_yaml
+upstreams:
+ - nodes:
+ - host: 127.0.0.1
+ port: 30880
+ weight: 1
+ type: roundrobin
+ id: 1
+routes:
+ -
+ uri: /t
+ plugins:
+ http-dubbo:
+ service_name: org.apache.dubbo.backend.DubboSerializationTestService
+ serialized: true
+ method: testVoid
+ service_version: 1.0.0
+ upstream_id: 1
+#END
+--- request
+GET /t
+
+
+
+=== TEST 5: test_fail
+--- apisix_yaml
+upstreams:
+ - nodes:
+ - host: 127.0.0.1
+ port: 30880
+ weight: 1
+ type: roundrobin
+ id: 1
+routes:
+ -
+ uri: /t
+ plugins:
+ http-dubbo:
+ service_name: org.apache.dubbo.backend.DubboSerializationTestService
+ serialized: true
+ method: testFailure
+ service_version: 1.0.0
+ upstream_id: 1
+#END
+--- request
+GET /t
+--- error_code: 500