From b5bb04496c8becd750614cc15e2b1fc5077a5104 Mon Sep 17 00:00:00 2001 From: TomlongTK Date: Thu, 23 May 2024 11:15:06 +0800 Subject: [PATCH] Add TripleConfig to ProtocolConfig as nest configuration (#14077) * Add TripleConfig to ProtocolConfig as nest configuration * Fix compile issue * Use default protocol config * Format code * Handle the situation where ProtocolConfig is not set * Follow the old rules and fix some sonar issues * Add checkDefault method * Refresh when uninitialized * Remove needRefresh --------- Co-authored-by: earthchen --- .../apache/dubbo/config/ProtocolConfig.java | 18 ++ .../org/apache/dubbo/config/TripleConfig.java | 118 --------- .../config/context/AbstractConfigManager.java | 20 +- .../dubbo/config/context/ConfigManager.java | 15 ++ .../dubbo/config/nested/TripleConfig.java | 237 ++++++++++++++++++ .../bootstrap/builders/TripleBuilder.java | 212 ++++++++++++++++ .../dubbo/config/ProtocolConfigTest.java | 80 ++++-- .../config/bootstrap/DubboBootstrapTest.java | 46 ++++ .../bootstrap/builders/TripleBuilderTest.java | 143 +++++++++++ .../src/main/resources/META-INF/dubbo.xsd | 86 +++++++ .../java/org/apache/dubbo/rpc/Constants.java | 6 - .../tri/TriHttp2RemoteFlowController.java | 74 +++--- .../rpc/protocol/tri/TripleHttp2Protocol.java | 80 +++--- .../rpc/protocol/tri/ExceptionUtilsTest.java | 1 - .../DubboConfigurationProperties.java | 2 +- 15 files changed, 886 insertions(+), 252 deletions(-) delete mode 100644 dubbo-common/src/main/java/org/apache/dubbo/config/TripleConfig.java create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/config/nested/TripleConfig.java create mode 100644 dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/TripleBuilder.java create mode 100644 dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/TripleBuilderTest.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java index 1d0b5918a06..a66e57390bd 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ProtocolConfig.java @@ -19,6 +19,8 @@ import org.apache.dubbo.common.serialization.PreferSerializationProvider; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.config.nested.TripleConfig; +import org.apache.dubbo.config.support.Nested; import org.apache.dubbo.config.support.Parameter; import org.apache.dubbo.rpc.model.ApplicationModel; @@ -236,6 +238,9 @@ public class ProtocolConfig extends AbstractConfig { */ private String jsonCheckLevel; + @Nested + private TripleConfig triple; + public ProtocolConfig() {} public ProtocolConfig(ApplicationModel applicationModel) { @@ -277,6 +282,11 @@ protected void checkDefault() { .getBean(PreferSerializationProvider.class) .getPreferSerialization(); } + + if (triple == null) { + triple = new TripleConfig(); + } + triple.checkDefault(); } @Parameter(excluded = true) @@ -621,6 +631,14 @@ public void setExtProtocol(String extProtocol) { this.extProtocol = extProtocol; } + public TripleConfig getTriple() { + return triple; + } + + public void setTriple(TripleConfig triple) { + this.triple = triple; + } + public void mergeProtocol(ProtocolConfig sourceConfig) { if (sourceConfig == null) { return; diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/TripleConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/TripleConfig.java deleted file mode 100644 index 1b7469ee21a..00000000000 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/TripleConfig.java +++ /dev/null @@ -1,118 +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.config; - -import java.io.Serializable; - -/** - * Configuration for triple protocol. - */ -public class TripleConfig implements Serializable { - - private static final long serialVersionUID = -3682252713701362155L; - - /** - * The header table size. - */ - private String headerTableSize; - - /** - * Whether to enable push, default is false. - */ - private Boolean enablePush; - - /** - * Maximum concurrent streams. - */ - private String maxConcurrentStreams; - - /** - * Initial window size. - */ - private String initialWindowSize; - - /** - * Maximum frame size. - */ - private String maxFrameSize; - - /** - * Maximum header list size. - */ - private String maxHeaderListSize; - - /** - * Whether to pass through standard HTTP headers, default is false. - */ - private Boolean passThroughStandardHttpHeaders; - - public String getHeaderTableSize() { - return headerTableSize; - } - - public void setHeaderTableSize(String headerTableSize) { - this.headerTableSize = headerTableSize; - } - - public Boolean getEnablePush() { - return enablePush; - } - - public void setEnablePush(Boolean enablePush) { - this.enablePush = enablePush; - } - - public String getMaxConcurrentStreams() { - return maxConcurrentStreams; - } - - public void setMaxConcurrentStreams(String maxConcurrentStreams) { - this.maxConcurrentStreams = maxConcurrentStreams; - } - - public String getInitialWindowSize() { - return initialWindowSize; - } - - public void setInitialWindowSize(String initialWindowSize) { - this.initialWindowSize = initialWindowSize; - } - - public String getMaxFrameSize() { - return maxFrameSize; - } - - public void setMaxFrameSize(String maxFrameSize) { - this.maxFrameSize = maxFrameSize; - } - - public String getMaxHeaderListSize() { - return maxHeaderListSize; - } - - public void setMaxHeaderListSize(String maxHeaderListSize) { - this.maxHeaderListSize = maxHeaderListSize; - } - - public Boolean getPassThroughStandardHttpHeaders() { - return passThroughStandardHttpHeaders; - } - - public void setPassThroughStandardHttpHeaders(Boolean passThroughStandardHttpHeaders) { - this.passThroughStandardHttpHeaders = passThroughStandardHttpHeaders; - } -} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java index 5a15b14ac2f..7fb8ff07f73 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/AbstractConfigManager.java @@ -419,7 +419,7 @@ static List getDefaultConfigs(Map confi List list = configsMap.values().stream() .filter(c -> TRUE.equals(AbstractConfigManager.isDefaultConfig(c))) .collect(Collectors.toList()); - if (list.size() > 0) { + if (!list.isEmpty()) { return list; } @@ -635,10 +635,7 @@ protected void checkDefaultAndValidateConfigs(Class boolean isNeedValidation(T config) { - if (config instanceof MetadataReportConfig) { - return false; - } - return true; + return !(config instanceof MetadataReportConfig); } private ConfigValidator getConfigValidator() { @@ -656,14 +653,11 @@ private ConfigValidator getConfigValidator() { * @return */ protected boolean isRequired(Class clazz) { - if (clazz == RegistryConfig.class - || clazz == MetadataReportConfig.class - || clazz == MonitorConfig.class - || clazz == MetricsConfig.class - || clazz == TracingConfig.class) { - return false; - } - return true; + return clazz != RegistryConfig.class + && clazz != MetadataReportConfig.class + && clazz != MonitorConfig.class + && clazz != MetricsConfig.class + && clazz != TracingConfig.class; } private boolean shouldAddDefaultConfig(Class clazz) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java index 58d7abf7cbc..e49bf560bf6 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java @@ -197,6 +197,21 @@ public Optional getProtocol(String idOrName) { return getConfig(ProtocolConfig.class, idOrName); } + public ProtocolConfig getOrAddProtocol(String idOrName) { + Optional protocol = getProtocol(idOrName); + if (protocol.isPresent()) { + return protocol.get(); + } + ProtocolConfig protocolConfig = new ProtocolConfig(idOrName); + addProtocol(protocolConfig); + // addProtocol triggers refresh when other protocols exist in the ConfigManager. + // So refresh is only done when ProtocolConfig is not refreshed. + if (!protocolConfig.isRefreshed()) { + protocolConfig.refresh(); + } + return protocolConfig; + } + public List getDefaultProtocols() { return getDefaultConfigs(ProtocolConfig.class); } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/TripleConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/TripleConfig.java new file mode 100644 index 00000000000..0edaf61c367 --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/TripleConfig.java @@ -0,0 +1,237 @@ +/* + * 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.config.nested; + +import java.io.Serializable; + +/** + * Configuration for triple protocol. + */ +public class TripleConfig implements Serializable { + + private static final long serialVersionUID = -3682252713701362155L; + + /** + * Maximum allowed size for HTTP1 request bodies. + * Limits the size of request to prevent excessively large request. + *

The default value is 8MiB. + */ + private Integer maxBodySize; + + /** + * Maximum allowed size for HTTP1 response bodies. + * Limits the size of responses to prevent excessively large response. + *

The default value is 8MiB. + */ + private Integer maxResponseBodySize; + + /** + * Set the maximum chunk size. + * HTTP requests and responses can be quite large, in which case it's better to process the data as a stream of + * chunks. + * This sets the limit, in bytes, at which Netty will send a chunk down the pipeline. + *

The default value is 8MiB. + */ + private Integer maxChunkSize; + + /** + * Set the maximum line length of header lines. + * This limits how much memory Netty will use when parsing HTTP header key-value pairs. + * You would typically set this to the same value as {@link #setMaxInitialLineLength(Integer)}. + *

The default value is 8KiB. + */ + private Integer maxHeaderSize; + + /** + * Set the maximum length of the first line of the HTTP header. + * This limits how much memory Netty will use when parsed the initial HTTP header line. + * You would typically set this to the same value as {@link #setMaxHeaderSize(Integer)}. + *

The default value is 4096. + */ + private Integer maxInitialLineLength; + + /** + * Set the initial size of the temporary buffer used when parsing the lines of the HTTP headers. + *

The default value is 16384 octets. + */ + private Integer initialBufferSize; + + /** + * The header table size. + */ + private Integer headerTableSize; + + /** + * Whether to enable push, default is false. + */ + private Boolean enablePush; + + /** + * Maximum concurrent streams. + */ + private Integer maxConcurrentStreams; + + /** + * Initial window size. + */ + private Integer initialWindowSize; + + /** + * Maximum frame size. + */ + private Integer maxFrameSize; + + /** + * Maximum header list size. + */ + private Integer maxHeaderListSize; + + public Integer getMaxBodySize() { + return maxBodySize; + } + + public void setMaxBodySize(Integer maxBodySize) { + this.maxBodySize = maxBodySize; + } + + public Integer getMaxResponseBodySize() { + return maxResponseBodySize; + } + + public void setMaxResponseBodySize(Integer maxResponseBodySize) { + this.maxResponseBodySize = maxResponseBodySize; + } + + public Integer getMaxChunkSize() { + return maxChunkSize; + } + + public void setMaxChunkSize(Integer maxChunkSize) { + this.maxChunkSize = maxChunkSize; + } + + public Integer getMaxHeaderSize() { + return maxHeaderSize; + } + + public void setMaxHeaderSize(Integer maxHeaderSize) { + this.maxHeaderSize = maxHeaderSize; + } + + public Integer getMaxInitialLineLength() { + return maxInitialLineLength; + } + + public void setMaxInitialLineLength(Integer maxInitialLineLength) { + this.maxInitialLineLength = maxInitialLineLength; + } + + public Integer getInitialBufferSize() { + return initialBufferSize; + } + + public void setInitialBufferSize(Integer initialBufferSize) { + this.initialBufferSize = initialBufferSize; + } + + public Integer getHeaderTableSize() { + return headerTableSize; + } + + public void setHeaderTableSize(Integer headerTableSize) { + this.headerTableSize = headerTableSize; + } + + public Boolean getEnablePush() { + return enablePush; + } + + public void setEnablePush(Boolean enablePush) { + this.enablePush = enablePush; + } + + public Integer getMaxConcurrentStreams() { + return maxConcurrentStreams; + } + + public void setMaxConcurrentStreams(Integer maxConcurrentStreams) { + this.maxConcurrentStreams = maxConcurrentStreams; + } + + public Integer getInitialWindowSize() { + return initialWindowSize; + } + + public void setInitialWindowSize(Integer initialWindowSize) { + this.initialWindowSize = initialWindowSize; + } + + public Integer getMaxFrameSize() { + return maxFrameSize; + } + + public void setMaxFrameSize(Integer maxFrameSize) { + this.maxFrameSize = maxFrameSize; + } + + public Integer getMaxHeaderListSize() { + return maxHeaderListSize; + } + + public void setMaxHeaderListSize(Integer maxHeaderListSize) { + this.maxHeaderListSize = maxHeaderListSize; + } + + public void checkDefault() { + if (maxBodySize == null) { + maxBodySize = 1 << 23; + } + if (maxResponseBodySize == null) { + maxResponseBodySize = 1 << 23; + } + if (maxChunkSize == null) { + maxChunkSize = 1 << 23; + } + if (maxHeaderSize == null) { + maxHeaderSize = 8192; + } + if (maxInitialLineLength == null) { + maxInitialLineLength = 4096; + } + if (initialBufferSize == null) { + initialBufferSize = 16384; + } + if (headerTableSize == null) { + headerTableSize = 4096; + } + if (enablePush == null) { + enablePush = false; + } + if (maxConcurrentStreams == null) { + maxConcurrentStreams = Integer.MAX_VALUE; + } + if (initialWindowSize == null) { + initialWindowSize = 1 << 23; + } + if (maxFrameSize == null) { + maxFrameSize = 1 << 23; + } + if (maxHeaderListSize == null) { + maxHeaderListSize = 1 << 15; + } + } +} diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/TripleBuilder.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/TripleBuilder.java new file mode 100644 index 00000000000..4e0b553ecf2 --- /dev/null +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/builders/TripleBuilder.java @@ -0,0 +1,212 @@ +/* + * 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.config.bootstrap.builders; + +import org.apache.dubbo.config.nested.TripleConfig; + +/** + * This is a builder for build {@link TripleConfig}. + * + * @since 3.3 + */ +public class TripleBuilder { + + /** + * Maximum allowed size for HTTP1 request bodies. + * Limits the size of request to prevent excessively large request. + *

The default value is 8MiB. + */ + private Integer maxBodySize; + + /** + * Maximum allowed size for HTTP1 response bodies. + * Limits the size of responses to prevent excessively large response. + *

The default value is 8MiB. + */ + private Integer maxResponseBodySize; + + /** + * Set the maximum chunk size. + * HTTP requests and responses can be quite large, in which case it's better to process the data as a stream of + * chunks. + * This sets the limit, in bytes, at which Netty will send a chunk down the pipeline. + *

The default value is 8KiB. + */ + private Integer maxChunkSize; + + /** + * Set the maximum line length of header lines. + * This limits how much memory Netty will use when parsing HTTP header key-value pairs. + * You would typically set this to the same value as {@link #maxInitialLineLength(Integer)}. + *

The default value is 8KiB. + */ + private Integer maxHeaderSize; + + /** + * Set the maximum length of the first line of the HTTP header. + * This limits how much memory Netty will use when parsed the initial HTTP header line. + * You would typically set this to the same value as {@link #maxHeaderSize(Integer)}. + *

The default value is 4096. + */ + private Integer maxInitialLineLength; + + /** + * Set the initial size of the temporary buffer used when parsing the lines of the HTTP headers. + *

The default value is 128 octets. + */ + private Integer initialBufferSize; + + /** + * The header table size. + */ + private Integer headerTableSize; + + /** + * Whether to enable push, default is false. + */ + private Boolean enablePush; + + /** + * Maximum concurrent streams. + */ + private Integer maxConcurrentStreams; + + /** + * Initial window size. + */ + private Integer initialWindowSize; + + /** + * Maximum frame size. + */ + private Integer maxFrameSize; + + /** + * Maximum header list size. + */ + private Integer maxHeaderListSize; + + public static TripleBuilder newBuilder() { + return new TripleBuilder(); + } + + public TripleBuilder maxBodySize(Integer maxBodySize) { + this.maxBodySize = maxBodySize; + return getThis(); + } + + public TripleBuilder maxResponseBodySize(Integer maxResponseBodySize) { + this.maxResponseBodySize = maxResponseBodySize; + return getThis(); + } + + public TripleBuilder maxChunkSize(Integer maxChunkSize) { + this.maxChunkSize = maxChunkSize; + return getThis(); + } + + public TripleBuilder maxHeaderSize(Integer maxHeaderSize) { + this.maxHeaderSize = maxHeaderSize; + return getThis(); + } + + public TripleBuilder maxInitialLineLength(Integer maxInitialLineLength) { + this.maxInitialLineLength = maxInitialLineLength; + return getThis(); + } + + public TripleBuilder initialBufferSize(Integer initialBufferSize) { + this.initialBufferSize = initialBufferSize; + return getThis(); + } + + public TripleBuilder headerTableSize(Integer headerTableSize) { + this.headerTableSize = headerTableSize; + return getThis(); + } + + public TripleBuilder enablePush(Boolean enablePush) { + this.enablePush = enablePush; + return getThis(); + } + + public TripleBuilder maxConcurrentStreams(Integer maxConcurrentStreams) { + this.maxConcurrentStreams = maxConcurrentStreams; + return getThis(); + } + + public TripleBuilder initialWindowSize(Integer initialWindowSize) { + this.initialWindowSize = initialWindowSize; + return getThis(); + } + + public TripleBuilder maxFrameSize(Integer maxFrameSize) { + this.maxFrameSize = maxFrameSize; + return getThis(); + } + + public TripleBuilder maxHeaderListSize(Integer maxHeaderListSize) { + this.maxHeaderListSize = maxHeaderListSize; + return getThis(); + } + + protected TripleBuilder getThis() { + return this; + } + + public TripleConfig build() { + TripleConfig triple = new TripleConfig(); + + if (maxBodySize != null) { + triple.setMaxBodySize(maxBodySize); + } + if (maxResponseBodySize != null) { + triple.setMaxResponseBodySize(maxResponseBodySize); + } + if (maxChunkSize != null) { + triple.setMaxChunkSize(maxChunkSize); + } + if (maxHeaderSize != null) { + triple.setMaxHeaderSize(maxHeaderSize); + } + if (maxInitialLineLength != null) { + triple.setMaxInitialLineLength(maxInitialLineLength); + } + if (initialBufferSize != null) { + triple.setInitialBufferSize(initialBufferSize); + } + if (headerTableSize != null) { + triple.setHeaderTableSize(headerTableSize); + } + if (enablePush != null) { + triple.setEnablePush(enablePush); + } + if (maxConcurrentStreams != null) { + triple.setMaxConcurrentStreams(maxConcurrentStreams); + } + if (initialWindowSize != null) { + triple.setInitialWindowSize(initialWindowSize); + } + if (maxFrameSize != null) { + triple.setMaxFrameSize(maxFrameSize); + } + if (maxHeaderListSize != null) { + triple.setMaxHeaderListSize(maxHeaderListSize); + } + return triple; + } +} diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java index c10c8eefc25..ef198ebf6c7 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ProtocolConfigTest.java @@ -35,6 +35,8 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; class ProtocolConfigTest { @@ -56,11 +58,35 @@ public static void afterAll() { } @Test - void testName() throws Exception { + void testDefaultTripleConfig() { + ProtocolConfig protocol = new ProtocolConfig(); + protocol.refresh(); + Map parameters = new HashMap<>(); + ProtocolConfig.appendParameters(parameters, protocol); + assertThat(parameters.isEmpty(), is(false)); + // http2 default config + assertEquals(4096, Integer.parseInt(parameters.get("triple.header.table.size"))); + assertFalse(Boolean.parseBoolean(parameters.get("triple.enable.push"))); + assertEquals(Integer.MAX_VALUE, Integer.parseInt(parameters.get("triple.max.concurrent.streams"))); + assertEquals(1 << 23, Integer.parseInt(parameters.get("triple.initial.window.size"))); + assertEquals(1 << 23, Integer.parseInt(parameters.get("triple.max.frame.size"))); + assertEquals(1 << 15, Integer.parseInt(parameters.get("triple.max.header.list.size"))); + + // http1 default config + assertEquals(1 << 23, Integer.parseInt(parameters.get("triple.max.body.size"))); + assertEquals(1 << 23, Integer.parseInt(parameters.get("triple.max.response.body.size"))); + assertEquals(1 << 23, Integer.parseInt(parameters.get("triple.max.chunk.size"))); + assertEquals(8192, Integer.parseInt(parameters.get("triple.max.header.size"))); + assertEquals(4096, Integer.parseInt(parameters.get("triple.max.initial.line.length"))); + assertEquals(16384, Integer.parseInt(parameters.get("triple.initial.buffer.size"))); + } + + @Test + void testName() { ProtocolConfig protocol = new ProtocolConfig(); String protocolName = "xprotocol"; protocol.setName(protocolName); - Map parameters = new HashMap(); + Map parameters = new HashMap<>(); ProtocolConfig.appendParameters(parameters, protocol); assertThat(protocol.getName(), equalTo(protocolName)); assertThat(protocol.getId(), equalTo(null)); @@ -68,7 +94,7 @@ void testName() throws Exception { } @Test - void testHost() throws Exception { + void testHost() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setHost("host"); Map parameters = new HashMap(); @@ -78,21 +104,21 @@ void testHost() throws Exception { } @Test - void testPort() throws Exception { + void testPort() { ProtocolConfig protocol = new ProtocolConfig(); int port = NetUtils.getAvailablePort(); protocol.setPort(port); - Map parameters = new HashMap(); + Map parameters = new HashMap<>(); ProtocolConfig.appendParameters(parameters, protocol); assertThat(protocol.getPort(), equalTo(port)); assertThat(parameters.isEmpty(), is(true)); } @Test - void testPath() throws Exception { + void testPath() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setContextpath("context-path"); - Map parameters = new HashMap(); + Map parameters = new HashMap<>(); ProtocolConfig.appendParameters(parameters, protocol); assertThat(protocol.getPath(), equalTo("context-path")); assertThat(protocol.getContextpath(), equalTo("context-path")); @@ -103,42 +129,42 @@ void testPath() throws Exception { } @Test - void testCorethreads() throws Exception { + void testCorethreads() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setCorethreads(10); assertThat(protocol.getCorethreads(), is(10)); } @Test - void testThreads() throws Exception { + void testThreads() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setThreads(10); assertThat(protocol.getThreads(), is(10)); } @Test - void testIothreads() throws Exception { + void testIothreads() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setIothreads(10); assertThat(protocol.getIothreads(), is(10)); } @Test - void testQueues() throws Exception { + void testQueues() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setQueues(10); assertThat(protocol.getQueues(), is(10)); } @Test - void testAccepts() throws Exception { + void testAccepts() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setAccepts(10); assertThat(protocol.getAccepts(), is(10)); } @Test - void testCodec() throws Exception { + void testCodec() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setName("dubbo"); protocol.setCodec("mockcodec"); @@ -146,84 +172,84 @@ void testCodec() throws Exception { } @Test - void testAccesslog() throws Exception { + void testAccesslog() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setAccesslog("access.log"); assertThat(protocol.getAccesslog(), equalTo("access.log")); } @Test - void testTelnet() throws Exception { + void testTelnet() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setTelnet("mocktelnethandler"); assertThat(protocol.getTelnet(), equalTo("mocktelnethandler")); } @Test - void testRegister() throws Exception { + void testRegister() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setRegister(true); assertThat(protocol.isRegister(), is(true)); } @Test - void testTransporter() throws Exception { + void testTransporter() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setTransporter("mocktransporter"); assertThat(protocol.getTransporter(), equalTo("mocktransporter")); } @Test - void testExchanger() throws Exception { + void testExchanger() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setExchanger("mockexchanger"); assertThat(protocol.getExchanger(), equalTo("mockexchanger")); } @Test - void testDispatcher() throws Exception { + void testDispatcher() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setDispatcher("mockdispatcher"); assertThat(protocol.getDispatcher(), equalTo("mockdispatcher")); } @Test - void testNetworker() throws Exception { + void testNetworker() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setNetworker("networker"); assertThat(protocol.getNetworker(), equalTo("networker")); } @Test - void testParameters() throws Exception { + void testParameters() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setParameters(Collections.singletonMap("k1", "v1")); assertThat(protocol.getParameters(), hasEntry("k1", "v1")); } @Test - void testDefault() throws Exception { + void testDefault() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setDefault(true); assertThat(protocol.isDefault(), is(true)); } @Test - void testKeepAlive() throws Exception { + void testKeepAlive() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setKeepAlive(true); assertThat(protocol.getKeepAlive(), is(true)); } @Test - void testOptimizer() throws Exception { + void testOptimizer() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setOptimizer("optimizer"); assertThat(protocol.getOptimizer(), equalTo("optimizer")); } @Test - void testExtension() throws Exception { + void testExtension() { ProtocolConfig protocol = new ProtocolConfig(); protocol.setExtension("extension"); assertThat(protocol.getExtension(), equalTo("extension")); @@ -384,7 +410,7 @@ void testCreateDefaultConfigFromProps() { } @Test - void testPreferSerializationDefault1() throws Exception { + void testPreferSerializationDefault1() { ProtocolConfig protocolConfig = new ProtocolConfig(); assertNull(protocolConfig.getPreferSerialization()); @@ -400,7 +426,7 @@ void testPreferSerializationDefault1() throws Exception { } @Test - void testPreferSerializationDefault2() throws Exception { + void testPreferSerializationDefault2() { ProtocolConfig protocolConfig = new ProtocolConfig(); assertNull(protocolConfig.getPreferSerialization()); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java index 79aeb132ae2..d46740eb95c 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java @@ -35,6 +35,7 @@ import org.apache.dubbo.config.deploy.DefaultApplicationDeployer; import org.apache.dubbo.config.metadata.ConfigurableMetadataServiceExporter; import org.apache.dubbo.config.metadata.ExporterDeployListener; +import org.apache.dubbo.config.nested.TripleConfig; import org.apache.dubbo.config.provider.impl.DemoServiceImpl; import org.apache.dubbo.config.utils.ConfigValidationUtils; import org.apache.dubbo.metadata.MetadataService; @@ -57,6 +58,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; @@ -472,6 +474,50 @@ void testRemoteMetadataServiceExporterCheckMetadataType() { }); } + @Test + void testDefaultTriple() { + ServiceConfig service = new ServiceConfig<>(); + service.setInterface(DemoService.class); + service.setRef(new DemoServiceImpl()); + + TripleConfig triple = new TripleConfig(); + triple.setMaxBodySize(50); + triple.setMaxResponseBodySize(100); + + ProtocolConfig protocolConfig = new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, -1); + protocolConfig.setTriple(triple); + + DubboBootstrap bootstrap = DubboBootstrap.getInstance(); + bootstrap + .application(new ApplicationConfig("bootstrap-test")) + .registry(new RegistryConfig(zkServerAddress)) + .protocol(protocolConfig) + .service(service) + .start(); + + TripleConfig tripleConfig = bootstrap + .getConfigManager() + .getProtocol(protocolConfig.getName()) + .flatMap(protocol -> Optional.of(protocol.getTriple())) + .orElse(null); + + // check custom value + Assertions.assertEquals(50, tripleConfig.getMaxBodySize()); + Assertions.assertEquals(100, tripleConfig.getMaxResponseBodySize()); + + // check default value + Assertions.assertEquals(1 << 23, tripleConfig.getMaxChunkSize()); + Assertions.assertEquals(8192, tripleConfig.getMaxHeaderSize()); + Assertions.assertEquals(4096, tripleConfig.getMaxInitialLineLength()); + Assertions.assertEquals(16384, tripleConfig.getInitialBufferSize()); + Assertions.assertEquals(4096, tripleConfig.getHeaderTableSize()); + Assertions.assertFalse(tripleConfig.getEnablePush()); + Assertions.assertEquals(Integer.MAX_VALUE, tripleConfig.getMaxConcurrentStreams()); + Assertions.assertEquals(1 << 23, tripleConfig.getInitialWindowSize()); + Assertions.assertEquals(1 << 23, tripleConfig.getMaxFrameSize()); + Assertions.assertEquals(1 << 15, tripleConfig.getMaxHeaderListSize()); + } + private ExporterDeployListener getListener(ApplicationModel model) { return (ExporterDeployListener) model.getExtensionLoader(ApplicationDeployListener.class).getExtension("exporter"); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/TripleBuilderTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/TripleBuilderTest.java new file mode 100644 index 00000000000..1450412a531 --- /dev/null +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/builders/TripleBuilderTest.java @@ -0,0 +1,143 @@ +/* + * 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.config.bootstrap.builders; + +import org.apache.dubbo.config.nested.TripleConfig; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class TripleBuilderTest { + + @Test + void maxBodySize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxBodySize(10240); + Assertions.assertEquals(10240, builder.build().getMaxBodySize()); + } + + @Test + void maxResponseBodySize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxResponseBodySize(8192); + Assertions.assertEquals(8192, builder.build().getMaxResponseBodySize()); + } + + @Test + void maxChunkSize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxChunkSize(2048); + Assertions.assertEquals(2048, builder.build().getMaxChunkSize()); + } + + @Test + void maxHeaderSize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxHeaderSize(40960); + Assertions.assertEquals(40960, builder.build().getMaxHeaderSize()); + } + + @Test + void maxInitialLineLength() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxInitialLineLength(Integer.MAX_VALUE); + Assertions.assertEquals(Integer.MAX_VALUE, builder.build().getMaxInitialLineLength()); + } + + @Test + void initialBufferSize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.initialBufferSize(3000); + Assertions.assertEquals(3000, builder.build().getInitialBufferSize()); + } + + @Test + void headerTableSize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.headerTableSize(1000); + Assertions.assertEquals(1000, builder.build().getHeaderTableSize()); + } + + @Test + void enablePush() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.enablePush(false); + Assertions.assertFalse(builder.build().getEnablePush()); + } + + @Test + void maxConcurrentStreams() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxConcurrentStreams(3000); + Assertions.assertEquals(3000, builder.build().getMaxConcurrentStreams()); + } + + @Test + void initialWindowSize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.initialWindowSize(10240); + Assertions.assertEquals(10240, builder.build().getInitialWindowSize()); + } + + @Test + void maxFrameSize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxFrameSize(4096); + Assertions.assertEquals(4096, builder.build().getMaxFrameSize()); + } + + @Test + void maxHeaderListSize() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxHeaderListSize(2000); + Assertions.assertEquals(2000, builder.build().getMaxHeaderListSize()); + } + + @Test + void build() { + TripleBuilder builder = TripleBuilder.newBuilder(); + builder.maxBodySize(2048) + .maxResponseBodySize(3072) + .maxChunkSize(10240) + .maxHeaderSize(400) + .maxInitialLineLength(100) + .initialBufferSize(8192) + .headerTableSize(300) + .enablePush(true) + .maxConcurrentStreams(Integer.MAX_VALUE) + .initialWindowSize(4096) + .maxFrameSize(1024) + .maxHeaderListSize(500); + + TripleConfig config = builder.build(); + TripleConfig config2 = builder.build(); + + Assertions.assertEquals(2048, config.getMaxBodySize()); + Assertions.assertEquals(3072, config.getMaxResponseBodySize()); + Assertions.assertEquals(10240, config.getMaxChunkSize()); + Assertions.assertEquals(400, config.getMaxHeaderSize()); + Assertions.assertEquals(100, config.getMaxInitialLineLength()); + Assertions.assertEquals(8192, config.getInitialBufferSize()); + Assertions.assertEquals(300, config.getHeaderTableSize()); + Assertions.assertTrue(config.getEnablePush()); + Assertions.assertEquals(Integer.MAX_VALUE, config.getMaxConcurrentStreams()); + Assertions.assertEquals(4096, config.getInitialWindowSize()); + Assertions.assertEquals(1024, config.getMaxFrameSize()); + Assertions.assertEquals(500, config.getMaxHeaderListSize()); + Assertions.assertNotSame(config, config2); + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index 32f67add22b..f07843a9cbc 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -1134,6 +1134,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1508,6 +1582,7 @@ + @@ -2179,6 +2254,17 @@ + + + + + + + + + + + diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java index afad51c598b..222dfcaf5d2 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java @@ -97,12 +97,6 @@ public interface Constants { String INVOCATION_KEY = "invocation"; String SERIALIZATION_ID_KEY = "serialization_id"; - String H2_SETTINGS_HEADER_TABLE_SIZE_KEY = "dubbo.rpc.tri.header-table-size"; - String H2_SETTINGS_ENABLE_PUSH_KEY = "dubbo.rpc.tri.enable-push"; - String H2_SETTINGS_MAX_CONCURRENT_STREAMS_KEY = "dubbo.rpc.tri.max-concurrent-streams"; - String H2_SETTINGS_INITIAL_WINDOW_SIZE_KEY = "dubbo.rpc.tri.initial-window-size"; - String H2_SETTINGS_MAX_FRAME_SIZE_KEY = "dubbo.rpc.tri.max-frame-size"; - String H2_SETTINGS_MAX_HEADER_LIST_SIZE_KEY = "dubbo.rpc.tri.max-header-list-size"; String H2_SETTINGS_SUPPORT_NO_LOWER_HEADER_KEY = "dubbo.rpc.tri.support-no-lower-header"; String H2_SETTINGS_IGNORE_1_0_0_KEY = "dubbo.rpc.tri.ignore-1.0.0-version"; String H2_SETTINGS_RESOLVE_FALLBACK_TO_DEFAULT_KEY = "dubbo.rpc.tri.resolve-fallback-to-default"; diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriHttp2RemoteFlowController.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriHttp2RemoteFlowController.java index aa5339317d5..e2eb02f6f0c 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriHttp2RemoteFlowController.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TriHttp2RemoteFlowController.java @@ -16,9 +16,7 @@ package org.apache.dubbo.rpc.protocol.tri; -import org.apache.dubbo.common.config.Configuration; -import org.apache.dubbo.common.config.ConfigurationUtils; -import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.config.nested.TripleConfig; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http2.Http2Connection; @@ -37,7 +35,6 @@ import java.util.ArrayDeque; import java.util.Deque; -import static io.netty.handler.codec.http2.Http2CodecUtil.DEFAULT_WINDOW_SIZE; import static io.netty.handler.codec.http2.Http2CodecUtil.MAX_WEIGHT; import static io.netty.handler.codec.http2.Http2CodecUtil.MIN_WEIGHT; import static io.netty.handler.codec.http2.Http2Error.FLOW_CONTROL_ERROR; @@ -49,47 +46,43 @@ import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero; import static java.lang.Math.max; import static java.lang.Math.min; -import static org.apache.dubbo.rpc.Constants.H2_SETTINGS_INITIAL_WINDOW_SIZE_KEY; /** * This design is learning from {@see io.netty.handler.codec.http2.DefaultHttp2RemoteFlowController} which is in Netty. */ @UnstableApi public class TriHttp2RemoteFlowController implements Http2RemoteFlowController { - private static final InternalLogger logger = - InternalLoggerFactory.getInstance(TriHttp2RemoteFlowController.class); + private static final InternalLogger logger = InternalLoggerFactory.getInstance(TriHttp2RemoteFlowController.class); private static final int MIN_WRITABLE_CHUNK = 32 * 1024; private final Http2Connection connection; private final Http2Connection.PropertyKey stateKey; private final StreamByteDistributor streamByteDistributor; private final FlowState connectionState; - private final Configuration config; private int initialWindowSize; private WritabilityMonitor monitor; private ChannelHandlerContext ctx; - public TriHttp2RemoteFlowController(Http2Connection connection, ApplicationModel applicationModel) { - this(connection, (Listener) null, applicationModel); + public TriHttp2RemoteFlowController(Http2Connection connection, TripleConfig config) { + this(connection, (Listener) null, config); } - public TriHttp2RemoteFlowController(Http2Connection connection, - StreamByteDistributor streamByteDistributor, - ApplicationModel applicationModel) { - this(connection, streamByteDistributor, null, applicationModel); + public TriHttp2RemoteFlowController( + Http2Connection connection, StreamByteDistributor streamByteDistributor, TripleConfig config) { + this(connection, streamByteDistributor, null, config); } - public TriHttp2RemoteFlowController(Http2Connection connection, final Listener listener, ApplicationModel applicationModel) { - this(connection, new WeightedFairQueueByteDistributor(connection), listener, applicationModel); + public TriHttp2RemoteFlowController(Http2Connection connection, final Listener listener, TripleConfig config) { + this(connection, new WeightedFairQueueByteDistributor(connection), listener, config); } - public TriHttp2RemoteFlowController(Http2Connection connection, - StreamByteDistributor streamByteDistributor, - final Listener listener, - ApplicationModel applicationModel) { + public TriHttp2RemoteFlowController( + Http2Connection connection, + StreamByteDistributor streamByteDistributor, + final Listener listener, + TripleConfig config) { this.connection = checkNotNull(connection, "connection"); this.streamByteDistributor = checkNotNull(streamByteDistributor, "streamWriteDistributor"); - this.config = ConfigurationUtils.getGlobalConfiguration(applicationModel); - this.initialWindowSize = config.getInt(H2_SETTINGS_INITIAL_WINDOW_SIZE_KEY, DEFAULT_WINDOW_SIZE); + this.initialWindowSize = config.getInitialWindowSize(); // Add a flow state for the connection. stateKey = connection.newKey(); @@ -414,9 +407,9 @@ int writeAllocatedBytes(int allocated) { if (cancelled) { cancel(INTERNAL_ERROR, cause); } - if(monitor.isOverFlowControl()){ + if (monitor.isOverFlowControl()) { cause = new Throwable(); - cancel(FLOW_CONTROL_ERROR,cause); + cancel(FLOW_CONTROL_ERROR, cause); } } return writtenBytes; @@ -427,8 +420,7 @@ int writeAllocatedBytes(int allocated) { */ int incrementStreamWindow(int delta) throws Http2Exception { if (delta > 0 && Integer.MAX_VALUE - delta < window) { - throw streamError(stream.id(), FLOW_CONTROL_ERROR, - "Window size overflow for stream: %d", stream.id()); + throw streamError(stream.id(), FLOW_CONTROL_ERROR, "Window size overflow for stream: %d", stream.id()); } window += delta; streamByteDistributor.updateStreamableBytes(this); @@ -499,8 +491,8 @@ void cancel(Http2Error error, Throwable cause) { FlowControlled frame = pendingWriteQueue.poll(); if (frame != null) { // Only create exception once and reuse to reduce overhead of filling in the stacktrace. - final Http2Exception exception = streamError(stream.id(), error, cause, - "Stream closed before write could take place"); + final Http2Exception exception = + streamError(stream.id(), error, cause, "Stream closed before write could take place"); do { writeError(frame, exception); frame = pendingWriteQueue.poll(); @@ -572,13 +564,13 @@ public final void write(Http2Stream stream, int numBytes) { * Called when the writability of the underlying channel changes. * @throws Http2Exception If a write occurs and an exception happens in the write operation. */ - void channelWritabilityChange() throws Http2Exception { } + void channelWritabilityChange() throws Http2Exception {} /** * Called when the state is cancelled. * @param state the state that was cancelled. */ - void stateCancelled(FlowState state) { } + void stateCancelled(FlowState state) {} /** * Set the initial window size for {@code state}. @@ -644,10 +636,10 @@ final void writePendingBytes() throws Http2Exception { int bytesToWrite = writableBytes(); // Make sure we always write at least once, regardless if we have bytesToWrite or not. // This ensures that zero-length frames will always be written. - for (;;) { - if (!streamByteDistributor.distribute(bytesToWrite, this) || - (bytesToWrite = writableBytes()) <= 0 || - !isChannelWritable0()) { + for (; ; ) { + if (!streamByteDistributor.distribute(bytesToWrite, this) + || (bytesToWrite = writableBytes()) <= 0 + || !isChannelWritable0()) { break; } } @@ -680,9 +672,9 @@ final boolean isWritableConnection() { } final boolean isOverFlowControl() { - if(connectionState.windowSize() == 0){ + if (connectionState.windowSize() == 0) { return true; - }else { + } else { return false; } } @@ -785,9 +777,12 @@ private void checkConnectionThenStreamWritabilityChanged(FlowState state) throws checkAllWritabilityChanged(); } else if (isWritable(state) != state.markedWritability()) { notifyWritabilityChanged(state); - }else if(isOverFlowControl()){ - throw streamError(state.stream().id(), FLOW_CONTROL_ERROR, - "TotalPendingBytes size overflow for stream: %d", state.stream().id()); + } else if (isOverFlowControl()) { + throw streamError( + state.stream().id(), + FLOW_CONTROL_ERROR, + "TotalPendingBytes size overflow for stream: %d", + state.stream().id()); } } @@ -798,4 +793,3 @@ private void checkAllWritabilityChanged() throws Http2Exception { } } } - diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2Protocol.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2Protocol.java index 2a8b539527e..415e8d7a311 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2Protocol.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/TripleHttp2Protocol.java @@ -17,9 +17,8 @@ package org.apache.dubbo.rpc.protocol.tri; import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.config.Configuration; -import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.config.nested.TripleConfig; import org.apache.dubbo.remoting.ChannelHandler; import org.apache.dubbo.remoting.api.AbstractWireProtocol; import org.apache.dubbo.remoting.api.pu.ChannelHandlerPretender; @@ -31,7 +30,6 @@ import org.apache.dubbo.remoting.http12.netty4.h2.NettyHttp2FrameCodec; import org.apache.dubbo.remoting.http12.netty4.h2.NettyHttp2ProtocolSelectorHandler; import org.apache.dubbo.remoting.utils.UrlUtils; -import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.FrameworkModel; import org.apache.dubbo.rpc.model.ScopeModelAware; import org.apache.dubbo.rpc.protocol.tri.h12.TripleProtocolDetector; @@ -47,6 +45,7 @@ import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; +import io.netty.handler.codec.http.HttpDecoderConfig; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.HttpServerUpgradeHandler; @@ -62,25 +61,9 @@ import io.netty.handler.logging.LogLevel; import io.netty.util.AsciiString; -import static org.apache.dubbo.rpc.Constants.H2_SETTINGS_ENABLE_PUSH_KEY; -import static org.apache.dubbo.rpc.Constants.H2_SETTINGS_HEADER_TABLE_SIZE_KEY; -import static org.apache.dubbo.rpc.Constants.H2_SETTINGS_INITIAL_WINDOW_SIZE_KEY; -import static org.apache.dubbo.rpc.Constants.H2_SETTINGS_MAX_CONCURRENT_STREAMS_KEY; -import static org.apache.dubbo.rpc.Constants.H2_SETTINGS_MAX_FRAME_SIZE_KEY; -import static org.apache.dubbo.rpc.Constants.H2_SETTINGS_MAX_HEADER_LIST_SIZE_KEY; - @Activate public class TripleHttp2Protocol extends AbstractWireProtocol implements ScopeModelAware { - // 1 MiB - private static final int MIB_1 = 1 << 20; - private static final int MIB_8 = 1 << 23; - private static final int KIB_32 = 1 << 15; - private static final int DEFAULT_MAX_HEADER_LIST_SIZE = KIB_32; - private static final int DEFAULT_SETTING_HEADER_LIST_SIZE = 4096; - private static final int DEFAULT_MAX_FRAME_SIZE = MIB_8; - private static final int DEFAULT_WINDOW_INIT_SIZE = MIB_8; - public static final Http2FrameLogger CLIENT_LOGGER = new Http2FrameLogger(LogLevel.DEBUG, "H2_CLIENT"); public static final Http2FrameLogger SERVER_LOGGER = new Http2FrameLogger(LogLevel.DEBUG, "H2_SERVER"); @@ -103,18 +86,16 @@ public void close() { @Override public void configClientPipeline(URL url, ChannelOperator operator, ContextOperator contextOperator) { - Configuration config = ConfigurationUtils.getGlobalConfiguration(url.getOrDefaultApplicationModel()); + TripleConfig tripleConfig = getTripleConfig(url); final Http2FrameCodec codec = Http2FrameCodecBuilder.forClient() .gracefulShutdownTimeoutMillis(10000) .initialSettings(new Http2Settings() - .headerTableSize( - config.getInt(H2_SETTINGS_HEADER_TABLE_SIZE_KEY, DEFAULT_SETTING_HEADER_LIST_SIZE)) - .pushEnabled(config.getBoolean(H2_SETTINGS_ENABLE_PUSH_KEY, false)) - .maxConcurrentStreams(config.getInt(H2_SETTINGS_MAX_CONCURRENT_STREAMS_KEY, Integer.MAX_VALUE)) - .initialWindowSize(config.getInt(H2_SETTINGS_INITIAL_WINDOW_SIZE_KEY, DEFAULT_WINDOW_INIT_SIZE)) - .maxFrameSize(config.getInt(H2_SETTINGS_MAX_FRAME_SIZE_KEY, DEFAULT_MAX_FRAME_SIZE)) - .maxHeaderListSize( - config.getInt(H2_SETTINGS_MAX_HEADER_LIST_SIZE_KEY, DEFAULT_MAX_HEADER_LIST_SIZE))) + .headerTableSize(tripleConfig.getHeaderTableSize()) + .pushEnabled(tripleConfig.getEnablePush()) + .maxConcurrentStreams(tripleConfig.getMaxConcurrentStreams()) + .initialWindowSize(tripleConfig.getInitialWindowSize()) + .maxFrameSize(tripleConfig.getMaxFrameSize()) + .maxHeaderListSize(tripleConfig.getMaxHeaderListSize())) .frameLogger(CLIENT_LOGGER) .build(); // codec.connection().local().flowController().frameWriter(codec.encoder().frameWriter()); @@ -148,17 +129,20 @@ public void configServerProtocolHandler(URL url, ChannelOperator operator) { } private void configurerHttp1Handlers(URL url, List handlers) { - final HttpServerCodec sourceCodec = new HttpServerCodec(); + TripleConfig tripleConfig = getTripleConfig(url); + final HttpServerCodec sourceCodec = new HttpServerCodec(new HttpDecoderConfig() + .setMaxChunkSize(tripleConfig.getMaxChunkSize()) + .setMaxHeaderSize(tripleConfig.getMaxHeaderSize()) + .setMaxInitialLineLength(tripleConfig.getMaxInitialLineLength()) + .setInitialBufferSize(tripleConfig.getInitialBufferSize())); handlers.add(new ChannelHandlerPretender(sourceCodec)); // Triple protocol http1 upgrade support handlers.add(new ChannelHandlerPretender(new HttpServerUpgradeHandler( sourceCodec, protocol -> { if (AsciiString.contentEquals(Http2CodecUtil.HTTP_UPGRADE_PROTOCOL_NAME, protocol)) { - Configuration config = - ConfigurationUtils.getGlobalConfiguration(url.getOrDefaultApplicationModel()); return new Http2ServerUpgradeCodec( - buildHttp2FrameCodec(config, url.getOrDefaultApplicationModel()), + buildHttp2FrameCodec(url), new HttpWriteQueueHandler(), new FlushConsolidationHandler(64, true), new TripleServerConnectionHandler(), @@ -172,7 +156,7 @@ private void configurerHttp1Handlers(URL url, List handlers) { // If the upgrade was successful, remove the message from the output list // so that it's not propagated to the next handler. This request will // be propagated as a user event instead. - handlers.add(new ChannelHandlerPretender(new HttpObjectAggregator(Integer.MAX_VALUE))); + handlers.add(new ChannelHandlerPretender(new HttpObjectAggregator(tripleConfig.getMaxBodySize()))); handlers.add(new ChannelHandlerPretender(new NettyHttp1Codec())); handlers.add(new ChannelHandlerPretender(new NettyHttp1ConnectionHandler( url, frameworkModel, DefaultHttp11ServerTransportListenerFactory.INSTANCE))); @@ -191,8 +175,7 @@ protected void initChannel(Http2StreamChannel ch) { } private void configurerHttp2Handlers(URL url, List handlers) { - Configuration config = ConfigurationUtils.getGlobalConfiguration(url.getOrDefaultApplicationModel()); - final Http2FrameCodec codec = buildHttp2FrameCodec(config, url.getOrDefaultApplicationModel()); + final Http2FrameCodec codec = buildHttp2FrameCodec(url); final Http2MultiplexHandler handler = buildHttp2MultiplexHandler(url); handlers.add(new ChannelHandlerPretender(new HttpWriteQueueHandler())); handlers.add(new ChannelHandlerPretender(codec)); @@ -202,21 +185,26 @@ private void configurerHttp2Handlers(URL url, List handlers) { handlers.add(new ChannelHandlerPretender(new TripleTailHandler())); } - private Http2FrameCodec buildHttp2FrameCodec(Configuration config, ApplicationModel applicationModel) { + private Http2FrameCodec buildHttp2FrameCodec(URL url) { + TripleConfig tripleConfig = getTripleConfig(url); return TripleHttp2FrameCodecBuilder.forServer() - .customizeConnection((connection) -> connection - .remote() - .flowController(new TriHttp2RemoteFlowController(connection, applicationModel))) + .customizeConnection((connection) -> + connection.remote().flowController(new TriHttp2RemoteFlowController(connection, tripleConfig))) .gracefulShutdownTimeoutMillis(10000) .initialSettings(new Http2Settings() - .headerTableSize( - config.getInt(H2_SETTINGS_HEADER_TABLE_SIZE_KEY, DEFAULT_SETTING_HEADER_LIST_SIZE)) - .maxConcurrentStreams(config.getInt(H2_SETTINGS_MAX_CONCURRENT_STREAMS_KEY, Integer.MAX_VALUE)) - .initialWindowSize(config.getInt(H2_SETTINGS_INITIAL_WINDOW_SIZE_KEY, DEFAULT_WINDOW_INIT_SIZE)) - .maxFrameSize(config.getInt(H2_SETTINGS_MAX_FRAME_SIZE_KEY, DEFAULT_MAX_FRAME_SIZE)) - .maxHeaderListSize( - config.getInt(H2_SETTINGS_MAX_HEADER_LIST_SIZE_KEY, DEFAULT_MAX_HEADER_LIST_SIZE))) + .headerTableSize(tripleConfig.getHeaderTableSize()) + .maxConcurrentStreams(tripleConfig.getMaxConcurrentStreams()) + .initialWindowSize(tripleConfig.getInitialWindowSize()) + .maxFrameSize(tripleConfig.getMaxFrameSize()) + .maxHeaderListSize(tripleConfig.getMaxHeaderListSize())) .frameLogger(SERVER_LOGGER) .build(); } + + private TripleConfig getTripleConfig(URL url) { + return url.getOrDefaultApplicationModel() + .getApplicationConfigManager() + .getOrAddProtocol(url.getProtocol()) + .getTriple(); + } } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/ExceptionUtilsTest.java b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/ExceptionUtilsTest.java index 34545486708..175ff442b79 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/ExceptionUtilsTest.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/test/java/org/apache/dubbo/rpc/protocol/tri/ExceptionUtilsTest.java @@ -91,7 +91,6 @@ void testSelfDefineException() throws Exception { URL providerUrl = URL.valueOf("tri://127.0.0.1:" + availablePort + "/" + IGreeter2.class.getName()) .addParameter(CommonConstants.TIMEOUT_KEY, 10000); - ; ModuleServiceRepository serviceRepository = applicationModel.getDefaultModule().getServiceRepository(); diff --git a/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboConfigurationProperties.java b/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboConfigurationProperties.java index f9fdce872bf..3f52e12802d 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboConfigurationProperties.java +++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboConfigurationProperties.java @@ -30,7 +30,7 @@ import org.apache.dubbo.config.RestConfig; import org.apache.dubbo.config.SslConfig; import org.apache.dubbo.config.TracingConfig; -import org.apache.dubbo.config.TripleConfig; +import org.apache.dubbo.config.nested.TripleConfig; import java.util.LinkedHashMap; import java.util.Map;