From 850f719927962ad983e93bbbee391471b1bd2cf7 Mon Sep 17 00:00:00 2001 From: Koy Zhuang <369491420@qq.com> Date: Wed, 30 Nov 2022 14:54:03 +0800 Subject: [PATCH 01/10] update(qos): support foreign ip whitelist. (#11051) --- .../dubbo/common/constants/QosConstants.java | 4 + .../dubbo/config/ApplicationConfig.java | 25 ++++ .../org/apache/dubbo/config/Constants.java | 3 +- .../qos/protocol/QosProtocolWrapper.java | 4 + .../apache/dubbo/qos/pu/QosWireProtocol.java | 3 +- .../org/apache/dubbo/qos/server/Server.java | 7 +- .../handler/ForeignHostPermitHandler.java | 94 +++++++++++++++ .../handler/LocalHostPermitHandler.java | 48 -------- .../qos/server/handler/QosProcessHandler.java | 6 +- .../handler/ForeignHostPermitHandlerTest.java | 110 ++++++++++++++++++ .../handler/LocalHostPermitHandlerTest.java | 56 --------- .../server/handler/QosProcessHandlerTest.java | 7 +- 12 files changed, 255 insertions(+), 112 deletions(-) create mode 100644 dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java delete mode 100644 dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandler.java create mode 100644 dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java delete mode 100644 dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandlerTest.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java index 3132642a57..3939296ffa 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/QosConstants.java @@ -30,6 +30,8 @@ public interface QosConstants { String ACCEPT_FOREIGN_IP = "qos.accept.foreign.ip"; + String ACCEPT_FOREIGN_IP_WHITELIST = "qos.accept.foreign.ip.whitelist"; + String QOS_ENABLE_COMPATIBLE = "qos-enable"; String QOS_HOST_COMPATIBLE = "qos-host"; @@ -37,4 +39,6 @@ public interface QosConstants { String QOS_PORT_COMPATIBLE = "qos-port"; String ACCEPT_FOREIGN_IP_COMPATIBLE = "qos-accept-foreign-ip"; + + String ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE = "qos-accept-foreign-ip-whitelist"; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java index c9597d2e7e..33852d430a 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ApplicationConfig.java @@ -50,6 +50,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.STARTUP_PROBE; import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION; import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP; import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_COMPATIBLE; +import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST; +import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST; @@ -149,6 +151,11 @@ public class ApplicationConfig extends AbstractConfig { */ private Boolean qosAcceptForeignIp; + /** + * When we disable accept foreign ip, support specify foreign ip in the whitelist + */ + private String qosAcceptForeignIpWhitelist; + /** * Customized parameters */ @@ -400,6 +407,15 @@ public class ApplicationConfig extends AbstractConfig { this.qosAcceptForeignIp = qosAcceptForeignIp; } + @Parameter(key = ACCEPT_FOREIGN_IP_WHITELIST) + public String getQosAcceptForeignIpWhitelist() { + return qosAcceptForeignIpWhitelist; + } + + public void setQosAcceptForeignIpWhitelist(String qosAcceptForeignIpWhitelist) { + this.qosAcceptForeignIpWhitelist = qosAcceptForeignIpWhitelist; + } + /** * The format is the same as the springboot, including: getQosEnableCompatible(), getQosPortCompatible(), getQosAcceptForeignIpCompatible(). * @@ -441,6 +457,15 @@ public class ApplicationConfig extends AbstractConfig { this.setQosAcceptForeignIp(qosAcceptForeignIp); } + @Parameter(key = ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE, excluded = true, attribute = false) + public String getQosAcceptForeignIpWhitelistCompatible() { + return this.getQosAcceptForeignIpWhitelist(); + } + + public void setQosAcceptForeignIpWhitelistCompatible(String qosAcceptForeignIpWhitelist) { + this.setQosAcceptForeignIpWhitelist(qosAcceptForeignIpWhitelist); + } + public Map getParameters() { return parameters; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java b/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java index 668acc408b..db1a87c8dc 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java @@ -18,6 +18,7 @@ package org.apache.dubbo.config; import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_COMPATIBLE; +import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST_COMPATIBLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT_COMPATIBLE; @@ -140,7 +141,7 @@ public interface Constants { String MULTI_SERIALIZATION_KEY = "serialize.multiple"; String[] DOT_COMPATIBLE_KEYS = new String[]{QOS_ENABLE_COMPATIBLE, QOS_HOST_COMPATIBLE, QOS_PORT_COMPATIBLE, - ACCEPT_FOREIGN_IP_COMPATIBLE, REGISTRY_TYPE_KEY}; + ACCEPT_FOREIGN_IP_COMPATIBLE, ACCEPT_FOREIGN_IP_WHITELIST_COMPATIBLE, REGISTRY_TYPE_KEY}; String IGNORE_CHECK_KEYS = "ignoreCheckKeys"; diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java index 18139f0fad..32b32c4cbf 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/protocol/QosProtocolWrapper.java @@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.qos.common.QosConstants; import org.apache.dubbo.qos.pu.QosWireProtocol; import org.apache.dubbo.qos.server.Server; @@ -37,6 +38,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_FAILED_START_SERVER; import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP; +import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP_WHITELIST; import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE; import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST; import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT; @@ -113,6 +115,7 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware { String host = url.getParameter(QOS_HOST); int port = url.getParameter(QOS_PORT, QosConstants.DEFAULT_PORT); boolean acceptForeignIp = Boolean.parseBoolean(url.getParameter(ACCEPT_FOREIGN_IP, "false")); + String acceptForeignIpWhitelist = url.getParameter(ACCEPT_FOREIGN_IP_WHITELIST, StringUtils.EMPTY_STRING); Server server = frameworkModel.getBeanFactory().getBean(Server.class); if (server.isStarted()) { @@ -122,6 +125,7 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware { server.setHost(host); server.setPort(port); server.setAcceptForeignIp(acceptForeignIp); + server.setAcceptForeignIpWhitelist(acceptForeignIpWhitelist); server.start(); } catch (Throwable throwable) { diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java index 71e6633eb3..9f9a998d19 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosWireProtocol.java @@ -18,6 +18,7 @@ package org.apache.dubbo.qos.pu; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.qos.server.DubboLogo; import org.apache.dubbo.qos.server.handler.QosProcessHandler; import org.apache.dubbo.remoting.ChannelHandler; @@ -48,7 +49,7 @@ public class QosWireProtocol extends AbstractWireProtocol implements ScopeModelA public void configServerProtocolHandler(URL url, ChannelOperator operator) { // add qosProcess handler QosProcessHandler handler = new QosProcessHandler(url.getOrDefaultFrameworkModel(), - DubboLogo.DUBBO, false); + DubboLogo.DUBBO, false, StringUtils.EMPTY_STRING); List handlers = new ArrayList<>(); handlers.add(new ChannelHandlerPretender(handler)); operator.configChannelHandler(handlers); diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java index fa40444e61..2d60b24457 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/Server.java @@ -52,6 +52,7 @@ public class Server { private int port; private boolean acceptForeignIp = true; + private String acceptForeignIpWhitelist = StringUtils.EMPTY_STRING; private EventLoopGroup boss; @@ -97,7 +98,7 @@ public class Server { @Override protected void initChannel(Channel ch) throws Exception { - ch.pipeline().addLast(new QosProcessHandler(frameworkModel, welcome, acceptForeignIp)); + ch.pipeline().addLast(new QosProcessHandler(frameworkModel, welcome, acceptForeignIp, acceptForeignIpWhitelist)); } }); try { @@ -147,6 +148,10 @@ public class Server { this.acceptForeignIp = acceptForeignIp; } + public void setAcceptForeignIpWhitelist(String acceptForeignIpWhitelist) { + this.acceptForeignIpWhitelist = acceptForeignIpWhitelist; + } + public String getWelcome() { return welcome; } diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java new file mode 100644 index 0000000000..c63072a9de --- /dev/null +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandler.java @@ -0,0 +1,94 @@ +/* + * 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.qos.server.handler; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerAdapter; +import io.netty.channel.ChannelHandlerContext; +import org.apache.dubbo.common.utils.NetUtils; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.qos.common.QosConstants; + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.function.Predicate; + +public class ForeignHostPermitHandler extends ChannelHandlerAdapter { + + // true means to accept foreign IP + private boolean acceptForeignIp; + + // the whitelist of foreign IP when acceptForeignIp = false, the delimiter is colon(,) + // support specific ip and an ip range from CIDR specification + private String acceptForeignIpWhitelist; + private Predicate whitelistPredicate = foreignIp -> false; + + public ForeignHostPermitHandler(boolean acceptForeignIp, String foreignIpWhitelist) { + this.acceptForeignIp = acceptForeignIp; + this.acceptForeignIpWhitelist = foreignIpWhitelist; + if (StringUtils.isNotEmpty(foreignIpWhitelist)) { + whitelistPredicate = Arrays.stream(foreignIpWhitelist.split(",")) + .map(String::trim) + .filter(StringUtils::isNotEmpty) + .map(foreignIpPattern -> (Predicate) foreignIp -> { + try { + // hard code port to -1 + return NetUtils.matchIpExpression(foreignIpPattern, foreignIp, -1); + } catch (UnknownHostException ignore) { + // ignore illegal CIDR specification + } + return false; + }) + .reduce(Predicate::or).orElse(s -> false); + } + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + if (acceptForeignIp) { + return; + } + + final InetAddress inetAddress = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress(); + // loopback address, return + if (inetAddress.isLoopbackAddress()) { + return; + } + + // the ip is in the whitelist, return + if (checkForeignIpInWhiteList(inetAddress)) { + return; + } + + ByteBuf cb = Unpooled.wrappedBuffer((QosConstants.BR_STR + "Foreign Ip Not Permitted, Consider Config It In Whitelist." + + QosConstants.BR_STR).getBytes()); + ctx.writeAndFlush(cb).addListener(ChannelFutureListener.CLOSE); + } + + private boolean checkForeignIpInWhiteList(InetAddress inetAddress) { + if (StringUtils.isEmpty(acceptForeignIpWhitelist)) { + return false; + } + + final String foreignIp = inetAddress.getHostAddress(); + return whitelistPredicate.test(foreignIp); + } +} diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandler.java deleted file mode 100644 index d93284ae7f..0000000000 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandler.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.qos.server.handler; - -import org.apache.dubbo.qos.common.QosConstants; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerAdapter; -import io.netty.channel.ChannelHandlerContext; - -import java.net.InetSocketAddress; - -public class LocalHostPermitHandler extends ChannelHandlerAdapter { - - // true means to accept foreign IP - private boolean acceptForeignIp; - - public LocalHostPermitHandler(boolean acceptForeignIp) { - this.acceptForeignIp = acceptForeignIp; - } - - @Override - public void handlerAdded(ChannelHandlerContext ctx) throws Exception { - if (!acceptForeignIp) { - if (!((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().isLoopbackAddress()) { - ByteBuf cb = Unpooled.wrappedBuffer((QosConstants.BR_STR + "Foreign Ip Not Permitted." - + QosConstants.BR_STR).getBytes()); - ctx.writeAndFlush(cb).addListener(ChannelFutureListener.CLOSE); - } - } - } -} diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java index 4e5ef439f8..32d89f7278 100644 --- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java +++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/server/handler/QosProcessHandler.java @@ -44,15 +44,17 @@ public class QosProcessHandler extends ByteToMessageDecoder { private String welcome; // true means to accept foreign IP private boolean acceptForeignIp; + private String acceptForeignIpWhitelist; private FrameworkModel frameworkModel; public static final String PROMPT = "dubbo>"; - public QosProcessHandler(FrameworkModel frameworkModel, String welcome, boolean acceptForeignIp) { + public QosProcessHandler(FrameworkModel frameworkModel, String welcome, boolean acceptForeignIp, String acceptForeignIpWhitelist) { this.frameworkModel = frameworkModel; this.welcome = welcome; this.acceptForeignIp = acceptForeignIp; + this.acceptForeignIpWhitelist = acceptForeignIpWhitelist; } @Override @@ -75,7 +77,7 @@ public class QosProcessHandler extends ByteToMessageDecoder { final int magic = in.getByte(in.readerIndex()); ChannelPipeline p = ctx.pipeline(); - p.addLast(new LocalHostPermitHandler(acceptForeignIp)); + p.addLast(new ForeignHostPermitHandler(acceptForeignIp, acceptForeignIpWhitelist)); if (isHttp(magic)) { // no welcome output for http protocol if (welcomeFuture != null && welcomeFuture.isCancellable()) { diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java new file mode 100644 index 0000000000..0cebdbdc67 --- /dev/null +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/ForeignHostPermitHandlerTest.java @@ -0,0 +1,110 @@ +/* + * 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.qos.server.handler; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import org.apache.dubbo.common.utils.StringUtils; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import java.net.InetAddress; +import java.net.InetSocketAddress; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class ForeignHostPermitHandlerTest { + @Test + void shouldShowIpNotPermittedMsg_GivenAcceptForeignIpFalseAndEmptyWhiteList() throws Exception { + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(context.channel()).thenReturn(channel); + InetAddress addr = mock(InetAddress.class); + when(addr.isLoopbackAddress()).thenReturn(false); + InetSocketAddress address = new InetSocketAddress(addr, 12345); + when(channel.remoteAddress()).thenReturn(address); + ChannelFuture future = mock(ChannelFuture.class); + when(context.writeAndFlush(any(ByteBuf.class))).thenReturn(future); + ForeignHostPermitHandler handler = new ForeignHostPermitHandler(false, StringUtils.EMPTY_STRING); + handler.handlerAdded(context); + ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); + verify(context).writeAndFlush(captor.capture()); + assertThat(new String(captor.getValue().array()), containsString("Foreign Ip Not Permitted, Consider Config It In Whitelist")); + verify(future).addListener(ChannelFutureListener.CLOSE); + } + + @Test + void shouldShowIpNotPermittedMsg_GivenAcceptForeignIpFalseAndNotMatchWhiteList() throws Exception { + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(context.channel()).thenReturn(channel); + InetAddress addr = mock(InetAddress.class); + when(addr.isLoopbackAddress()).thenReturn(false); + when(addr.getHostAddress()).thenReturn("179.23.44.1"); + InetSocketAddress address = new InetSocketAddress(addr, 12345); + when(channel.remoteAddress()).thenReturn(address); + ChannelFuture future = mock(ChannelFuture.class); + when(context.writeAndFlush(any(ByteBuf.class))).thenReturn(future); + ForeignHostPermitHandler handler = new ForeignHostPermitHandler(false, "175.23.44.1 , 192.168.1.192/26"); + handler.handlerAdded(context); + ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); + verify(context).writeAndFlush(captor.capture()); + assertThat(new String(captor.getValue().array()), containsString("Foreign Ip Not Permitted, Consider Config It In Whitelist")); + verify(future).addListener(ChannelFutureListener.CLOSE); + } + + @Test + void shouldNotShowIpNotPermittedMsg_GivenAcceptForeignIpFalseAndMatchWhiteList() throws Exception { + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(context.channel()).thenReturn(channel); + InetAddress addr = mock(InetAddress.class); + when(addr.isLoopbackAddress()).thenReturn(false); + when(addr.getHostAddress()).thenReturn("175.23.44.1"); + InetSocketAddress address = new InetSocketAddress(addr, 12345); + when(channel.remoteAddress()).thenReturn(address); + + ForeignHostPermitHandler handler = new ForeignHostPermitHandler(false, "175.23.44.1, 192.168.1.192/26 "); + handler.handlerAdded(context); + verify(context, never()).writeAndFlush(any()); + } + + @Test + void shouldNotShowIpNotPermittedMsg_GivenAcceptForeignIpFalseAndMatchWhiteListRange() throws Exception { + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + Channel channel = mock(Channel.class); + when(context.channel()).thenReturn(channel); + InetAddress addr = mock(InetAddress.class); + when(addr.isLoopbackAddress()).thenReturn(false); + when(addr.getHostAddress()).thenReturn("192.168.1.199"); + InetSocketAddress address = new InetSocketAddress(addr, 12345); + when(channel.remoteAddress()).thenReturn(address); + + ForeignHostPermitHandler handler = new ForeignHostPermitHandler(false, "175.23.44.1, 192.168.1.192/26"); + handler.handlerAdded(context); + verify(context, never()).writeAndFlush(any()); + } +} diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandlerTest.java deleted file mode 100644 index 9d11d080e8..0000000000 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/LocalHostPermitHandlerTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.qos.server.handler; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelHandlerContext; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import java.net.InetAddress; -import java.net.InetSocketAddress; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -class LocalHostPermitHandlerTest { - @Test - void testHandlerAdded() throws Exception { - ChannelHandlerContext context = mock(ChannelHandlerContext.class); - Channel channel = mock(Channel.class); - when(context.channel()).thenReturn(channel); - InetAddress addr = mock(InetAddress.class); - when(addr.isLoopbackAddress()).thenReturn(false); - InetSocketAddress address = new InetSocketAddress(addr, 12345); - when(channel.remoteAddress()).thenReturn(address); - ChannelFuture future = mock(ChannelFuture.class); - when(context.writeAndFlush(any(ByteBuf.class))).thenReturn(future); - LocalHostPermitHandler handler = new LocalHostPermitHandler(false); - handler.handlerAdded(context); - ArgumentCaptor captor = ArgumentCaptor.forClass(ByteBuf.class); - verify(context).writeAndFlush(captor.capture()); - assertThat(new String(captor.getValue().array()), containsString("Foreign Ip Not Permitted")); - verify(future).addListener(ChannelFutureListener.CLOSE); - } -} \ No newline at end of file diff --git a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java index 0ba4909a01..3649bcdeca 100644 --- a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java +++ b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/server/handler/QosProcessHandlerTest.java @@ -16,6 +16,7 @@ */ package org.apache.dubbo.qos.server.handler; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.model.FrameworkModel; import io.netty.buffer.ByteBuf; @@ -42,7 +43,7 @@ class QosProcessHandlerTest { ChannelHandlerContext context = Mockito.mock(ChannelHandlerContext.class); ChannelPipeline pipeline = Mockito.mock(ChannelPipeline.class); Mockito.when(context.pipeline()).thenReturn(pipeline); - QosProcessHandler handler = new QosProcessHandler(FrameworkModel.defaultModel(), "welcome", false); + QosProcessHandler handler = new QosProcessHandler(FrameworkModel.defaultModel(), "welcome", false, StringUtils.EMPTY_STRING); handler.decode(context, buf, Collections.emptyList()); verify(pipeline).addLast(any(HttpServerCodec.class)); verify(pipeline).addLast(any(HttpObjectAggregator.class)); @@ -56,7 +57,7 @@ class QosProcessHandlerTest { ChannelHandlerContext context = Mockito.mock(ChannelHandlerContext.class); ChannelPipeline pipeline = Mockito.mock(ChannelPipeline.class); Mockito.when(context.pipeline()).thenReturn(pipeline); - QosProcessHandler handler = new QosProcessHandler(FrameworkModel.defaultModel(), "welcome", false); + QosProcessHandler handler = new QosProcessHandler(FrameworkModel.defaultModel(), "welcome", false, StringUtils.EMPTY_STRING); handler.decode(context, buf, Collections.emptyList()); verify(pipeline).addLast(any(LineBasedFrameDecoder.class)); verify(pipeline).addLast(any(StringDecoder.class)); @@ -66,4 +67,4 @@ class QosProcessHandlerTest { } -} \ No newline at end of file +} From 3c68e9476e1c418f50608897472e1b313eb6bc94 Mon Sep 17 00:00:00 2001 From: gold-fisher <603391652@qq.com> Date: Thu, 1 Dec 2022 18:07:42 +0800 Subject: [PATCH 02/10] =?UTF-8?q?Fixes=20#11044,solve=20remoteApplicationN?= =?UTF-8?q?ame=20is=20null,=20in=20mesh=20mode=20with=20t=E2=80=A6=20(#110?= =?UTF-8?q?58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes #11044,solve remoteApplicationName is null, in mesh mode with triple protocol. --- .../dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java index 98748e25f1..61de32a9ba 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/AbstractServerCallListener.java @@ -31,6 +31,7 @@ import org.apache.dubbo.rpc.protocol.tri.observer.ServerCallToObserverAdapter; import java.net.InetSocketAddress; import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_TIMEOUT_SERVER; +import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_APPLICATION_KEY; public abstract class AbstractServerCallListener implements AbstractServerCall.Listener { @@ -57,6 +58,7 @@ public abstract class AbstractServerCallListener implements AbstractServerCall.L .remove(TripleHeaderEnum.CONSUMER_APP_NAME_KEY); if (null != remoteApp) { RpcContext.getServerContext().setRemoteApplicationName(remoteApp); + invocation.setAttachmentIfAbsent(REMOTE_APPLICATION_KEY, remoteApp); } final long stInMillis = System.currentTimeMillis(); try { From 2f55e72ac9fefe14642b8c0bccdd9d826ef2006a Mon Sep 17 00:00:00 2001 From: Andy Cheung Date: Mon, 5 Dec 2022 11:07:21 +0800 Subject: [PATCH 03/10] Add error code support of ListenerInvokerWrapper. (#11065) --- .../kubernetes/KubernetesMeshEnvListener.java | 16 ++++++++-------- .../rpc/listener/ListenerInvokerWrapper.java | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java index 94a58b0d37..966ad64dc6 100644 --- a/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java +++ b/dubbo-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java @@ -36,9 +36,9 @@ import static org.apache.dubbo.common.constants.LoggerCodeConstants.REGISTRY_ERR public class KubernetesMeshEnvListener implements MeshEnvListener { public static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(KubernetesMeshEnvListener.class); - private volatile static boolean usingApiServer = false; - private volatile static KubernetesClient kubernetesClient; - private volatile static String namespace; + private static volatile boolean usingApiServer = false; + private static volatile KubernetesClient kubernetesClient; + private static volatile String namespace; private final Map appRuleListenerMap = new ConcurrentHashMap<>(); @@ -103,11 +103,11 @@ public class KubernetesMeshEnvListener implements MeshEnvListener { } } - @Override - public void onClose(WatcherException cause) { - // ignore - } - }); + @Override + public void onClose(WatcherException cause) { + // ignore + } + }); vsAppWatch.put(appName, watch); try { GenericKubernetesResource vsRule = kubernetesClient diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerInvokerWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerInvokerWrapper.java index b4ee190812..2dd6d9c7e8 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerInvokerWrapper.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerInvokerWrapper.java @@ -17,6 +17,7 @@ package org.apache.dubbo.rpc.listener; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.LoggerCodeConstants; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.CollectionUtils; @@ -100,11 +101,12 @@ public class ListenerInvokerWrapper implements Invoker { try { consumer.accept(listener); } catch (RuntimeException t) { - logger.error(t.getMessage(), t); + logger.error(LoggerCodeConstants.INTERNAL_ERROR, "wrapped listener internal error", "", t.getMessage(), t); exception = t; } } } + if (exception != null) { throw exception; } From 93e60093c50c2e0ad051878a3333c30767f79907 Mon Sep 17 00:00:00 2001 From: Andy Cheung Date: Mon, 5 Dec 2022 11:14:54 +0800 Subject: [PATCH 04/10] Correct the error code inspector working branch in scheduled testing. (#11064) --- .github/workflows/build-and-test-scheduled-3.1.yml | 1 + .github/workflows/build-and-test-scheduled-3.2.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/build-and-test-scheduled-3.1.yml b/.github/workflows/build-and-test-scheduled-3.1.yml index 8b134b168f..c23d088670 100644 --- a/.github/workflows/build-and-test-scheduled-3.1.yml +++ b/.github/workflows/build-and-test-scheduled-3.1.yml @@ -315,6 +315,7 @@ jobs: steps: - uses: actions/checkout@v3 with: + ref: "3.1" path: "./dubbo" - uses: actions/checkout@v3 diff --git a/.github/workflows/build-and-test-scheduled-3.2.yml b/.github/workflows/build-and-test-scheduled-3.2.yml index c7dddc0c1d..9a6e14d9d9 100644 --- a/.github/workflows/build-and-test-scheduled-3.2.yml +++ b/.github/workflows/build-and-test-scheduled-3.2.yml @@ -314,6 +314,7 @@ jobs: steps: - uses: actions/checkout@v3 with: + ref: "3.2" path: "./dubbo" - uses: actions/checkout@v3 From c5815be7b62c0673a912e1fce45b5246325c4c51 Mon Sep 17 00:00:00 2001 From: huazhongming Date: Mon, 5 Dec 2022 11:56:37 +0800 Subject: [PATCH 05/10] Fix native image compile failure and run binary package failure (#11066) * fix native image failed Signed-off-by: crazyhzm * fix native image failed Signed-off-by: crazyhzm * remove import Signed-off-by: crazyhzm Signed-off-by: crazyhzm --- .gitignore | 6 + .../apache/dubbo/config/AbstractConfig.java | 7 +- .../dubbo-demo-native-consumer/pom.xml | 19 +++ .../demo/graalvm/consumer/Application.java | 10 +- .../dubbo-demo-native-provider/pom.xml | 20 +++ .../demo/graalvm/provider/Application.java | 25 ++-- .../META-INF/native-image/reflect-config.json | 115 ++++++++++++++++-- .../native-image/resource-config.json | 6 + .../MetricsReporterFactory$Adaptive.java | 30 +++++ .../serialize/Serialization$Adaptive.java | 4 +- .../MetadataReportFactory$Adaptive.java | 2 +- .../registry/RegistryFactory$Adaptive.java | 2 +- .../PortUnificationTransporter$Adaptive.java | 39 ++++++ .../state/StateRouterFactory$Adaptive.java | 7 +- 14 files changed, 263 insertions(+), 29 deletions(-) create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java create mode 100644 dubbo-native/src/main/java/org/apache/dubbo/remoting/api/pu/PortUnificationTransporter$Adaptive.java diff --git a/.gitignore b/.gitignore index 87a564393d..0eb7f3d19e 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,9 @@ dubbo-demo/dubbo-demo-triple/build/* # global registry center .tmp + +dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/resources/META-INF/native-image +dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/generated +dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/resources/META-INF/native-image +dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/generated + diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java index 53109a3564..e2bb8dc668 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java @@ -743,7 +743,12 @@ public abstract class AbstractConfig implements Serializable { && ClassUtils.isTypeMatch(method.getParameterTypes()[0], value) && !isIgnoredAttribute(obj.getClass(), propertyName)) { value = environment.resolvePlaceholders(value); - method.invoke(obj, ClassUtils.convertPrimitive(ScopeModelUtil.getFrameworkModel(getScopeModel()), method.getParameterTypes()[0], value)); + if (StringUtils.hasText(value)) { + Object arg = ClassUtils.convertPrimitive(ScopeModelUtil.getFrameworkModel(getScopeModel()), method.getParameterTypes()[0], value); + if (arg != null) { + method.invoke(obj, arg); + } + } } } catch (Exception e) { logger.info("Failed to override the property " + method.getName() + " in " + diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml index d23b171ad6..c0fa8b3015 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/pom.xml @@ -85,6 +85,16 @@ dubbo-remoting-http + + com.alibaba + fastjson + + + + org.apache.dubbo + dubbo-native + + @@ -184,11 +194,20 @@ --initialize-at-run-time=io.netty.channel.unix.Limits --initialize-at-run-time=io.netty.channel.unix.Socket --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=io.netty.internal.tcnative.CertificateVerifier + --initialize-at-run-time=io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod + --initialize-at-run-time=io.netty.handler.ssl.ReferenceCountedOpenSslEngine + --initialize-at-run-time=io.netty.handler.ssl.OpenSslPrivateKeyMethod + --initialize-at-run-time=io.netty.internal.tcnative.CertificateVerifier + --initialize-at-run-time=io.netty.internal.tcnative.SSL + --initialize-at-run-time=io.netty.handler.ssl.OpenSslAsyncPrivateKeyMethod + --initialize-at-run-time=io.netty.internal.tcnative.SSLPrivateKeyMethod --report-unsupported-elements-at-runtime --allow-incomplete-classpath --enable-url-protocols=http -H:+ReportExceptionStackTraces + -H:+AllowJRTFileSystem diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/java/com/apache/dubbo/demo/graalvm/consumer/Application.java b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/java/com/apache/dubbo/demo/graalvm/consumer/Application.java index 1c253d820c..d227b6c2e4 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/java/com/apache/dubbo/demo/graalvm/consumer/Application.java +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-consumer/src/main/java/com/apache/dubbo/demo/graalvm/consumer/Application.java @@ -33,6 +33,7 @@ public class Application { public static void main(String[] args) { System.setProperty("dubbo.application.logger", "log4j"); System.setProperty("native", "true"); + System.setProperty("dubbo.json-framework.prefer","fastjson"); if (isClassic(args)) { runWithRefer(); } else { @@ -45,11 +46,8 @@ public class Application { } private static void runWithBootstrap() { - ReferenceConfig reference = new ReferenceConfig<>(); - reference.setInterface(DemoService.class); - reference.setGeneric("false"); - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); + ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-api-consumer"); applicationConfig.setQosEnable(false); applicationConfig.setCompiler("jdk"); @@ -57,6 +55,10 @@ public class Application { m.put("proxy", "jdk"); applicationConfig.setParameters(m); + ReferenceConfig reference = new ReferenceConfig<>(); + reference.setInterface(DemoService.class); + reference.setGeneric("false"); + bootstrap.application(applicationConfig) .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) .protocol(new ProtocolConfig(CommonConstants.DUBBO, -1)) diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml index 5319a3553a..98caedd58f 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/pom.xml @@ -79,6 +79,17 @@ dubbo-remoting-http + + com.alibaba + fastjson + + + + org.apache.dubbo + dubbo-native + + + @@ -180,11 +191,20 @@ --initialize-at-run-time=io.netty.channel.unix.Limits --initialize-at-run-time=io.netty.channel.unix.Socket --initialize-at-run-time=io.netty.channel.ChannelHandlerMask + --initialize-at-run-time=io.netty.internal.tcnative.CertificateVerifier + --initialize-at-run-time=io.netty.internal.tcnative.AsyncSSLPrivateKeyMethod + --initialize-at-run-time=io.netty.handler.ssl.ReferenceCountedOpenSslEngine + --initialize-at-run-time=io.netty.handler.ssl.OpenSslPrivateKeyMethod + --initialize-at-run-time=io.netty.internal.tcnative.CertificateVerifier + --initialize-at-run-time=io.netty.internal.tcnative.SSL + --initialize-at-run-time=io.netty.handler.ssl.OpenSslAsyncPrivateKeyMethod + --initialize-at-run-time=io.netty.internal.tcnative.SSLPrivateKeyMethod --report-unsupported-elements-at-runtime --allow-incomplete-classpath --enable-url-protocols=http -H:+ReportExceptionStackTraces + -H:+AllowJRTFileSystem diff --git a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/java/org/apache/dubbo/demo/graalvm/provider/Application.java b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/java/org/apache/dubbo/demo/graalvm/provider/Application.java index 60d21c93c4..66b0796c44 100644 --- a/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/java/org/apache/dubbo/demo/graalvm/provider/Application.java +++ b/dubbo-demo/dubbo-demo-native/dubbo-demo-native-provider/src/main/java/org/apache/dubbo/demo/graalvm/provider/Application.java @@ -24,6 +24,7 @@ import org.apache.dubbo.config.ServiceConfig; import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apace.dubbo.graalvm.demo.DemoService; +import org.apache.dubbo.rpc.model.ModuleModel; import java.util.HashMap; import java.util.Map; @@ -34,6 +35,7 @@ public class Application { public static void main(String[] args) throws Exception { System.setProperty("dubbo.application.logger", "log4j"); System.setProperty("native", "true"); + System.setProperty("dubbo.json-framework.prefer","fastjson"); if (isClassic(args)) { startWithExport(); } else { @@ -47,32 +49,30 @@ public class Application { } private static void startWithBootstrap() { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(DemoService.class); - service.setRef(new DemoServiceImpl()); - DubboBootstrap bootstrap = DubboBootstrap.getInstance(); - ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-api-provider"); + ApplicationConfig applicationConfig = new ApplicationConfig( "dubbo-demo-api-provider"); applicationConfig.setQosEnable(false); applicationConfig.setCompiler("jdk"); Map m = new HashMap<>(1); m.put("proxy", "jdk"); applicationConfig.setParameters(m); + ServiceConfig service = new ServiceConfig<>(); + service.setInterface(DemoService.class); + service.setRef(new DemoServiceImpl()); + bootstrap.application(applicationConfig) .registry(new RegistryConfig("zookeeper://127.0.0.1:2181")) .protocol(new ProtocolConfig(CommonConstants.DUBBO, -1)) .service(service) .start() .await(); + + System.out.println("dubbo service started"); } private static void startWithExport() throws InterruptedException { - ServiceConfig service = new ServiceConfig<>(); - service.setInterface(DemoService.class); - service.setRef(new DemoServiceImpl()); - ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-api-provider"); applicationConfig.setQosEnable(false); applicationConfig.setCompiler("jdk"); @@ -81,6 +81,13 @@ public class Application { m.put("proxy", "jdk"); applicationConfig.setParameters(m); + ModuleModel moduleModel = applicationConfig.getApplicationModel().newModule(); + + + ServiceConfig service = new ServiceConfig<>(moduleModel); + service.setInterface(DemoService.class); + service.setRef(new DemoServiceImpl()); + service.setApplication(applicationConfig); service.setRegistry(new RegistryConfig("zookeeper://127.0.0.1:2181")); service.export(); diff --git a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json index 84975373e9..38d23920d7 100644 --- a/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json +++ b/dubbo-native-plugin/src/main/resources/META-INF/native-image/reflect-config.json @@ -1107,7 +1107,7 @@ "methods": [ { "name": "", - "parameterTypes": [] + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] } ] }, @@ -1332,7 +1332,13 @@ }, { "name": "org.apache.dubbo.config.deploy.DefaultApplicationDeployer", - "allPublicConstructors": true + "allPublicConstructors": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] + } + ] }, { "name": "org.apache.dubbo.config.deploy.DefaultModuleDeployer", @@ -1481,7 +1487,7 @@ "methods": [ { "name": "", - "parameterTypes": [] + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] } ] }, @@ -2062,7 +2068,13 @@ { "name": "org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter", "allPublicMethods": true, - "allPublicConstructors": true + "allPublicConstructors": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] }, { "name": "org.apache.dubbo.rpc.cluster.filter.support.ZoneAwareFilter" @@ -2347,9 +2359,6 @@ { "name": "org.apache.dubbo.rpc.filter.CompatibleFilter" }, - { - "name": "org.apache.dubbo.rpc.filter.ContextFilter" - }, { "name": "org.apache.dubbo.rpc.filter.DeprecatedFilter" }, @@ -2671,5 +2680,97 @@ "parameterTypes": [] } ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.convert.ConverterUtil", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.FrameworkModel"] + } + ] + }, + { + "name": "org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.ModuleModel"] + } + ] + }, + { + "name": "org.apache.dubbo.config.context.ModuleConfigManager", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.ModuleModel"] + } + ] + }, + { + "name": "org.apache.dubbo.common.store.support.SimpleDataStore", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "org.apache.dubbo.common.metrics.collector.DefaultMetricsCollector", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": ["org.apache.dubbo.rpc.model.ApplicationModel"] + } + ] + }, + { + "name": "org.apache.dubbo.config.deploy.DefaultMetricsServiceExporter", + "allPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.alibaba.fastjson.JSON", + "allPublicMethods": true + }, + { + "name": "java.util.Collections$UnmodifiableMap", + "allPublicMethods": true + }, + { + "name": "java.util.Collections$UnmodifiableCollection", + "allPublicMethods": true } ] diff --git a/dubbo-native-plugin/src/main/resources/META-INF/native-image/resource-config.json b/dubbo-native-plugin/src/main/resources/META-INF/native-image/resource-config.json index 2d1ac938e9..977e6eb3d1 100644 --- a/dubbo-native-plugin/src/main/resources/META-INF/native-image/resource-config.json +++ b/dubbo-native-plugin/src/main/resources/META-INF/native-image/resource-config.json @@ -153,6 +153,12 @@ }, { "pattern": "\\Qorg/apache/dubbo/remoting/exchange/Exchangers.class\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore\\E" + }, + { + "pattern": "\\QMETA-INF/dubbo/internal/org.apache.dubbo.common.metrics.service.MetricsServiceExporter\\E" } ] }, diff --git a/dubbo-native/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.java new file mode 100644 index 0000000000..aa288ce381 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/common/metrics/MetricsReporterFactory$Adaptive.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.common.metrics; +import org.apache.dubbo.rpc.model.ScopeModel; +import org.apache.dubbo.rpc.model.ScopeModelUtil; +public class MetricsReporterFactory$Adaptive implements org.apache.dubbo.common.metrics.MetricsReporterFactory { +public org.apache.dubbo.common.metrics.MetricsReporter createMetricsReporter(org.apache.dubbo.common.URL arg0) { +if (arg0 == null) throw new IllegalArgumentException("url == null"); +org.apache.dubbo.common.URL url = arg0; +String extName = ( url.getProtocol() == null ? "nop" : url.getProtocol() ); +if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.metrics.MetricsReporterFactory) name from url (" + url.toString() + ") use keys([protocol])"); +ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.common.metrics.MetricsReporterFactory.class); +org.apache.dubbo.common.metrics.MetricsReporterFactory extension = (org.apache.dubbo.common.metrics.MetricsReporterFactory)scopeModel.getExtensionLoader(org.apache.dubbo.common.metrics.MetricsReporterFactory.class).getExtension(extName); +return extension.createMetricsReporter(arg0); +} +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/common/serialize/Serialization$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/common/serialize/Serialization$Adaptive.java index 9bf19889e7..ae3a0b6d6a 100644 --- a/dubbo-native/src/main/java/org/apache/dubbo/common/serialize/Serialization$Adaptive.java +++ b/dubbo-native/src/main/java/org/apache/dubbo/common/serialize/Serialization$Adaptive.java @@ -27,7 +27,7 @@ throw new UnsupportedOperationException("The method public abstract java.lang.St public org.apache.dubbo.common.serialize.ObjectInput deserialize(org.apache.dubbo.common.URL arg0, java.io.InputStream arg1) throws java.io.IOException { if (arg0 == null) throw new IllegalArgumentException("url == null"); org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("serialization", "hessian2"); +String extName = url.getParameter("serialization", "adaptive"); if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.serialize.Serialization) name from url (" + url.toString() + ") use keys([serialization])"); ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.common.serialize.Serialization.class); org.apache.dubbo.common.serialize.Serialization extension = (org.apache.dubbo.common.serialize.Serialization)scopeModel.getExtensionLoader(org.apache.dubbo.common.serialize.Serialization.class).getExtension(extName); @@ -36,7 +36,7 @@ return extension.deserialize(arg0, arg1); public org.apache.dubbo.common.serialize.ObjectOutput serialize(org.apache.dubbo.common.URL arg0, java.io.OutputStream arg1) throws java.io.IOException { if (arg0 == null) throw new IllegalArgumentException("url == null"); org.apache.dubbo.common.URL url = arg0; -String extName = url.getParameter("serialization", "hessian2"); +String extName = url.getParameter("serialization", "adaptive"); if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.serialize.Serialization) name from url (" + url.toString() + ") use keys([serialization])"); ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.common.serialize.Serialization.class); org.apache.dubbo.common.serialize.Serialization extension = (org.apache.dubbo.common.serialize.Serialization)scopeModel.getExtensionLoader(org.apache.dubbo.common.serialize.Serialization.class).getExtension(extName); diff --git a/dubbo-native/src/main/java/org/apache/dubbo/metadata/report/MetadataReportFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/metadata/report/MetadataReportFactory$Adaptive.java index 069e3b940f..0816ad1ec3 100644 --- a/dubbo-native/src/main/java/org/apache/dubbo/metadata/report/MetadataReportFactory$Adaptive.java +++ b/dubbo-native/src/main/java/org/apache/dubbo/metadata/report/MetadataReportFactory$Adaptive.java @@ -28,6 +28,6 @@ org.apache.dubbo.metadata.report.MetadataReportFactory extension = (org.apache.d return extension.getMetadataReport(arg0); } public void destroy() { -throw new UnsupportedOperationException("The method public abstract void org.apache.dubbo.metadata.report.MetadataReportFactory.destroy() of interface org.apache.dubbo.metadata.report.MetadataReportFactory is not adaptive method!"); +throw new UnsupportedOperationException("The method public default void org.apache.dubbo.metadata.report.MetadataReportFactory.destroy() of interface org.apache.dubbo.metadata.report.MetadataReportFactory is not adaptive method!"); } } diff --git a/dubbo-native/src/main/java/org/apache/dubbo/registry/RegistryFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/registry/RegistryFactory$Adaptive.java index 85bb0b61d1..8b3ebc963e 100644 --- a/dubbo-native/src/main/java/org/apache/dubbo/registry/RegistryFactory$Adaptive.java +++ b/dubbo-native/src/main/java/org/apache/dubbo/registry/RegistryFactory$Adaptive.java @@ -21,7 +21,7 @@ public class RegistryFactory$Adaptive implements org.apache.dubbo.registry.Regis public org.apache.dubbo.registry.Registry getRegistry(org.apache.dubbo.common.URL arg0) { if (arg0 == null) throw new IllegalArgumentException("url == null"); org.apache.dubbo.common.URL url = arg0; -String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() ); +String extName = ( url.getProtocol() == null ? "adaptive" : url.getProtocol() ); if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.registry.RegistryFactory) name from url (" + url.toString() + ") use keys([protocol])"); ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.registry.RegistryFactory.class); org.apache.dubbo.registry.RegistryFactory extension = (org.apache.dubbo.registry.RegistryFactory)scopeModel.getExtensionLoader(org.apache.dubbo.registry.RegistryFactory.class).getExtension(extName); diff --git a/dubbo-native/src/main/java/org/apache/dubbo/remoting/api/pu/PortUnificationTransporter$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/remoting/api/pu/PortUnificationTransporter$Adaptive.java new file mode 100644 index 0000000000..3f6c242732 --- /dev/null +++ b/dubbo-native/src/main/java/org/apache/dubbo/remoting/api/pu/PortUnificationTransporter$Adaptive.java @@ -0,0 +1,39 @@ +/* + * 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.remoting.api.pu; +import org.apache.dubbo.rpc.model.ScopeModel; +import org.apache.dubbo.rpc.model.ScopeModelUtil; +public class PortUnificationTransporter$Adaptive implements org.apache.dubbo.remoting.api.pu.PortUnificationTransporter { +public org.apache.dubbo.remoting.Client connect(org.apache.dubbo.common.URL arg0, org.apache.dubbo.remoting.ChannelHandler arg1) throws org.apache.dubbo.remoting.RemotingException { +if (arg0 == null) throw new IllegalArgumentException("url == null"); +org.apache.dubbo.common.URL url = arg0; +String extName = url.getParameter("client", url.getParameter("transporter", "netty4")); +if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.api.pu.PortUnificationTransporter) name from url (" + url.toString() + ") use keys([client, transporter])"); +ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.api.pu.PortUnificationTransporter.class); +org.apache.dubbo.remoting.api.pu.PortUnificationTransporter extension = (org.apache.dubbo.remoting.api.pu.PortUnificationTransporter)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.api.pu.PortUnificationTransporter.class).getExtension(extName); +return extension.connect(arg0, arg1); +} +public org.apache.dubbo.remoting.api.pu.AbstractPortUnificationServer bind(org.apache.dubbo.common.URL arg0, org.apache.dubbo.remoting.ChannelHandler arg1) throws org.apache.dubbo.remoting.RemotingException { +if (arg0 == null) throw new IllegalArgumentException("url == null"); +org.apache.dubbo.common.URL url = arg0; +String extName = url.getParameter("server", url.getParameter("transporter", "netty4")); +if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.remoting.api.pu.PortUnificationTransporter) name from url (" + url.toString() + ") use keys([server, transporter])"); +ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.remoting.api.pu.PortUnificationTransporter.class); +org.apache.dubbo.remoting.api.pu.PortUnificationTransporter extension = (org.apache.dubbo.remoting.api.pu.PortUnificationTransporter)scopeModel.getExtensionLoader(org.apache.dubbo.remoting.api.pu.PortUnificationTransporter.class).getExtension(extName); +return extension.bind(arg0, arg1); +} +} diff --git a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory$Adaptive.java b/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory$Adaptive.java index 2dc6ccf2fc..c33747dc83 100644 --- a/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory$Adaptive.java +++ b/dubbo-native/src/main/java/org/apache/dubbo/rpc/cluster/router/state/StateRouterFactory$Adaptive.java @@ -15,17 +15,16 @@ * limitations under the License. */ package org.apache.dubbo.rpc.cluster.router.state; -import org.apache.dubbo.common.URL; import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.model.ScopeModelUtil; public class StateRouterFactory$Adaptive implements org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory { -public org.apache.dubbo.rpc.cluster.router.state.StateRouter getRouter(Class arg0, URL arg1) { -if (arg0 == null) throw new IllegalArgumentException("url == null"); +public org.apache.dubbo.rpc.cluster.router.state.StateRouter getRouter(java.lang.Class arg0, org.apache.dubbo.common.URL arg1) { +if (arg1 == null) throw new IllegalArgumentException("url == null"); org.apache.dubbo.common.URL url = arg1; String extName = ( url.getProtocol() == null ? "adaptive" : url.getProtocol() ); if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory) name from url (" + url.toString() + ") use keys([protocol])"); ScopeModel scopeModel = ScopeModelUtil.getOrDefault(url.getScopeModel(), org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory.class); org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory extension = (org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory)scopeModel.getExtensionLoader(org.apache.dubbo.rpc.cluster.router.state.StateRouterFactory.class).getExtension(extName); -return extension.getRouter(arg0,arg1); +return extension.getRouter(arg0, arg1); } } From 9b9b12033f413d10aca93d2727f17dd82ea2dfa0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Dec 2022 14:06:46 +0800 Subject: [PATCH 06/10] Bump resteasy-jaxrs in /dubbo-dependencies-bom (#11071) --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 54b8ae9acc..1b935fdc46 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -138,7 +138,7 @@ 3.4.19 2.0 - 3.0.19.Final + 3.0.20.Final 8.5.78 0.5.3 2.1.2 From 1470c7ca1eeba0ad4bcb309678e5c432bbfc002f Mon Sep 17 00:00:00 2001 From: huazhongming Date: Mon, 5 Dec 2022 15:37:33 +0800 Subject: [PATCH 07/10] Cache jvm system parameters to prevent each call from being executed, affecting performance (#10839) * Cache jvm system parameters to prevent each call from being executed, affecting performance Signed-off-by: crazyhzm * fix npe Signed-off-by: crazyhzm * optimization performance Signed-off-by: crazyhzm * remove unused import Signed-off-by: crazyhzm * add default config value Signed-off-by: crazyhzm * change getProperty method Signed-off-by: crazyhzm * change convert method Signed-off-by: crazyhzm * change getInternalProperty by default value Signed-off-by: crazyhzm * add overwrite cache api Signed-off-by: crazyhzm * add clear cache api Signed-off-by: crazyhzm * fix ut Signed-off-by: crazyhzm * fix ut Signed-off-by: crazyhzm * fix ut Signed-off-by: crazyhzm * reset DubboBootstrap Signed-off-by: crazyhzm * change serialization.security.check config to app scopemodel Signed-off-by: crazyhzm * fix url without scopemodel Signed-off-by: crazyhzm * fix url without scopemodel Signed-off-by: crazyhzm Signed-off-by: crazyhzm --- .../common/config/CompositeConfiguration.java | 16 ++ .../dubbo/common/config/Configuration.java | 32 +-- .../config/EnvironmentConfiguration.java | 13 ++ .../common/config/InmemoryConfiguration.java | 10 + .../OrderedPropertiesConfiguration.java | 10 + .../common/config/PrefixedConfiguration.java | 13 ++ .../config/PropertiesConfiguration.java | 10 + .../common/config/SystemConfiguration.java | 48 ++++- .../AbstractDynamicConfiguration.java | 5 + .../nop/NopDynamicConfiguration.java | 5 + .../CompositeDynamicConfiguration.java | 5 + .../context/ConfigConfigurationAdapter.java | 10 + .../config/SystemConfigurationTest.java | 18 +- .../utils/SerializeClassCheckerTest.java | 32 +-- .../config/bootstrap/MultiInstanceTest.java | 37 ++-- .../apollo/ApolloDynamicConfiguration.java | 10 + .../nacos/NacosDynamicConfiguration.java | 11 ++ .../ZookeeperDynamicConfiguration.java | 10 + .../org/apache/dubbo/rpc/AsyncRpcResult.java | 12 +- .../dubbo/rpc/filter/AccessLogFilter.java | 4 +- .../dubbo/rpc/protocol/AbstractInvoker.java | 12 +- .../dubbo/DecodeableRpcInvocation.java | 14 +- .../dubbo/decode/DubboTelnetDecodeTest.java | 187 +++++++++--------- .../DefaultHessian2FactoryInitializer.java | 2 +- .../dubbo/Hessian2FactoryInitializer.java | 2 + 25 files changed, 370 insertions(+), 158 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/CompositeConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/CompositeConfiguration.java index 1653e96134..6212108a2b 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/CompositeConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/CompositeConfiguration.java @@ -89,4 +89,20 @@ public class CompositeConfiguration implements Configuration { return null; } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + for (Configuration config : configList) { + try { + Object value = config.getProperty(key, defaultValue); + if (!ConfigurationUtils.isEmptyValue(value)) { + return value; + } + } catch (Exception e) { + logger.error("Error when trying to get value for key " + key + " from " + config + ", " + + "will continue to try the next one."); + } + } + return defaultValue; + } + } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Configuration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Configuration.java index 5c3988ab02..6a4f3ba7ae 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/Configuration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/Configuration.java @@ -127,18 +127,19 @@ public interface Configuration { * Gets a property from the configuration. The default value will return if the configuration doesn't contain * the mapping for the specified key. * - * @param key property to retrieve + * @param key property to retrieve * @param defaultValue default value * @return the value to which this configuration maps the specified key, or default value if the configuration * contains no mapping for this key. */ default Object getProperty(String key, Object defaultValue) { - Object value = getInternalProperty(key); - return value != null ? value : defaultValue; + return getInternalProperty(key, defaultValue); } Object getInternalProperty(String key); + Object getInternalProperty(String key, Object defaultValue); + /** * Check if the configuration contains the specified key. * @@ -153,9 +154,12 @@ public interface Configuration { default T convert(Class cls, String key, T defaultValue) { // we only process String properties for now - String value = (String) getProperty(key); + Object value = getProperty(key, defaultValue); - if (value == null) { + if (!String.class.isInstance(value)) { + if (cls.isInstance(value)) { + return cls.cast(value); + } return defaultValue; } @@ -164,24 +168,26 @@ public interface Configuration { return cls.cast(value); } + String str = (String) value; + if (Boolean.class.equals(cls) || Boolean.TYPE.equals(cls)) { - obj = Boolean.valueOf(value); + obj = Boolean.valueOf(str); } else if (Number.class.isAssignableFrom(cls) || cls.isPrimitive()) { if (Integer.class.equals(cls) || Integer.TYPE.equals(cls)) { - obj = Integer.valueOf(value); + obj = Integer.valueOf(str); } else if (Long.class.equals(cls) || Long.TYPE.equals(cls)) { - obj = Long.valueOf(value); + obj = Long.valueOf(str); } else if (Byte.class.equals(cls) || Byte.TYPE.equals(cls)) { - obj = Byte.valueOf(value); + obj = Byte.valueOf(str); } else if (Short.class.equals(cls) || Short.TYPE.equals(cls)) { - obj = Short.valueOf(value); + obj = Short.valueOf(str); } else if (Float.class.equals(cls) || Float.TYPE.equals(cls)) { - obj = Float.valueOf(value); + obj = Float.valueOf(str); } else if (Double.class.equals(cls) || Double.TYPE.equals(cls)) { - obj = Double.valueOf(value); + obj = Double.valueOf(str); } } else if (cls.isEnum()) { - obj = Enum.valueOf(cls.asSubclass(Enum.class), value); + obj = Enum.valueOf(cls.asSubclass(Enum.class), str); } return cls.cast(obj); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/EnvironmentConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/EnvironmentConfiguration.java index 227b180897..c95e92864e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/EnvironmentConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/EnvironmentConfiguration.java @@ -34,6 +34,19 @@ public class EnvironmentConfiguration implements Configuration { return value; } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + String value = System.getenv(key); + if (StringUtils.isEmpty(value)) { + value = System.getenv(StringUtils.toOSStyleKey(key)); + } + + if (StringUtils.isEmpty(value)) { + return defaultValue; + } + return value; + } + public Map getProperties() { return System.getenv(); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/InmemoryConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/InmemoryConfiguration.java index 92d808de9f..6fc1d01c80 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/InmemoryConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/InmemoryConfiguration.java @@ -45,6 +45,16 @@ public class InmemoryConfiguration implements Configuration { return store.get(key); } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + Object v = store.get(key); + if (v != null) { + return v; + } else { + return defaultValue; + } + } + /** * Add one property into the store, the previous value will be replaced if the key exists */ diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesConfiguration.java index 191320ed7f..dbf0719429 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/OrderedPropertiesConfiguration.java @@ -68,6 +68,16 @@ public class OrderedPropertiesConfiguration implements Configuration { return properties.getProperty(key); } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + Object v = properties.getProperty(key); + if (v != null){ + return v; + }else { + return defaultValue; + } + } + public void setProperty(String key, String value) { properties.setProperty(key, value); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/PrefixedConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/PrefixedConfiguration.java index e23e6601ec..0220a1ecf1 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/PrefixedConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/PrefixedConfiguration.java @@ -42,4 +42,17 @@ public class PrefixedConfiguration implements Configuration { return null; } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + if (StringUtils.isBlank(prefix)) { + return origin.getInternalProperty(key, defaultValue); + } + + Object value = origin.getInternalProperty(prefix + "." + key, defaultValue); + if (!ConfigurationUtils.isEmptyValue(value)) { + return value; + } + return null; + } + } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java index e215dfb799..9d4ed79234 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/PropertiesConfiguration.java @@ -49,6 +49,16 @@ public class PropertiesConfiguration implements Configuration { return properties.getProperty(key); } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + Object v = properties.getProperty(key); + if (v != null){ + return v; + }else { + return defaultValue; + } + } + public void setProperty(String key, String value) { properties.setProperty(key, value); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/SystemConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/SystemConfiguration.java index 8341fd4e15..9ea3c207b6 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/SystemConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/SystemConfiguration.java @@ -18,17 +18,61 @@ package org.apache.dubbo.common.config; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** - * Configuration from system properties + * FIXME: is this really necessary? PropertiesConfiguration should have already covered this: + * + * @See ConfigUtils#getProperty(String) + * @see PropertiesConfiguration */ public class SystemConfiguration implements Configuration { + private final Map cache = new ConcurrentHashMap<>(); + @Override public Object getInternalProperty(String key) { - return System.getProperty(key); + if (cache.containsKey(key)) { + return cache.get(key); + } else { + Object val = System.getProperty(key); + if (val != null) { + cache.putIfAbsent(key, val); + } + return val; + } } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + if (cache.containsKey(key)) { + return cache.get(key); + } else { + Object val = System.getProperty(key); + if (val != null) { + cache.putIfAbsent(key, val); + } else { + val = defaultValue; + if (defaultValue != null) { + cache.putIfAbsent(key, defaultValue); + } + } + return val; + } + } + + public void overwriteCache(String key, Object value) { + if (value != null) { + cache.put(key, value); + } + } + + public void clearCache() { + cache.clear(); + } + + + public Map getProperties() { return (Map) System.getProperties(); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfiguration.java index afd1cac989..71a959dab7 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfiguration.java @@ -120,6 +120,11 @@ public abstract class AbstractDynamicConfiguration implements DynamicConfigurati return null; } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + return null; + } + @Override public final void close() throws Exception { try { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java index 0f08705189..f834ed7ff7 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java @@ -36,6 +36,11 @@ public class NopDynamicConfiguration implements DynamicConfiguration { return null; } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + return null; + } + @Override public void addListener(String key, String group, ConfigurationListener listener) { // no-op diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java index d9f6e3d30d..c1ee02d05e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java @@ -75,6 +75,11 @@ public class CompositeDynamicConfiguration implements DynamicConfiguration { return iterateConfigOperation(configuration -> configuration.getInternalProperty(key)); } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + return iterateConfigOperation(configuration -> configuration.getInternalProperty(key, defaultValue)); + } + @Override public boolean publishConfig(String key, String group, String content) throws UnsupportedOperationException { boolean publishedAll = true; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigConfigurationAdapter.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigConfigurationAdapter.java index 2b141e8a8b..15599e4cfb 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigConfigurationAdapter.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigConfigurationAdapter.java @@ -42,6 +42,16 @@ public class ConfigConfigurationAdapter implements Configuration { return metaData.get(key); } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + Object v = metaData.get(key); + if (v != null) { + return v; + } else { + return defaultValue; + } + } + public Map getProperties() { return metaData; } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/config/SystemConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/SystemConfigurationTest.java index d25f46101c..ddb1dfde58 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/config/SystemConfigurationTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/config/SystemConfigurationTest.java @@ -70,23 +70,23 @@ class SystemConfigurationTest { void testConvert() { Assertions.assertEquals( MOCK_STRING_VALUE, sysConfig.convert(String.class, NOT_EXIST_KEY, MOCK_STRING_VALUE)); - System.setProperty(MOCK_KEY, String.valueOf(MOCK_BOOL_VALUE)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(MOCK_BOOL_VALUE)); Assertions.assertEquals(MOCK_BOOL_VALUE, sysConfig.convert(Boolean.class, MOCK_KEY, null)); - System.setProperty(MOCK_KEY, String.valueOf(MOCK_STRING_VALUE)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(MOCK_STRING_VALUE)); Assertions.assertEquals(MOCK_STRING_VALUE, sysConfig.convert(String.class, MOCK_KEY, null)); - System.setProperty(MOCK_KEY, String.valueOf(MOCK_INT_VALUE)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(MOCK_INT_VALUE)); Assertions.assertEquals(MOCK_INT_VALUE, sysConfig.convert(Integer.class, MOCK_KEY, null)); - System.setProperty(MOCK_KEY, String.valueOf(MOCK_LONG_VALUE)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(MOCK_LONG_VALUE)); Assertions.assertEquals(MOCK_LONG_VALUE, sysConfig.convert(Long.class, MOCK_KEY, null)); - System.setProperty(MOCK_KEY, String.valueOf(MOCK_SHORT_VALUE)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(MOCK_SHORT_VALUE)); Assertions.assertEquals(MOCK_SHORT_VALUE, sysConfig.convert(Short.class, MOCK_KEY, null)); - System.setProperty(MOCK_KEY, String.valueOf(MOCK_FLOAT_VALUE)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(MOCK_FLOAT_VALUE)); Assertions.assertEquals(MOCK_FLOAT_VALUE, sysConfig.convert(Float.class, MOCK_KEY, null)); - System.setProperty(MOCK_KEY, String.valueOf(MOCK_DOUBLE_VALUE)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(MOCK_DOUBLE_VALUE)); Assertions.assertEquals(MOCK_DOUBLE_VALUE, sysConfig.convert(Double.class, MOCK_KEY, null)); - System.setProperty(MOCK_KEY, String.valueOf(MOCK_BYTE_VALUE)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(MOCK_BYTE_VALUE)); Assertions.assertEquals(MOCK_BYTE_VALUE, sysConfig.convert(Byte.class, MOCK_KEY, null)); - System.setProperty(MOCK_KEY, String.valueOf(ConfigMock.MockOne)); + sysConfig.overwriteCache(MOCK_KEY, String.valueOf(ConfigMock.MockOne)); Assertions.assertEquals(ConfigMock.MockOne, sysConfig.convert(ConfigMock.class, MOCK_KEY, null)); } diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/SerializeClassCheckerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/SerializeClassCheckerTest.java index 0ffd6546c3..62a923f5ee 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/SerializeClassCheckerTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/SerializeClassCheckerTest.java @@ -16,9 +16,11 @@ */ package org.apache.dubbo.common.utils; +import org.apache.dubbo.common.config.SystemConfiguration; import org.apache.dubbo.common.constants.CommonConstants; import javassist.compiler.Javac; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -57,14 +59,16 @@ class SerializeClassCheckerTest { serializeClassChecker.validateClass(int.class.getName().toUpperCase(Locale.ROOT)); } - Assertions.assertThrows(IllegalArgumentException.class, ()-> { + Assertions.assertThrows(IllegalArgumentException.class, () -> { serializeClassChecker.validateClass(Socket.class.getName()); }); } @Test void testAddAllow() { - System.setProperty(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST, Socket.class.getName() + "," + Javac.class.getName()); + SystemConfiguration systemConfiguration = ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration(); + + systemConfiguration.overwriteCache(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST, Socket.class.getName() + "," + Javac.class.getName()); SerializeClassChecker serializeClassChecker = SerializeClassChecker.getInstance(); for (int i = 0; i < 10; i++) { @@ -72,40 +76,44 @@ class SerializeClassCheckerTest { serializeClassChecker.validateClass(Javac.class.getName()); } - System.clearProperty(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST); + systemConfiguration.clearCache(); + } @Test void testAddBlock() { - System.setProperty(CommonConstants.CLASS_DESERIALIZE_BLOCKED_LIST, LinkedList.class.getName() + "," + Integer.class.getName()); + SystemConfiguration systemConfiguration = ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration(); + systemConfiguration.overwriteCache(CommonConstants.CLASS_DESERIALIZE_BLOCKED_LIST, LinkedList.class.getName() + "," + Integer.class.getName()); SerializeClassChecker serializeClassChecker = SerializeClassChecker.getInstance(); for (int i = 0; i < 10; i++) { - Assertions.assertThrows(IllegalArgumentException.class, ()-> { + Assertions.assertThrows(IllegalArgumentException.class, () -> { serializeClassChecker.validateClass(LinkedList.class.getName()); }); - Assertions.assertThrows(IllegalArgumentException.class, ()-> { + Assertions.assertThrows(IllegalArgumentException.class, () -> { serializeClassChecker.validateClass(Integer.class.getName()); }); } - System.clearProperty(CommonConstants.CLASS_DESERIALIZE_BLOCKED_LIST); + systemConfiguration.clearCache(); + } @Test void testBlockAll() { - System.setProperty(CommonConstants.CLASS_DESERIALIZE_BLOCK_ALL, "true"); - System.setProperty(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST, LinkedList.class.getName()); + SystemConfiguration systemConfiguration = ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration(); + + systemConfiguration.overwriteCache(CommonConstants.CLASS_DESERIALIZE_BLOCK_ALL, "true"); + systemConfiguration.overwriteCache(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST, LinkedList.class.getName()); SerializeClassChecker serializeClassChecker = SerializeClassChecker.getInstance(); for (int i = 0; i < 10; i++) { serializeClassChecker.validateClass(LinkedList.class.getName()); - Assertions.assertThrows(IllegalArgumentException.class, ()-> { + Assertions.assertThrows(IllegalArgumentException.class, () -> { serializeClassChecker.validateClass(Integer.class.getName()); }); } - System.clearProperty(CommonConstants.CLASS_DESERIALIZE_BLOCK_ALL); - System.clearProperty(CommonConstants.CLASS_DESERIALIZE_ALLOWED_LIST); + systemConfiguration.clearCache(); } } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/MultiInstanceTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/MultiInstanceTest.java index 994fbe5c99..4ddcb4450f 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/MultiInstanceTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/MultiInstanceTest.java @@ -122,7 +122,6 @@ class MultiInstanceTest { @AfterEach public void afterEach() { SysProps.clear(); - DubboBootstrap.reset(); } @Test @@ -154,12 +153,12 @@ class MultiInstanceTest { @Test void testDefaultProviderApplication() { + DubboBootstrap.reset(); DubboBootstrap dubboBootstrap = DubboBootstrap.getInstance(); try { configProviderApp(dubboBootstrap).start(); } finally { dubboBootstrap.destroy(); - DubboBootstrap.reset(); } } @@ -174,13 +173,12 @@ class MultiInstanceTest { Assertions.assertTrue(e.toString().contains("No provider available"), StringUtils.toString(e)); } finally { dubboBootstrap.destroy(); - DubboBootstrap.reset(); - SysProps.clear(); } } @Test void testDefaultMixedApplication() { + DubboBootstrap.reset(); DubboBootstrap dubboBootstrap = DubboBootstrap.getInstance(); try { dubboBootstrap.application("mixed-app"); @@ -191,7 +189,6 @@ class MultiInstanceTest { testConsumer(dubboBootstrap); } finally { dubboBootstrap.destroy(); - DubboBootstrap.reset(); } } @@ -221,6 +218,8 @@ class MultiInstanceTest { void testMultiModuleApplication() throws InterruptedException { //SysProps.setProperty(METADATA_PUBLISH_DELAY_KEY, "100"); + + FrameworkModel frameworkModel = new FrameworkModel(); String version1 = "1.0"; String version2 = "2.0"; String version3 = "3.0"; @@ -230,7 +229,7 @@ class MultiInstanceTest { try { // provider app - providerBootstrap = DubboBootstrap.newInstance(); + providerBootstrap = DubboBootstrap.newInstance(frameworkModel); ServiceConfig serviceConfig1 = new ServiceConfig(); serviceConfig1.setInterface(DemoService.class); @@ -274,7 +273,7 @@ class MultiInstanceTest { //Thread.sleep(200); // consumer app - consumerBootstrap = DubboBootstrap.newInstance(); + consumerBootstrap = DubboBootstrap.newInstance(frameworkModel); consumerBootstrap.application("consumer-app") .registry(registryConfig) .reference(builder -> builder @@ -308,10 +307,12 @@ class MultiInstanceTest { @Test void testMultiProviderApplicationsStopOneByOne() { + DubboBootstrap.reset(); String version1 = "1.0"; String version2 = "2.0"; + FrameworkModel frameworkModel = new FrameworkModel(); DubboBootstrap providerBootstrap1 = null; DubboBootstrap providerBootstrap2 = null; @@ -328,7 +329,7 @@ class MultiInstanceTest { ProtocolConfig protocolConfig1 = new ProtocolConfig("dubbo", NetUtils.getAvailablePort()); - providerBootstrap1 = DubboBootstrap.getInstance(); + providerBootstrap1 = DubboBootstrap.newInstance(frameworkModel); providerBootstrap1.application("provider1") .registry(registryConfig) .service(serviceConfig1) @@ -351,7 +352,7 @@ class MultiInstanceTest { ProtocolConfig protocolConfig2 = new ProtocolConfig("dubbo", NetUtils.getAvailablePort()); - providerBootstrap2 = DubboBootstrap.newInstance(); + providerBootstrap2 = DubboBootstrap.newInstance(frameworkModel); providerBootstrap2.application("provider2") .registry(registryConfig2) .service(serviceConfig2) @@ -430,6 +431,7 @@ class MultiInstanceTest { String version2 = "2.0"; String version3 = "3.0"; + FrameworkModel frameworkModel = new FrameworkModel(); String serviceKey1 = DemoService.class.getName() + ":" + version1; String serviceKey2 = DemoService.class.getName() + ":" + version2; String serviceKey3 = DemoService.class.getName() + ":" + version3; @@ -439,7 +441,7 @@ class MultiInstanceTest { try { // provider app - providerBootstrap = DubboBootstrap.newInstance(); + providerBootstrap = DubboBootstrap.newInstance(frameworkModel); ServiceConfig serviceConfig1 = new ServiceConfig(); serviceConfig1.setInterface(DemoService.class); @@ -477,7 +479,7 @@ class MultiInstanceTest { Assertions.assertNull(frameworkServiceRepository.lookupExportedServiceWithoutGroup(serviceKey3)); // consumer module 1 - consumerBootstrap = DubboBootstrap.newInstance(); + consumerBootstrap = DubboBootstrap.newInstance(frameworkModel); consumerBootstrap.application("consumer-app") .registry(registryConfig) .reference(builder -> builder @@ -572,6 +574,7 @@ class MultiInstanceTest { String version2 = "2.0"; String version3 = "3.0"; + FrameworkModel frameworkModel = new FrameworkModel(); String serviceKey1 = DemoService.class.getName() + ":" + version1; String serviceKey2 = DemoService.class.getName() + ":" + version2; String serviceKey3 = DemoService.class.getName() + ":" + version3; @@ -579,7 +582,7 @@ class MultiInstanceTest { // provider app DubboBootstrap providerBootstrap = null; try { - providerBootstrap = DubboBootstrap.newInstance(); + providerBootstrap = DubboBootstrap.newInstance(frameworkModel); ServiceConfig serviceConfig1 = new ServiceConfig(); serviceConfig1.setInterface(DemoService.class); @@ -652,6 +655,7 @@ class MultiInstanceTest { String version2 = "2.0"; String version3 = "3.0"; + FrameworkModel frameworkModel = new FrameworkModel(); String serviceKey1 = DemoService.class.getName() + ":" + version1; String serviceKey2 = DemoService.class.getName() + ":" + version2; String serviceKey3 = DemoService.class.getName() + ":" + version3; @@ -659,7 +663,7 @@ class MultiInstanceTest { // provider app DubboBootstrap providerBootstrap = null; try { - providerBootstrap = DubboBootstrap.newInstance(); + providerBootstrap = DubboBootstrap.newInstance(frameworkModel); ServiceConfig serviceConfig1 = new ServiceConfig(); serviceConfig1.setInterface(DemoService.class); @@ -706,6 +710,7 @@ class MultiInstanceTest { @Test void testOldApiDeploy() throws Exception { + DubboBootstrap.reset(); try { // provider app ApplicationModel providerApplicationModel = ApplicationModel.defaultModel(); @@ -781,8 +786,10 @@ class MultiInstanceTest { @Test void testAsyncExportAndReferServices() throws ExecutionException, InterruptedException { - DubboBootstrap providerBootstrap = DubboBootstrap.newInstance(); - DubboBootstrap consumerBootstrap = DubboBootstrap.newInstance(); + FrameworkModel frameworkModel = new FrameworkModel(); + + DubboBootstrap providerBootstrap = DubboBootstrap.newInstance(frameworkModel); + DubboBootstrap consumerBootstrap = DubboBootstrap.newInstance(frameworkModel); try { ServiceConfig serviceConfig = new ServiceConfig(); diff --git a/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java index 5d78b94671..a6e503debe 100644 --- a/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java +++ b/dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java @@ -215,6 +215,16 @@ public class ApolloDynamicConfiguration implements DynamicConfiguration { return dubboConfig.getProperty(key, null); } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + Object v = dubboConfig.getProperty(key, null); + if (v != null) { + return v; + } else { + return defaultValue; + } + } + /** * Ignores the group parameter. * diff --git a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java index 2f43c85f27..bc95620220 100644 --- a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java +++ b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java @@ -220,6 +220,17 @@ public class NacosDynamicConfiguration implements DynamicConfiguration { return null; } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + Object v = defaultValue; + try { + v = configService.getConfig(key, DEFAULT_GROUP, getDefaultTimeout()); + } catch (NacosException e) { + logger.error(e.getMessage()); + } + return v; + } + @Override public boolean publishConfig(String key, String group, String content) { boolean published = false; diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java index 4836ed1b2f..4836012aa1 100644 --- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java +++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java @@ -85,6 +85,16 @@ public class ZookeeperDynamicConfiguration extends TreePathDynamicConfiguration return zkClient.getContent(buildPathKey("", key)); } + @Override + public Object getInternalProperty(String key, Object defaultValue) { + Object v = zkClient.getContent(buildPathKey("", key)); + if (v != null) { + return v; + } else { + return defaultValue; + } + } + @Override protected void doClose() throws Exception { // remove data listener diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java index 4814ce0acc..2e7dfd9d17 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java @@ -20,6 +20,7 @@ import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.threadpool.ThreadlessExecutor; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ConsumerMethodModel; import org.apache.dubbo.rpc.protocol.dubbo.FutureAdapter; @@ -66,11 +67,6 @@ public class AsyncRpcResult implements Result { private CompletableFuture responseFuture; - /** - * Whether set future to Thread Local when invocation mode is sync - */ - private static final boolean setFutureWhenSync = Boolean.parseBoolean(System.getProperty(CommonConstants.SET_FUTURE_IN_SYNC_MODE, "true")); - public AsyncRpcResult(CompletableFuture future, Invocation invocation) { this.responseFuture = future; this.invocation = invocation; @@ -216,7 +212,11 @@ public class AsyncRpcResult implements Result { fn.accept(v, t); }); - if (setFutureWhenSync || ((RpcInvocation) invocation).getInvokeMode() != InvokeMode.SYNC) { + // Whether set future to Thread Local when invocation mode is sync + String setFutureWhenSync = ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration() + .getString(CommonConstants.SET_FUTURE_IN_SYNC_MODE, "true"); + + if (Boolean.parseBoolean(setFutureWhenSync) || ((RpcInvocation) invocation).getInvokeMode() != InvokeMode.SYNC) { // Necessary! update future in context, see https://github.com/apache/dubbo/issues/9461 RpcContext.getServiceContext().setFuture(new FutureAdapter<>(this.responseFuture)); } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java index 3433fb4dc6..f9243c76df 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/AccessLogFilter.java @@ -81,7 +81,7 @@ public class AccessLogFilter implements Filter { private AtomicBoolean scheduled = new AtomicBoolean(); - private static final String LINE_SEPARATOR = "line.separator"; + private final String LINE_SEPARATOR = System.getProperty("line.separator"); /** * Default constructor initialize demon thread for writing into access log file with names with access log key @@ -173,7 +173,7 @@ public class AccessLogFilter implements Filter { try { while (!logQueue.isEmpty()) { writer.write(logQueue.poll().getLogMessage()); - writer.write(System.getProperty(LINE_SEPARATOR)); + writer.write(LINE_SEPARATOR); } } finally { writer.flush(); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java index ee04a1ded8..e8e5d28056 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java @@ -39,6 +39,7 @@ import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.protocol.dubbo.FutureAdapter; import org.apache.dubbo.rpc.support.RpcUtils; @@ -87,11 +88,6 @@ public abstract class AbstractInvoker implements Invoker { */ private boolean destroyed = false; - /** - * Whether set future to Thread Local when invocation mode is sync - */ - private static final boolean setFutureWhenSync = Boolean.parseBoolean(System.getProperty(CommonConstants.SET_FUTURE_IN_SYNC_MODE, "true")); - // -- Constructor public AbstractInvoker(Class type, URL url) { @@ -242,7 +238,11 @@ public abstract class AbstractInvoker implements Invoker { asyncResult = AsyncRpcResult.newDefaultAsyncResult(null, e, invocation); } - if (setFutureWhenSync || invocation.getInvokeMode() != InvokeMode.SYNC) { + // Whether set future to Thread Local when invocation mode is sync + String setFutureWhenSync = ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration() + .getString(CommonConstants.SET_FUTURE_IN_SYNC_MODE, "true"); + + if (Boolean.parseBoolean(setFutureWhenSync) || invocation.getInvokeMode() != InvokeMode.SYNC) { // set server context RpcContext.getServiceContext().setFuture(new FutureAdapter<>(asyncResult.getResponseFuture())); } diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java index c24bd27817..af997afe7d 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcInvocation.java @@ -17,6 +17,7 @@ package org.apache.dubbo.rpc.protocol.dubbo; +import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.serialize.Cleanable; @@ -37,6 +38,7 @@ import org.apache.dubbo.rpc.model.FrameworkServiceRepository; import org.apache.dubbo.rpc.model.MethodDescriptor; import org.apache.dubbo.rpc.model.ModuleModel; import org.apache.dubbo.rpc.model.ProviderModel; +import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.model.ServiceDescriptor; import org.apache.dubbo.rpc.support.RpcUtils; @@ -134,7 +136,17 @@ public class DecodeableRpcInvocation extends RpcInvocation implements Codec, Dec ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader(); try { - if (Boolean.parseBoolean(System.getProperty(SERIALIZATION_SECURITY_CHECK_KEY, "true"))) { + ScopeModel scopeModel = channel.getUrl().getScopeModel(); + if (scopeModel instanceof ModuleModel) { + scopeModel = scopeModel.getParent(); + } else { + scopeModel = ApplicationModel.defaultModel(); + } + String serializationSecurityCheck = ConfigurationUtils.getSystemConfiguration( + scopeModel).getString(SERIALIZATION_SECURITY_CHECK_KEY, "true"); + + + if (Boolean.parseBoolean(serializationSecurityCheck)) { CodecSupport.checkSerialization(frameworkModel.getServiceRepository(), path, version, serializationType); } Object[] args = DubboCodec.EMPTY_OBJECT_ARRAY; diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/decode/DubboTelnetDecodeTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/decode/DubboTelnetDecodeTest.java index f6f08ab3ec..254b99c4ee 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/decode/DubboTelnetDecodeTest.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/decode/DubboTelnetDecodeTest.java @@ -16,6 +16,9 @@ */ package org.apache.dubbo.rpc.protocol.dubbo.decode; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.embedded.EmbeddedChannel; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.common.url.component.ServiceConfigURL; @@ -38,10 +41,6 @@ import org.apache.dubbo.rpc.model.ModuleServiceRepository; import org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation; import org.apache.dubbo.rpc.protocol.dubbo.DubboCodec; import org.apache.dubbo.rpc.protocol.dubbo.support.DemoService; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.embedded.EmbeddedChannel; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -78,13 +77,13 @@ class DubboTelnetDecodeTest { // disable org.apache.dubbo.remoting.transport.CodecSupport.checkSerialization to avoid error: // java.io.IOException: Service org.apache.dubbo.rpc.protocol.dubbo.support.DemoService with version 0.0.0 not found, invocation rejected. - System.setProperty(SERIALIZATION_SECURITY_CHECK_KEY, "false"); + ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration().overwriteCache(SERIALIZATION_SECURITY_CHECK_KEY, "false"); } @AfterAll public static void teardown() { FrameworkModel.defaultModel().destroy(); - System.clearProperty(SERIALIZATION_SECURITY_CHECK_KEY); + ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration().clearCache(); } @@ -101,25 +100,26 @@ class DubboTelnetDecodeTest { try { Codec2 codec = ExtensionLoader.getExtensionLoader(Codec2.class).getExtension("dubbo"); URL url = new ServiceConfigURL("dubbo", "localhost", 22226); + url = url.setScopeModel(ApplicationModel.defaultModel().newModule()); NettyCodecAdapter adapter = new NettyCodecAdapter(codec, url, new MockChannelHandler()); MockHandler mockHandler = new MockHandler(null, - new MultiMessageHandler( - new DecodeHandler( - new HeaderExchangeHandler(new ExchangeHandlerAdapter() { - @Override - public CompletableFuture reply(ExchangeChannel channel, Object msg) { - if (checkDubboDecoded(msg)) { - dubbo.incrementAndGet(); - } - return getDefaultFuture(); - } - })))); + new MultiMessageHandler( + new DecodeHandler( + new HeaderExchangeHandler(new ExchangeHandlerAdapter() { + @Override + public CompletableFuture reply(ExchangeChannel channel, Object msg) { + if (checkDubboDecoded(msg)) { + dubbo.incrementAndGet(); + } + return getDefaultFuture(); + } + })))); ch = new LocalEmbeddedChannel(); ch.pipeline() - .addLast("decoder", adapter.getDecoder()) - .addLast("handler", mockHandler); + .addLast("decoder", adapter.getDecoder()) + .addLast("handler", mockHandler); ch.writeInbound(dubboByteBuf); } catch (Exception e) { @@ -148,6 +148,7 @@ class DubboTelnetDecodeTest { try { Codec2 codec = ExtensionLoader.getExtensionLoader(Codec2.class).getExtension("dubbo"); URL url = new ServiceConfigURL("dubbo", "localhost", 22226); + url = url.setScopeModel(ApplicationModel.defaultModel().newModule()); NettyCodecAdapter adapter = new NettyCodecAdapter(codec, url, new MockChannelHandler()); MockHandler mockHandler = new MockHandler((msg) -> { @@ -155,19 +156,19 @@ class DubboTelnetDecodeTest { telnet.incrementAndGet(); } }, - new MultiMessageHandler( - new DecodeHandler( - new HeaderExchangeHandler(new ExchangeHandlerAdapter() { - @Override - public CompletableFuture reply(ExchangeChannel channel, Object msg) { - return getDefaultFuture(); - } - })))); + new MultiMessageHandler( + new DecodeHandler( + new HeaderExchangeHandler(new ExchangeHandlerAdapter() { + @Override + public CompletableFuture reply(ExchangeChannel channel, Object msg) { + return getDefaultFuture(); + } + })))); ch = new LocalEmbeddedChannel(); ch.pipeline() - .addLast("decoder", adapter.getDecoder()) - .addLast("handler", mockHandler); + .addLast("decoder", adapter.getDecoder()) + .addLast("handler", mockHandler); ch.writeInbound(telnetByteBuf); } catch (Exception e) { @@ -192,13 +193,13 @@ class DubboTelnetDecodeTest { * | telnet(incomplete) | * +--------------------------------------------------+ *

- * + *

* Second ByteBuf: * +--------------------------++----------------------+ * | telnet(the remaining) || dubbo(complete) | * +--------------------------++----------------------+ - * || - * Magic Code + * || + * Magic Code * * @throws InterruptedException */ @@ -211,6 +212,7 @@ class DubboTelnetDecodeTest { try { Codec2 codec = ExtensionLoader.getExtensionLoader(Codec2.class).getExtension("dubbo"); URL url = new ServiceConfigURL("dubbo", "localhost", 22226); + url = url.setScopeModel(ApplicationModel.defaultModel().newModule()); NettyCodecAdapter adapter = new NettyCodecAdapter(codec, url, new MockChannelHandler()); MockHandler mockHandler = new MockHandler((msg) -> { @@ -218,23 +220,23 @@ class DubboTelnetDecodeTest { telnetDubbo.incrementAndGet(); } }, - new MultiMessageHandler( - new DecodeHandler( - new HeaderExchangeHandler(new ExchangeHandlerAdapter() { - @Override - public CompletableFuture reply(ExchangeChannel channel, Object msg) { - if (checkDubboDecoded(msg)) { - telnetDubbo.incrementAndGet(); - } + new MultiMessageHandler( + new DecodeHandler( + new HeaderExchangeHandler(new ExchangeHandlerAdapter() { + @Override + public CompletableFuture reply(ExchangeChannel channel, Object msg) { + if (checkDubboDecoded(msg)) { + telnetDubbo.incrementAndGet(); + } - return getDefaultFuture(); - } - })))); + return getDefaultFuture(); + } + })))); ch = new LocalEmbeddedChannel(); ch.pipeline() - .addLast("decoder", adapter.getDecoder()) - .addLast("handler", mockHandler); + .addLast("decoder", adapter.getDecoder()) + .addLast("handler", mockHandler); ch.writeInbound(telnetByteBuf); ch.writeInbound(Unpooled.wrappedBuffer(Unpooled.wrappedBuffer("\n".getBytes()), dubboByteBuf)); @@ -265,7 +267,7 @@ class DubboTelnetDecodeTest { * | telnet(incomplete) | * +--------------------------------------------------+ *

- * + *

* Second ByteBuf (secondByteBuf): * +--------------------------------------------------+ * | telnet(the remaining) | telnet(complete) | @@ -283,6 +285,7 @@ class DubboTelnetDecodeTest { try { Codec2 codec = ExtensionLoader.getExtensionLoader(Codec2.class).getExtension("dubbo"); URL url = new ServiceConfigURL("dubbo", "localhost", 22226); + url = url.setScopeModel(ApplicationModel.defaultModel().newModule()); NettyCodecAdapter adapter = new NettyCodecAdapter(codec, url, new MockChannelHandler()); MockHandler mockHandler = new MockHandler((msg) -> { @@ -290,19 +293,19 @@ class DubboTelnetDecodeTest { telnetTelnet.incrementAndGet(); } }, - new MultiMessageHandler( - new DecodeHandler( - new HeaderExchangeHandler(new ExchangeHandlerAdapter() { - @Override - public CompletableFuture reply(ExchangeChannel channel, Object msg) { - return getDefaultFuture(); - } - })))); + new MultiMessageHandler( + new DecodeHandler( + new HeaderExchangeHandler(new ExchangeHandlerAdapter() { + @Override + public CompletableFuture reply(ExchangeChannel channel, Object msg) { + return getDefaultFuture(); + } + })))); ch = new LocalEmbeddedChannel(); ch.pipeline() - .addLast("decoder", adapter.getDecoder()) - .addLast("handler", mockHandler); + .addLast("decoder", adapter.getDecoder()) + .addLast("handler", mockHandler); ch.writeInbound(firstByteBuf); ch.writeInbound(secondByteBuf); @@ -336,8 +339,8 @@ class DubboTelnetDecodeTest { * +-------------------------++-----------------------+ * | dubbo(the remaining) || dubbo(complete) | * +-------------------------++-----------------------+ - * || - * Magic Code + * || + * Magic Code * * @throws InterruptedException */ @@ -354,25 +357,26 @@ class DubboTelnetDecodeTest { try { Codec2 codec = ExtensionLoader.getExtensionLoader(Codec2.class).getExtension("dubbo"); URL url = new ServiceConfigURL("dubbo", "localhost", 22226); + url = url.setScopeModel(ApplicationModel.defaultModel().newModule()); NettyCodecAdapter adapter = new NettyCodecAdapter(codec, url, new MockChannelHandler()); MockHandler mockHandler = new MockHandler(null, - new MultiMessageHandler( - new DecodeHandler( - new HeaderExchangeHandler(new ExchangeHandlerAdapter() { - @Override - public CompletableFuture reply(ExchangeChannel channel, Object msg) { - if (checkDubboDecoded(msg)) { - dubboDubbo.incrementAndGet(); - } - return getDefaultFuture(); - } - })))); + new MultiMessageHandler( + new DecodeHandler( + new HeaderExchangeHandler(new ExchangeHandlerAdapter() { + @Override + public CompletableFuture reply(ExchangeChannel channel, Object msg) { + if (checkDubboDecoded(msg)) { + dubboDubbo.incrementAndGet(); + } + return getDefaultFuture(); + } + })))); ch = new LocalEmbeddedChannel(); ch.pipeline() - .addLast("decoder", adapter.getDecoder()) - .addLast("handler", mockHandler); + .addLast("decoder", adapter.getDecoder()) + .addLast("handler", mockHandler); ch.writeInbound(firstDubboByteBuf); ch.writeInbound(secondDubboByteBuf); @@ -421,6 +425,7 @@ class DubboTelnetDecodeTest { try { Codec2 codec = ExtensionLoader.getExtensionLoader(Codec2.class).getExtension("dubbo"); URL url = new ServiceConfigURL("dubbo", "localhost", 22226); + url = url.setScopeModel(ApplicationModel.defaultModel().newModule()); NettyCodecAdapter adapter = new NettyCodecAdapter(codec, url, new MockChannelHandler()); MockHandler mockHandler = new MockHandler((msg) -> { @@ -428,22 +433,22 @@ class DubboTelnetDecodeTest { dubboTelnet.incrementAndGet(); } }, - new MultiMessageHandler( - new DecodeHandler( - new HeaderExchangeHandler(new ExchangeHandlerAdapter() { - @Override - public CompletableFuture reply(ExchangeChannel channel, Object msg) { - if (checkDubboDecoded(msg)) { - dubboTelnet.incrementAndGet(); - } - return getDefaultFuture(); - } - })))); + new MultiMessageHandler( + new DecodeHandler( + new HeaderExchangeHandler(new ExchangeHandlerAdapter() { + @Override + public CompletableFuture reply(ExchangeChannel channel, Object msg) { + if (checkDubboDecoded(msg)) { + dubboTelnet.incrementAndGet(); + } + return getDefaultFuture(); + } + })))); ch = new LocalEmbeddedChannel(); ch.pipeline() - .addLast("decoder", adapter.getDecoder()) - .addLast("handler", mockHandler); + .addLast("decoder", adapter.getDecoder()) + .addLast("handler", mockHandler); ch.writeInbound(firstDubboByteBuf); ch.writeInbound(secondByteBuf); @@ -496,13 +501,13 @@ class DubboTelnetDecodeTest { if (msg instanceof DecodeableRpcInvocation) { DecodeableRpcInvocation invocation = (DecodeableRpcInvocation) msg; if ("sayHello".equals(invocation.getMethodName()) - && invocation.getParameterTypes().length == 1 - && String.class.equals(invocation.getParameterTypes()[0]) - && invocation.getArguments().length == 1 - && "dubbo".equals(invocation.getArguments()[0]) - && DemoService.class.getName().equals(invocation.getAttachment("path")) - && DemoService.class.getName().equals(invocation.getAttachment("interface")) - && "0.0.0".equals(invocation.getAttachment("version"))) { + && invocation.getParameterTypes().length == 1 + && String.class.equals(invocation.getParameterTypes()[0]) + && invocation.getArguments().length == 1 + && "dubbo".equals(invocation.getArguments()[0]) + && DemoService.class.getName().equals(invocation.getAttachment("path")) + && DemoService.class.getName().equals(invocation.getAttachment("interface")) + && "0.0.0".equals(invocation.getAttachment("version"))) { return true; } } diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/DefaultHessian2FactoryInitializer.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/DefaultHessian2FactoryInitializer.java index cca8697030..ce0baccd02 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/DefaultHessian2FactoryInitializer.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/DefaultHessian2FactoryInitializer.java @@ -24,7 +24,7 @@ public class DefaultHessian2FactoryInitializer extends AbstractHessian2FactoryIn @Override protected SerializerFactory createSerializerFactory() { Hessian2SerializerFactory hessian2SerializerFactory = new Hessian2SerializerFactory(); - hessian2SerializerFactory.setAllowNonSerializable(Boolean.parseBoolean(System.getProperty("dubbo.hessian.allowNonSerializable", "false"))); + hessian2SerializerFactory.setAllowNonSerializable(Boolean.parseBoolean(ALLOW_NON_SERIALIZABLE)); hessian2SerializerFactory.getClassFactory().allow("org.apache.dubbo.*"); return hessian2SerializerFactory; } diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/Hessian2FactoryInitializer.java b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/Hessian2FactoryInitializer.java index 842888cf1b..2095587b4e 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/Hessian2FactoryInitializer.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/dubbo/Hessian2FactoryInitializer.java @@ -27,7 +27,9 @@ import com.alibaba.com.caucho.hessian.io.SerializerFactory; @SPI(value = "default", scope = ExtensionScope.FRAMEWORK) public interface Hessian2FactoryInitializer { String ALLOW = System.getProperty("dubbo.application.hessian2.allow"); + String DENY = System.getProperty("dubbo.application.hessian2.deny"); + String WHITELIST = System.getProperty("dubbo.application.hessian2.whitelist"); String ALLOW_NON_SERIALIZABLE = System.getProperty("dubbo.hessian.allowNonSerializable", "false"); From a795ff73dff7318c564a3d38a19be97b92ce496a Mon Sep 17 00:00:00 2001 From: huazhongming Date: Tue, 6 Dec 2022 15:45:45 +0800 Subject: [PATCH 08/10] Get system properties from context (#11082) --- .../src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java | 3 +-- .../java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java index 2e7dfd9d17..afd8d86837 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java @@ -20,7 +20,6 @@ import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.threadpool.ThreadlessExecutor; -import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ConsumerMethodModel; import org.apache.dubbo.rpc.protocol.dubbo.FutureAdapter; @@ -213,7 +212,7 @@ public class AsyncRpcResult implements Result { }); // Whether set future to Thread Local when invocation mode is sync - String setFutureWhenSync = ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration() + String setFutureWhenSync = invocation.getModuleModel().getModelEnvironment().getSystemConfiguration() .getString(CommonConstants.SET_FUTURE_IN_SYNC_MODE, "true"); if (Boolean.parseBoolean(setFutureWhenSync) || ((RpcInvocation) invocation).getInvokeMode() != InvokeMode.SYNC) { diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java index e8e5d28056..fe668d65b9 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java @@ -39,7 +39,6 @@ import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.protocol.dubbo.FutureAdapter; import org.apache.dubbo.rpc.support.RpcUtils; @@ -239,7 +238,7 @@ public abstract class AbstractInvoker implements Invoker { } // Whether set future to Thread Local when invocation mode is sync - String setFutureWhenSync = ApplicationModel.defaultModel().getModelEnvironment().getSystemConfiguration() + String setFutureWhenSync = invocation.getModuleModel().getModelEnvironment().getSystemConfiguration() .getString(CommonConstants.SET_FUTURE_IN_SYNC_MODE, "true"); if (Boolean.parseBoolean(setFutureWhenSync) || invocation.getInvokeMode() != InvokeMode.SYNC) { From 7cccc4f193f36b4ff8fa2e4b77671e65dba32b7a Mon Sep 17 00:00:00 2001 From: earthchen Date: Wed, 7 Dec 2022 20:11:15 +0800 Subject: [PATCH 09/10] opt some tri code (#11079) * opt some code * remove unused if * fix npe --- .../tri/stream/TripleServerStream.java | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleServerStream.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleServerStream.java index f289bb1706..33a17c6283 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleServerStream.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleServerStream.java @@ -371,14 +371,6 @@ public class TripleServerStream extends AbstractStream implements ServerStream { } } - try { - final TriDecoder.Listener listener = new ServerDecoderListener(); - deframer = new TriDecoder(deCompressor, listener); - } catch (Throwable t) { - responseErr(TriRpcStatus.INTERNAL.withCause(t)); - return; - } - Map requestMetadata = headersToMap(headers); boolean hasStub = pathResolver.hasNativeStub(path); if (hasStub) { @@ -390,10 +382,9 @@ public class TripleServerStream extends AbstractStream implements ServerStream { frameworkModel, acceptEncoding, serviceName, originalMethodName, filters, executor); } + // must before onHeader + deframer = new TriDecoder(deCompressor, new ServerDecoderListener(listener)); listener.onHeader(requestMetadata); - if (listener == null) { - deframer.close(); - } } @@ -427,21 +418,27 @@ public class TripleServerStream extends AbstractStream implements ServerStream { .withDescription("Canceled by client ,errorCode=" + errorCode)); }); } + } - private class ServerDecoderListener implements TriDecoder.Listener { - @Override - public void onRawMessage(byte[] data) { - listener.onMessage(data); - } + private static class ServerDecoderListener implements TriDecoder.Listener { - @Override - public void close() { - if (listener != null) { - listener.onComplete(); - } - } + private final ServerStream.Listener listener; + + public ServerDecoderListener(ServerStream.Listener listener) { + this.listener = listener; + } + + @Override + public void onRawMessage(byte[] data) { + listener.onMessage(data); + } + + @Override + public void close() { + listener.onComplete(); } } + } From 9713ad64b3914d45847905cfec7e38d849fdf18d Mon Sep 17 00:00:00 2001 From: huazhongming Date: Thu, 8 Dec 2022 16:04:28 +0800 Subject: [PATCH 10/10] fix ssl npe (#11093) --- .../transport/netty4/NettyPortUnificationServerHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServerHandler.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServerHandler.java index 3d22ce7a03..338f3572d1 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServerHandler.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyPortUnificationServerHandler.java @@ -138,7 +138,9 @@ public class NettyPortUnificationServerHandler extends ByteToMessageDecoder { private void enableSsl(ChannelHandlerContext ctx) { ChannelPipeline p = ctx.pipeline(); - p.addLast("ssl", sslCtx.newHandler(ctx.alloc())); + if (sslCtx != null) { + p.addLast("ssl", sslCtx.newHandler(ctx.alloc())); + } p.addLast("unificationA", new NettyPortUnificationServerHandler(url, sslCtx, false, protocols, handler, dubboChannels, urlMapper, handlerMapper));