From 25ff10d9280ca4a71e3511a7fb280984f6facf9c Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Tue, 26 Nov 2024 10:21:57 -0600 Subject: [PATCH 1/4] Adding a new Config Class called ServerConfig for Server specific properties. Adding 2 new properties to the newly created ServerConfig, and mapping them for ENV override using the ServerMappedConfigSourceInitializer. maxMessageSizeBytes and port. Replacing the hardcoded values on the codebase with the new configurable properties from ServerConfig. Added the new configuration to the ConfigInjectionModule Created UT for testing the Config validations and restrictions. Added Test case for ConfigInjectionModule to retrieve the newly config object. Signed-off-by: Alfredo Gutierrez --- .../com/hedera/block/server/BlockNodeApp.java | 10 ++- .../com/hedera/block/server/ServerConfig.java | 71 +++++++++++++++++++ .../config/BlockNodeConfigExtension.java | 4 +- .../server/config/ConfigInjectionModule.java | 13 ++++ .../ServerMappedConfigSourceInitializer.java | 20 +++--- .../hedera/block/server/BlockNodeAppTest.java | 7 +- .../hedera/block/server/ServerConfigTest.java | 69 ++++++++++++++++++ ...rverMappedConfigSourceInitializerTest.java | 17 +++-- 8 files changed, 186 insertions(+), 25 deletions(-) create mode 100644 server/src/main/java/com/hedera/block/server/ServerConfig.java create mode 100644 server/src/test/java/com/hedera/block/server/ServerConfigTest.java diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java index e5d7723c4..91485e3bc 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java @@ -48,6 +48,7 @@ public class BlockNodeApp { private final WebServerConfig.Builder webServerBuilder; private final PbjBlockStreamService pbjBlockStreamService; private final PbjBlockAccessService pbjBlockAccessService; + private final ServerConfig serverConfig; /** * Constructs a new BlockNodeApp with the specified dependencies. @@ -57,6 +58,7 @@ public class BlockNodeApp { * @param pbjBlockStreamService defines the Block Stream services * @param pbjBlockAccessService defines the Block Access services * @param webServerBuilder used to build the web server and start it + * @param serverConfig has the server configuration */ @Inject public BlockNodeApp( @@ -64,12 +66,14 @@ public BlockNodeApp( @NonNull HealthService healthService, @NonNull PbjBlockStreamService pbjBlockStreamService, @NonNull PbjBlockAccessService pbjBlockAccessService, - @NonNull WebServerConfig.Builder webServerBuilder) { + @NonNull WebServerConfig.Builder webServerBuilder, + @NonNull ServerConfig serverConfig) { this.serviceStatus = serviceStatus; this.healthService = healthService; this.pbjBlockStreamService = pbjBlockStreamService; this.pbjBlockAccessService = pbjBlockAccessService; this.webServerBuilder = webServerBuilder; + this.serverConfig = serverConfig; } /** @@ -88,13 +92,13 @@ public void start() throws IOException { // Override the default message size final PbjConfig pbjConfig = PbjConfig.builder() .name(PBJ_PROTOCOL_PROVIDER_CONFIG_NAME) - .maxMessageSizeBytes(1024 * 4096) + .maxMessageSizeBytes(serverConfig.maxMessageSizeBytes()) .build(); // Build the web server // TODO: make port server a configurable value. final WebServer webServer = webServerBuilder - .port(8080) + .port(serverConfig.port()) .addProtocol(pbjConfig) .addRouting(pbjRouting) .addRouting(httpRouting) diff --git a/server/src/main/java/com/hedera/block/server/ServerConfig.java b/server/src/main/java/com/hedera/block/server/ServerConfig.java new file mode 100644 index 000000000..3ea4d3e9e --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/ServerConfig.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server; + +import com.swirlds.config.api.ConfigData; +import com.swirlds.config.api.ConfigProperty; +import com.swirlds.config.api.validation.annotation.Max; +import com.swirlds.config.api.validation.annotation.Min; + +/** + * Use this configuration across the server features + * + *

ServerConfig will have settings for the server. + * + * @param maxMessageSizeBytes the http2 max message/frame size in bytes + * @param port the port the server will listen on + */ +@ConfigData("server") +public record ServerConfig( + @ConfigProperty(defaultValue = "4_194_304") @Min(10_240) @Max(16_777_215) int maxMessageSizeBytes, + @ConfigProperty(defaultValue = "8080") @Min(1024) @Max(65_535) int port) { + private static final System.Logger LOGGER = System.getLogger(ServerConfig.class.getName()); + + /** + * Validate the configuration. + * + * @throws IllegalArgumentException if the configuration is invalid + */ + public ServerConfig { + + validateMaxMessageSizeBytes(maxMessageSizeBytes); + validatePort(port); + + LOGGER.log(System.Logger.Level.INFO, "Server configuration server.maxMessageSizeBytes: " + maxMessageSizeBytes); + LOGGER.log(System.Logger.Level.INFO, "Server configuration server.port: " + port); + } + + private void validatePort(int port) { + if (port < 1024) { + throw new IllegalArgumentException("port must be greater than 1024"); + } + + if (port > 65_535) { + throw new IllegalArgumentException("port must be less than 65_535"); + } + } + + private void validateMaxMessageSizeBytes(int maxMessageSizeBytes) { + if (maxMessageSizeBytes < 10_240) { + throw new IllegalArgumentException("maxMessageSizeBytes must be greater than 10_240"); + } + + if (maxMessageSizeBytes > 16_777_215) { + throw new IllegalArgumentException("maxMessageSizeBytes must be less than 16_777_215"); + } + } +} diff --git a/server/src/main/java/com/hedera/block/server/config/BlockNodeConfigExtension.java b/server/src/main/java/com/hedera/block/server/config/BlockNodeConfigExtension.java index 198a9ec0b..48b032784 100644 --- a/server/src/main/java/com/hedera/block/server/config/BlockNodeConfigExtension.java +++ b/server/src/main/java/com/hedera/block/server/config/BlockNodeConfigExtension.java @@ -17,6 +17,7 @@ package com.hedera.block.server.config; import com.google.auto.service.AutoService; +import com.hedera.block.server.ServerConfig; import com.hedera.block.server.consumer.ConsumerConfig; import com.hedera.block.server.mediator.MediatorConfig; import com.hedera.block.server.notifier.NotifierConfig; @@ -54,6 +55,7 @@ public Set> getConfigDataTypes() { PrometheusConfig.class, ProducerConfig.class, ConsumerConfig.class, - PersistenceStorageConfig.class); + PersistenceStorageConfig.class, + ServerConfig.class); } } diff --git a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java index 342790d80..e8c2550cd 100644 --- a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java @@ -16,6 +16,7 @@ package com.hedera.block.server.config; +import com.hedera.block.server.ServerConfig; import com.hedera.block.server.consumer.ConsumerConfig; import com.hedera.block.server.mediator.MediatorConfig; import com.hedera.block.server.notifier.NotifierConfig; @@ -118,4 +119,16 @@ static NotifierConfig provideNotifierConfig(Configuration configuration) { static ProducerConfig provideProducerConfig(Configuration configuration) { return configuration.getConfigData(ProducerConfig.class); } + + /** + * Provides a server configuration singleton using the configuration. + * + * @param configuration is the configuration singleton + * @return a server configuration singleton + */ + @Singleton + @Provides + static ServerConfig provideServerConfig(Configuration configuration) { + return configuration.getConfigData(ServerConfig.class); + } } diff --git a/server/src/main/java/com/hedera/block/server/config/ServerMappedConfigSourceInitializer.java b/server/src/main/java/com/hedera/block/server/config/ServerMappedConfigSourceInitializer.java index ac49cf417..67b2d8aa0 100644 --- a/server/src/main/java/com/hedera/block/server/config/ServerMappedConfigSourceInitializer.java +++ b/server/src/main/java/com/hedera/block/server/config/ServerMappedConfigSourceInitializer.java @@ -26,15 +26,14 @@ * A class that extends {@link MappedConfigSource} ir order to have project-relevant initialization. */ public final class ServerMappedConfigSourceInitializer { - private static final List MAPPINGS = - List.of( - new ConfigMapping( - "consumer.timeoutThresholdMillis", "CONSUMER_TIMEOUT_THRESHOLD_MILLIS"), - new ConfigMapping( - "persistence.storage.rootPath", "PERSISTENCE_STORAGE_ROOT_PATH"), - new ConfigMapping("service.delayMillis", "SERVICE_DELAY_MILLIS"), - new ConfigMapping("mediator.ringBufferSize", "MEDIATOR_RING_BUFFER_SIZE"), - new ConfigMapping("notifier.ringBufferSize", "NOTIFIER_RING_BUFFER_SIZE")); + private static final List MAPPINGS = List.of( + new ConfigMapping("consumer.timeoutThresholdMillis", "CONSUMER_TIMEOUT_THRESHOLD_MILLIS"), + new ConfigMapping("persistence.storage.rootPath", "PERSISTENCE_STORAGE_ROOT_PATH"), + new ConfigMapping("service.delayMillis", "SERVICE_DELAY_MILLIS"), + new ConfigMapping("mediator.ringBufferSize", "MEDIATOR_RING_BUFFER_SIZE"), + new ConfigMapping("notifier.ringBufferSize", "NOTIFIER_RING_BUFFER_SIZE"), + new ConfigMapping("server.maxMessageSizeBytes", "SERVER_MAX_MESSAGE_SIZE_BYTES"), + new ConfigMapping("server.port", "SERVER_PORT")); private ServerMappedConfigSourceInitializer() {} @@ -47,8 +46,7 @@ private ServerMappedConfigSourceInitializer() {} */ @NonNull public static MappedConfigSource getMappedConfigSource() { - final MappedConfigSource config = - new MappedConfigSource(SystemEnvironmentConfigSource.getInstance()); + final MappedConfigSource config = new MappedConfigSource(SystemEnvironmentConfigSource.getInstance()); MAPPINGS.forEach(config::addMapping); return config; } diff --git a/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java b/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java index 40e067b50..001a0857b 100644 --- a/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java @@ -74,18 +74,23 @@ class BlockNodeAppTest { @Mock private BlockNodeContext blockNodeContext; + ServerConfig serverConfig; + private BlockNodeApp blockNodeApp; @BeforeEach void setup() { + serverConfig = new ServerConfig(4_194_304, 8080); + blockNodeApp = new BlockNodeApp( serviceStatus, healthService, new PbjBlockStreamServiceProxy( liveStreamMediator, serviceStatus, blockNodeEventHandler, notifier, blockNodeContext), new PbjBlockAccessServiceProxy(serviceStatus, blockReader, blockNodeContext), - webServerBuilder); + webServerBuilder, + serverConfig); when(webServerBuilder.port(8080)).thenReturn(webServerBuilder); when(webServerBuilder.addProtocol(any(PbjConfig.class))).thenReturn(webServerBuilder); diff --git a/server/src/test/java/com/hedera/block/server/ServerConfigTest.java b/server/src/test/java/com/hedera/block/server/ServerConfigTest.java new file mode 100644 index 000000000..14ab2f077 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/ServerConfigTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class ServerConfigTest { + + @BeforeEach + void setUp() {} + + @AfterEach + void tearDown() {} + + @Test + void testValidValues() { + + ServerConfig serverConfig = new ServerConfig(4_194_304, 8080); + + assertEquals(4_194_304, serverConfig.maxMessageSizeBytes()); + assertEquals(8080, serverConfig.port()); + } + + @Test + void testMessageSizeTooBig() { + assertThrows(IllegalArgumentException.class, () -> { + new ServerConfig(16_777_216, 8080); + }); + } + + @Test + void testMessageSizeTooSmall() { + assertThrows(IllegalArgumentException.class, () -> { + new ServerConfig(10_239, 8080); + }); + } + + @Test + void testPortValueTooBig() { + assertThrows(IllegalArgumentException.class, () -> { + new ServerConfig(4_194_304, 65_536); + }); + } + + @Test + void testPortValueTooSmall() { + assertThrows(IllegalArgumentException.class, () -> { + new ServerConfig(4_194_304, 1023); + }); + } +} diff --git a/server/src/test/java/com/hedera/block/server/config/ServerMappedConfigSourceInitializerTest.java b/server/src/test/java/com/hedera/block/server/config/ServerMappedConfigSourceInitializerTest.java index 863b8a3ea..5c2f03dde 100644 --- a/server/src/test/java/com/hedera/block/server/config/ServerMappedConfigSourceInitializerTest.java +++ b/server/src/test/java/com/hedera/block/server/config/ServerMappedConfigSourceInitializerTest.java @@ -33,7 +33,9 @@ class ServerMappedConfigSourceInitializerTest { new ConfigMapping("persistence.storage.rootPath", "PERSISTENCE_STORAGE_ROOT_PATH"), new ConfigMapping("service.delayMillis", "SERVICE_DELAY_MILLIS"), new ConfigMapping("mediator.ringBufferSize", "MEDIATOR_RING_BUFFER_SIZE"), - new ConfigMapping("notifier.ringBufferSize", "NOTIFIER_RING_BUFFER_SIZE") + new ConfigMapping("notifier.ringBufferSize", "NOTIFIER_RING_BUFFER_SIZE"), + new ConfigMapping("server.maxMessageSizeBytes", "SERVER_MAX_MESSAGE_SIZE_BYTES"), + new ConfigMapping("server.port", "SERVER_PORT"), }; private static MappedConfigSource toTest; @@ -59,19 +61,16 @@ void test_VerifyAllSupportedMappingsAreAddedToInstance() throws ReflectiveOperat for (final ConfigMapping current : SUPPORTED_MAPPINGS) { final Predicate predicate = - cm -> - current.mappedName().equals(cm.mappedName()) - && current.originalName().equals(cm.originalName()); + cm -> current.mappedName().equals(cm.mappedName()) + && current.originalName().equals(cm.originalName()); assertTrue( actual.stream().anyMatch(predicate), - () -> - "when testing for: [%s] it is not contained in mappings of the actual initialized object %s" - .formatted(current, actual)); + () -> "when testing for: [%s] it is not contained in mappings of the actual initialized object %s" + .formatted(current, actual)); } } - private static Queue extractConfigMappings() - throws ReflectiveOperationException { + private static Queue extractConfigMappings() throws ReflectiveOperationException { final Field configMappings = MappedConfigSource.class.getDeclaredField("configMappings"); try { configMappings.setAccessible(true); From 01128d40238eaac30b1ca6dadd54081ab78d4b99 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Tue, 26 Nov 2024 10:22:06 -0600 Subject: [PATCH 2/4] Added Test case for ConfigInjectionModule to retrieve the newly config object. Signed-off-by: Alfredo Gutierrez --- .../config/ConfigInjectionModuleTest.java | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/server/src/test/java/com/hedera/block/server/config/ConfigInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/config/ConfigInjectionModuleTest.java index 898fe0b70..5d2f58824 100644 --- a/server/src/test/java/com/hedera/block/server/config/ConfigInjectionModuleTest.java +++ b/server/src/test/java/com/hedera/block/server/config/ConfigInjectionModuleTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.*; +import com.hedera.block.server.ServerConfig; import com.hedera.block.server.consumer.ConsumerConfig; import com.hedera.block.server.mediator.MediatorConfig; import com.hedera.block.server.notifier.NotifierConfig; @@ -36,12 +37,10 @@ void testProvidePersistenceStorageConfig() throws IOException { BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); Configuration configuration = context.configuration(); - PersistenceStorageConfig persistenceStorageConfig = - configuration.getConfigData(PersistenceStorageConfig.class); + PersistenceStorageConfig persistenceStorageConfig = configuration.getConfigData(PersistenceStorageConfig.class); // Call the method under test - PersistenceStorageConfig providedConfig = - ConfigInjectionModule.providePersistenceStorageConfig(configuration); + PersistenceStorageConfig providedConfig = ConfigInjectionModule.providePersistenceStorageConfig(configuration); // Verify that the correct config data is returned assertNotNull(providedConfig); @@ -71,8 +70,7 @@ void testProvidePrometheusConfig() throws IOException { PrometheusConfig prometheusConfig = configuration.getConfigData(PrometheusConfig.class); // Call the method under test - PrometheusConfig providedConfig = - ConfigInjectionModule.providePrometheusConfig(configuration); + PrometheusConfig providedConfig = ConfigInjectionModule.providePrometheusConfig(configuration); // Verify that the correct config data is returned assertNotNull(providedConfig); @@ -119,4 +117,17 @@ void testProvideNotifierConfig() throws IOException { assertNotNull(providedConfig); assertSame(notifierConfig, providedConfig); } + + @Test + void testServerConfig() throws IOException { + BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); + Configuration configuration = context.configuration(); + ServerConfig serverConfig = configuration.getConfigData(ServerConfig.class); + + ServerConfig providedConfig = ConfigInjectionModule.provideServerConfig(configuration); + + // Verify the config + assertNotNull(providedConfig); + assertSame(serverConfig, providedConfig); + } } From 70470ab9b85d931adce755f07037af6a796422ea Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Wed, 27 Nov 2024 12:16:39 -0600 Subject: [PATCH 3/4] Added new properties to docs Signed-off-by: Alfredo Gutierrez --- server/docs/configuration.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/server/docs/configuration.md b/server/docs/configuration.md index 50f2cd6d9..cda8487c1 100644 --- a/server/docs/configuration.md +++ b/server/docs/configuration.md @@ -9,10 +9,12 @@ The default configuration allows users to quickly get up and running without hav ease of use at the trade-off of some insecure default configuration. Most configuration settings have appropriate defaults and can be left unchanged. It is recommended to browse the properties below and adjust to your needs. -| Environment Variable | Description | Default Value | -|:---|:---|---:| -| PERSISTENCE_STORAGE_ROOT_PATH | The root path for the storage, if not provided will attempt to create a `data` on the working dir of the app. | | -| CONSUMER_TIMEOUT_THRESHOLD_MILLIS | Time to wait for subscribers before disconnecting in milliseconds | 1500 | -| SERVICE_DELAY_MILLIS | Service shutdown delay in milliseconds | 500 | -| MEDIATOR_RING_BUFFER_SIZE | Size of the ring buffer used by the mediator (must be a power of 2) | 67108864 | -| NOTIFIER_RING_BUFFER_SIZE | Size of the ring buffer used by the notifier (must be a power of 2) | 2048 | +| Environment Variable | Description | Default Value | +|:----------------------------------|:--------------------------------------------------------------------------------------------------------------|:--------------| +| PERSISTENCE_STORAGE_ROOT_PATH | The root path for the storage, if not provided will attempt to create a `data` on the working dir of the app. | | +| CONSUMER_TIMEOUT_THRESHOLD_MILLIS | Time to wait for subscribers before disconnecting in milliseconds | 1500 | +| SERVICE_DELAY_MILLIS | Service shutdown delay in milliseconds | 500 | +| MEDIATOR_RING_BUFFER_SIZE | Size of the ring buffer used by the mediator (must be a power of 2) | 67108864 | +| NOTIFIER_RING_BUFFER_SIZE | Size of the ring buffer used by the notifier (must be a power of 2) | 2048 | +| SERVER_PORT | The port the server will listen on | 8080 | +| SERVER_MAX_MESSAGE_SIZE_BYTES | The maximum size of a message frame in bytes | 1048576 | From a1d085703a39085ad0008e0970bea224867e7437 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Wed, 27 Nov 2024 12:27:39 -0600 Subject: [PATCH 4/4] using private static final field for constants Signed-off-by: Alfredo Gutierrez --- .../com/hedera/block/server/ServerConfig.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/server/src/main/java/com/hedera/block/server/ServerConfig.java b/server/src/main/java/com/hedera/block/server/ServerConfig.java index 3ea4d3e9e..b10e8e6c4 100644 --- a/server/src/main/java/com/hedera/block/server/ServerConfig.java +++ b/server/src/main/java/com/hedera/block/server/ServerConfig.java @@ -31,10 +31,23 @@ */ @ConfigData("server") public record ServerConfig( - @ConfigProperty(defaultValue = "4_194_304") @Min(10_240) @Max(16_777_215) int maxMessageSizeBytes, - @ConfigProperty(defaultValue = "8080") @Min(1024) @Max(65_535) int port) { + @ConfigProperty(defaultValue = defaultMaxMessageSizeBytes) + @Min(minMaxMessageSizeBytes) + @Max(maxMaxMessageSizeBytes) + int maxMessageSizeBytes, + @ConfigProperty(defaultValue = defaultPort) @Min(minPort) @Max(maxPort) int port) { private static final System.Logger LOGGER = System.getLogger(ServerConfig.class.getName()); + // Constants for maxMessageSizeBytes property + private static final String defaultMaxMessageSizeBytes = "4_194_304"; + private static final long minMaxMessageSizeBytes = 10_240; + private static final long maxMaxMessageSizeBytes = 16_777_215; + + // Constants for port property + private static final String defaultPort = "8080"; + private static final int minPort = 1024; + private static final int maxPort = 65_535; + /** * Validate the configuration. * @@ -50,22 +63,22 @@ public record ServerConfig( } private void validatePort(int port) { - if (port < 1024) { - throw new IllegalArgumentException("port must be greater than 1024"); + if (port < minPort) { + throw new IllegalArgumentException("port must be greater than " + minPort); } - if (port > 65_535) { - throw new IllegalArgumentException("port must be less than 65_535"); + if (port > maxPort) { + throw new IllegalArgumentException("port must be less than " + maxPort); } } private void validateMaxMessageSizeBytes(int maxMessageSizeBytes) { - if (maxMessageSizeBytes < 10_240) { - throw new IllegalArgumentException("maxMessageSizeBytes must be greater than 10_240"); + if (maxMessageSizeBytes < minMaxMessageSizeBytes) { + throw new IllegalArgumentException("maxMessageSizeBytes must be greater than " + minMaxMessageSizeBytes); } - if (maxMessageSizeBytes > 16_777_215) { - throw new IllegalArgumentException("maxMessageSizeBytes must be less than 16_777_215"); + if (maxMessageSizeBytes > maxMaxMessageSizeBytes) { + throw new IllegalArgumentException("maxMessageSizeBytes must be less than " + maxMaxMessageSizeBytes); } } }