This is an automated email from the ASF dual-hosted git repository.
xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 1363524ad add p2cLoadBalancer (#4451)
1363524ad is described below
commit 1363524ad4a53b8f9c9f75a611ce1dae7c0eb8ee
Author: SeaChess <[email protected]>
AuthorDate: Thu Mar 9 18:03:22 2023 +0800
add p2cLoadBalancer (#4451)
Co-authored-by: xiaoyu <[email protected]>
---
db/init/mysql/schema.sql | 1 +
db/init/oracle/schema.sql | 3 +
db/init/pg/create-table.sql | 1 +
.../src/main/resources/sql-script/h2/schema.sql | 1 +
.../shenyu/common/enums/LoadBalanceEnum.java | 7 +-
.../shenyu/loadbalancer/entity/Upstream.java | 95 ++++++++++++++++
.../shenyu/loadbalancer/spi/P2cLoadBalancer.java | 121 +++++++++++++++++++++
...org.apache.shenyu.loadbalancer.spi.LoadBalancer | 1 +
.../loadbalancer/spi/P2cLoadBalancerTest.java | 65 +++++++++++
.../apache/shenyu/plugin/divide/DividePlugin.java | 28 ++++-
.../shenyu/plugin/divide/DividePluginTest.java | 20 +++-
11 files changed, 339 insertions(+), 4 deletions(-)
diff --git a/db/init/mysql/schema.sql b/db/init/mysql/schema.sql
index 1b6e693fe..94678e48e 100644
--- a/db/init/mysql/schema.sql
+++ b/db/init/mysql/schema.sql
@@ -1704,6 +1704,7 @@ INSERT INTO `shenyu_dict` VALUES ('1529402613195784193',
'loadBalance', 'LOAD_BA
INSERT INTO `shenyu_dict` VALUES ('1529402613195784194', 'loadBalance',
'LOAD_BALANCE', 'random', 'random', 'random', 1, 1, '2022-05-25 18:02:52',
'2022-05-25 18:02:52');
INSERT INTO `shenyu_dict` VALUES ('1529402613195784195', 'loadBalance',
'LOAD_BALANCE', 'hash', 'hash', 'hash', 0, 1, '2022-05-25 18:02:52',
'2022-05-25 18:02:52');
INSERT INTO `shenyu_dict` VALUES ('1572621976689762307', 'loadBalance',
'LOAD_BALANCE', 'leastActive', 'leastActive', 'leastActive', 3, 1, '2023-01-17
18:02:52', '2023-01-17 18:02:52');
+INSERT INTO `shenyu_dict` VALUES ('1572621976689762308', 'loadBalance',
'LOAD_BALANCE', 'p2c', 'p2c', 'p2c', 4, 1, '2023-03-07 22:12:12', '2023-03-07
22:12:12');
INSERT INTO `shenyu_dict` VALUES ('1529402613195784196', 'status',
'DIVIDE_STATUS', 'close', 'false', 'close', 1, 1, '2022-05-25 18:02:52',
'2022-05-25 18:02:52');
INSERT INTO `shenyu_dict` VALUES ('1529402613195784197', 'status',
'DIVIDE_STATUS', 'open', 'true', 'open', 0, 1, '2022-05-25 18:02:52',
'2022-05-25 18:02:52');
INSERT INTO `shenyu_dict` VALUES ('1529402613195784198', 'multiRuleHandle',
'MULTI_RULE_HANDLE', 'multiple rule', '1', 'multiple rule', 1, 1, '2022-05-25
18:02:52', '2022-05-25 18:02:52');
diff --git a/db/init/oracle/schema.sql b/db/init/oracle/schema.sql
index 12e724e05..0bec3c5f3 100644
--- a/db/init/oracle/schema.sql
+++ b/db/init/oracle/schema.sql
@@ -1087,6 +1087,9 @@ VALUES ('1545812228228259842', 'engine', 'engine',
'MergeTree', 'MergeTree', '',
INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ INTO SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
VALUES ('1545812228228259843', 'loadBalance', 'LOAD_BALANCE', 'leastActive',
'leastActive', 'leastActive', 3, 1);
+INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(shenyu_dict(type, dict_code, dict_name))
*/ INTO SHENYU_DICT (ID, TYPE, DICT_CODE, DICT_NAME, DICT_VALUE, "desc", SORT,
ENABLED)
+VALUES ('1545812228228259844', 'loadBalance', 'LOAD_BALANCE', 'p2c', 'p2c',
'p2c', 4, 1);
+
/*plugin*/
INSERT /*+ IGNORE_ROW_ON_DUPKEY_INDEX(plugin(id)) */ INTO plugin (id, name,
role, sort, enabled) VALUES ('1','sign','Authentication', 20, '0', null);
diff --git a/db/init/pg/create-table.sql b/db/init/pg/create-table.sql
index f391b1024..6e5f8a170 100644
--- a/db/init/pg/create-table.sql
+++ b/db/init/pg/create-table.sql
@@ -2003,6 +2003,7 @@ INSERT INTO "public"."shenyu_dict" VALUES
('1572621976689762306', 'engine', 'eng
INSERT INTO "public"."shenyu_dict" VALUES ('1572621976689762307',
'loadBalance', 'LOAD_BALANCE', 'leastActive', 'leastActive', 'leastActive', 3,
1, '2023-01-17 18:02:52.924', '2023-01-17 18:02:52.924');
INSERT INTO "public"."shenyu_dict" VALUES ('1630761573833920512', 'mapType',
'mapType', 'all', 'all', '', 1, 1, '2023-03-01 10:47:11', '2023-03-01
10:47:11');
INSERT INTO "public"."shenyu_dict" VALUES ('1630761984393367552', 'mapType',
'mapType', 'field', 'field', '', 1, 1, '2023-03-01 10:48:49', '2023-03-01
10:48:49');
+INSERT INTO "public"."shenyu_dict" VALUES ('1572621976689762308',
'loadBalance', 'LOAD_BALANCE', 'p2c', 'p2c', 'p2c', 4, 1, '2023-03-07
22:15:16.846', '2023-03-07 22:15:16.846');
-- ----------------------------
-- Table structure for user_role
diff --git a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
index 84c024835..3411f9c84 100755
--- a/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
+++ b/shenyu-admin/src/main/resources/sql-script/h2/schema.sql
@@ -500,6 +500,7 @@ INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`,
`dict_name`, `dict_v
INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`,
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1572621976689762307',
'loadBalance', 'LOAD_BALANCE', 'leastActive', 'leastActive', 'leastActive', 0,
1);
INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`,
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1630761573833920512',
'mapType', 'mapType', 'all', 'all', '', 0, 1);
INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`,
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1630761984393367552',
'mapType', 'mapType', 'field', 'field', '', 1, 1);
+INSERT IGNORE INTO `shenyu_dict` (`id`, `type`,`dict_code`, `dict_name`,
`dict_value`, `desc`, `sort`, `enabled`) VALUES ('1572621976689762308',
'loadBalance', 'LOAD_BALANCE', 'p2c', 'p2c', 'p2c', 0, 1);
/*plugin*/
INSERT IGNORE INTO `plugin` (`id`, `name`, `role`, `sort`, `enabled`) VALUES
('1','sign','Authentication', 20, '0');
diff --git
a/shenyu-common/src/main/java/org/apache/shenyu/common/enums/LoadBalanceEnum.java
b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/LoadBalanceEnum.java
index 82ce53059..657882843 100644
---
a/shenyu-common/src/main/java/org/apache/shenyu/common/enums/LoadBalanceEnum.java
+++
b/shenyu-common/src/main/java/org/apache/shenyu/common/enums/LoadBalanceEnum.java
@@ -40,7 +40,12 @@ public enum LoadBalanceEnum {
/**
* least activity load balance enum.
*/
- LEAST_ACTIVITY(4, "leastActive", true);
+ LEAST_ACTIVITY(4, "leastActive", true),
+
+ /**
+ * pick of 2 choices load balance enum.
+ */
+ P2C(5, "p2c", true);
private final int code;
diff --git
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
index 6a5827e3d..090bca801 100644
---
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
+++
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
@@ -20,6 +20,7 @@ package org.apache.shenyu.loadbalancer.entity;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicLong;
/**
* this is upstream.
@@ -81,6 +82,26 @@ public final class Upstream {
*/
private String version;
+ /**
+ * ewma value.
+ */
+ private long lag;
+
+ /**
+ * response stamp.
+ */
+ private long responseStamp;
+
+ /**
+ * Last selected timestamp.
+ */
+ private long lastPicked;
+
+ /**
+ * Total number of requests being processed.
+ */
+ private AtomicLong inflight = new AtomicLong(1);
+
private Upstream(final Builder builder) {
this.protocol = builder.protocol;
this.url = builder.url;
@@ -254,6 +275,80 @@ public final class Upstream {
this.version = version;
}
+ /**
+ * Gets lag.
+ *
+ * @return the lag
+ */
+ public long getLag() {
+ return lag;
+ }
+
+ /**
+ * Sets lag.
+ * @param lag the lag
+ */
+ public void setLag(final long lag) {
+ this.lag = lag;
+ }
+
+ /**
+ * Gets inflight.
+ *
+ * @return the inflight
+ */
+
+ /**
+ * Gets responseStamp.
+ *
+ * @return the responseStamp
+ */
+ public long getResponseStamp() {
+ return responseStamp;
+ }
+
+ /**
+ * Sets responseStamp.
+ * @param responseStamp the responseStamp
+ */
+ public void setResponseStamp(final long responseStamp) {
+ this.responseStamp = responseStamp;
+ }
+
+ /**
+ * Gets lastPickedStamp.
+ *
+ * @return the lastPickedStamp
+ */
+ public long getLastPicked() {
+ return lastPicked;
+ }
+
+ /**
+ * Sets lastPickedStamp.
+ * @param lastPicked the lastPickedStamp
+ */
+ public void setLastPicked(final long lastPicked) {
+ this.lastPicked = lastPicked;
+ }
+
+ /**
+ * Gets inflight.
+ *
+ * @return the inflight
+ */
+ public AtomicLong getInflight() {
+ return inflight;
+ }
+
+ /**
+ * Sets inflight.
+ * @param inflight the inflight
+ */
+ public void setInflight(final AtomicLong inflight) {
+ this.inflight = inflight;
+ }
+
/**
* build request domain.
*
diff --git
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancer.java
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancer.java
new file mode 100644
index 000000000..c3dfc1f07
--- /dev/null
+++
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancer.java
@@ -0,0 +1,121 @@
+/*
+ * 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.shenyu.loadbalancer.spi;
+
+import org.apache.shenyu.loadbalancer.entity.Upstream;
+import org.apache.shenyu.spi.Join;
+
+import java.util.List;
+import java.util.Random;
+
+/**
+ * p2c algorithm impl.
+ */
+@Join
+public class P2cLoadBalancer extends AbstractLoadBalancer {
+
+ /**
+ * maximum tolerance of idle time.
+ */
+ private static final int FORCE_GAP = 3 * 1000;
+
+ /**
+ * penalty value.
+ */
+ private static final int PENALTY = 250 * 1000;
+
+ /**
+ * pick times.
+ */
+ private static final int PICK_TIMES = 3;
+
+ private Random random = new Random();
+
+ /**
+ * pick of 2 choices to select upstream.
+ *
+ * @param upstreamList the upstream list
+ * @param ip the ip
+ * @return selected upstream
+ */
+ @Override
+ protected Upstream doSelect(final List<Upstream> upstreamList, final
String ip) {
+ long start = System.currentTimeMillis();
+ Upstream[] upstreams = pickTwoUpstreams(upstreamList);
+ Upstream picked;
+ Upstream unpicked;
+ if (load(upstreams[0]) > load(upstreams[1])) {
+ picked = upstreams[1];
+ unpicked = upstreams[0];
+ } else {
+ picked = upstreams[0];
+ unpicked = upstreams[1];
+ }
+ // If the failed node is not selected once in the forceGap period, it
is forced to be selected once.
+ long pick = unpicked.getLastPicked();
+ if ((start - pick) > FORCE_GAP) {
+ unpicked.setLastPicked(start);
+ picked = unpicked;
+ }
+
+ if (picked != unpicked) {
+ picked.setLastPicked(start);
+ }
+ picked.getInflight().incrementAndGet();
+ return picked;
+ }
+
+ /**
+ * select two nodes randomly.
+ *
+ * @param upstreamList the upstream list
+ * @return two upstream
+ */
+ private Upstream[] pickTwoUpstreams(final List<Upstream> upstreamList) {
+ Upstream[] upstreams = new Upstream[2];
+ for (int i = 0; i < PICK_TIMES; i++) {
+ int a = random.nextInt(upstreamList.size());
+ int b = random.nextInt(upstreamList.size() - 1);
+ // prevent random nodes from being the same.
+ if (b >= a) {
+ b += 1;
+ }
+ upstreams[0] = upstreamList.get(a);
+ upstreams[1] = upstreamList.get(b);
+ if (upstreams[0].isHealthy() && upstreams[1].isHealthy()) {
+ break;
+ }
+ }
+ return upstreams;
+ }
+
+ /**
+ * calculate load.
+ *
+ * @param upstream the upstream
+ * @return load
+ */
+ public long load(final Upstream upstream) {
+ long lag = (long) (Math.sqrt((double) upstream.getLag()) + 1);
+ long load = lag * upstream.getInflight().get();
+ if (load == 0) {
+ load = PENALTY;
+ }
+ return load;
+ }
+}
diff --git
a/shenyu-loadbalancer/src/main/resources/META-INF/shenyu/org.apache.shenyu.loadbalancer.spi.LoadBalancer
b/shenyu-loadbalancer/src/main/resources/META-INF/shenyu/org.apache.shenyu.loadbalancer.spi.LoadBalancer
index e74332f0c..12e623900 100644
---
a/shenyu-loadbalancer/src/main/resources/META-INF/shenyu/org.apache.shenyu.loadbalancer.spi.LoadBalancer
+++
b/shenyu-loadbalancer/src/main/resources/META-INF/shenyu/org.apache.shenyu.loadbalancer.spi.LoadBalancer
@@ -17,3 +17,4 @@ random=org.apache.shenyu.loadbalancer.spi.RandomLoadBalancer
roundRobin=org.apache.shenyu.loadbalancer.spi.RoundRobinLoadBalancer
hash=org.apache.shenyu.loadbalancer.spi.HashLoadBalancer
leastActive=org.apache.shenyu.loadbalancer.spi.LeastActiveLoadBalance
+p2c=org.apache.shenyu.loadbalancer.spi.P2cLoadBalancer
\ No newline at end of file
diff --git
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancerTest.java
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancerTest.java
new file mode 100644
index 000000000..fcd98f59c
--- /dev/null
+++
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/spi/P2cLoadBalancerTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.shenyu.loadbalancer.spi;
+
+import org.apache.shenyu.loadbalancer.entity.Upstream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class P2cLoadBalancerTest {
+ private final List<Upstream> upstreamList = new ArrayList<>();
+
+ /**
+ * build upstream list.
+ */
+ public void buildUpstreamList() {
+ Upstream upstream1 = Upstream.builder()
+ .url("baidu.com")
+ .protocol("https://")
+ .build();
+ Upstream upstream2 = Upstream.builder()
+ .url("pro.jd.com")
+ .protocol("https://")
+ .build();
+ upstreamList.add(upstream1);
+ upstreamList.add(upstream2);
+ }
+
+ @Test
+ public void testResponseTimeBalancerSameLag() {
+ buildUpstreamList();
+ final P2cLoadBalancer p2cLoadBalancer = new P2cLoadBalancer();
+ Upstream upstream = p2cLoadBalancer.doSelect(upstreamList,
"localhost");
+ Upstream upstream1 = p2cLoadBalancer.doSelect(upstreamList,
"localhost");
+ Assertions.assertTrue((upstream.getUrl().equals("baidu.com") &&
upstream1.getUrl().equals("pro.jd.com"))
+ || upstream1.getUrl().equals("baidu.com") &&
upstream.getUrl().equals("pro.jd.com"));
+ }
+
+ @Test
+ public void testResponseTimeBalancerSameInflight() {
+ buildUpstreamList();
+ final P2cLoadBalancer p2cLoadBalancer = new P2cLoadBalancer();
+ upstreamList.get(0).setLag(1);
+ Upstream upstream = p2cLoadBalancer.doSelect(upstreamList,
"localhost");
+ Upstream upstream1 = p2cLoadBalancer.doSelect(upstreamList,
"localhost");
+ Assertions.assertTrue(upstream.getUrl().equals("baidu.com") &&
upstream1.getUrl().equals("pro.jd.com"));
+ }
+}
diff --git
a/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
b/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
index 1cf21eada..091bc8407 100644
---
a/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
+++
b/shenyu-plugin/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java
@@ -54,6 +54,8 @@ import java.util.Objects;
public class DividePlugin extends AbstractShenyuPlugin {
private static final Logger LOG =
LoggerFactory.getLogger(DividePlugin.class);
+
+ private static final String P2C = "p2c";
private final DivideRuleHandle defaultRuleHandle = new DivideRuleHandle();
@@ -108,7 +110,8 @@ public class DividePlugin extends AbstractShenyuPlugin {
exchange.getAttributes().put(Constants.RETRY_STRATEGY,
StringUtils.defaultString(ruleHandle.getRetryStrategy(),
RetryEnum.CURRENT.getName()));
exchange.getAttributes().put(Constants.LOAD_BALANCE,
StringUtils.defaultString(ruleHandle.getLoadBalance(),
LoadBalanceEnum.RANDOM.getName()));
exchange.getAttributes().put(Constants.DIVIDE_SELECTOR_ID,
selector.getId());
- return chain.execute(exchange);
+ return ruleHandle.getLoadBalance().equals(P2C) ?
chain.execute(exchange).doOnSuccess(e -> responseTrigger(upstream
+ )).doOnError(throwable -> responseTrigger(upstream)) :
chain.execute(exchange);
}
@Override
@@ -143,4 +146,27 @@ public class DividePlugin extends AbstractShenyuPlugin {
return defaultRuleHandle;
}
}
+
+ private void responseTrigger(final Upstream upstream) {
+ long now = System.currentTimeMillis();
+ upstream.getInflight().decrementAndGet();
+ upstream.setResponseStamp(now);
+ long stamp = upstream.getResponseStamp();
+ long td = now - stamp;
+ if (td < 0) {
+ td = 0;
+ }
+ double w = Math.exp((double) -td / (double) 600);
+
+ long lag = now - upstream.getLastPicked();
+ if (lag < 0) {
+ lag = 0;
+ }
+ long oldLag = upstream.getLag();
+ if (oldLag == 0) {
+ w = 0;
+ }
+ lag = (int) ((double) oldLag * w + (double) lag * (1.0 - w));
+ upstream.setLag(lag);
+ }
}
diff --git
a/shenyu-plugin/shenyu-plugin-divide/src/test/java/org/apache/shenyu/plugin/divide/DividePluginTest.java
b/shenyu-plugin/shenyu-plugin-divide/src/test/java/org/apache/shenyu/plugin/divide/DividePluginTest.java
index b4a43af35..92e5a7614 100644
---
a/shenyu-plugin/shenyu-plugin-divide/src/test/java/org/apache/shenyu/plugin/divide/DividePluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-divide/src/test/java/org/apache/shenyu/plugin/divide/DividePluginTest.java
@@ -27,6 +27,7 @@ import org.apache.shenyu.common.enums.RpcTypeEnum;
import org.apache.shenyu.common.utils.GsonUtils;
import org.apache.shenyu.common.utils.UpstreamCheckUtils;
import org.apache.shenyu.loadbalancer.cache.UpstreamCacheManager;
+import org.apache.shenyu.loadbalancer.entity.Upstream;
import org.apache.shenyu.loadbalancer.factory.LoadBalancerFactory;
import org.apache.shenyu.plugin.api.ShenyuPluginChain;
import org.apache.shenyu.plugin.api.context.ShenyuContext;
@@ -50,17 +51,20 @@ import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
@@ -206,6 +210,18 @@ public final class DividePluginTest {
assertEquals(PluginEnum.DIVIDE.getCode(), dividePlugin.getOrder());
}
+ @Test
+ public void responseTriggerTest() throws NoSuchMethodException,
InstantiationException, IllegalAccessException, InvocationTargetException {
+ Upstream upstream = Upstream.builder()
+ .url("upstream")
+ .build();
+ assertEquals(0, upstream.getLag());
+ Method method =
DividePlugin.class.getDeclaredMethod("responseTrigger", Upstream.class);
+ method.setAccessible(true);
+ method.invoke(DividePlugin.class.newInstance(), upstream);
+ assertNotEquals(0, upstream.getLag());
+ }
+
/**
* Init mock info.
*/