From d75fba5346846bac86e8f782e12d3bdadf322360 Mon Sep 17 00:00:00 2001 From: Oleksandr Shevchenko Date: Wed, 13 Mar 2024 10:27:14 +0200 Subject: [PATCH] Add support for maxInboundMetadataSize client configuration (#1064) --- .../AbstractChannelFactory.java | 6 ++- .../client/config/GrpcChannelProperties.java | 37 +++++++++++++++++++ ...itional-spring-configuration-metadata.json | 8 +++- .../GrpcChannelPropertiesGivenUnitTest.java | 4 +- .../GrpcChannelPropertiesNoUnitTest.java | 4 +- 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/channelfactory/AbstractChannelFactory.java b/grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/channelfactory/AbstractChannelFactory.java index 4b6bb63ed..7db3c6903 100644 --- a/grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/channelfactory/AbstractChannelFactory.java +++ b/grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/channelfactory/AbstractChannelFactory.java @@ -234,7 +234,7 @@ protected boolean isNonNullAndNonBlank(final String value) { } /** - * Configures limits such as max message sizes that should be used by the channel. + * Configures limits such as max message or metadata sizes that should be used by the channel. * * @param builder The channel builder to configure. * @param name The name of the client to configure. @@ -245,6 +245,10 @@ protected void configureLimits(final T builder, final String name) { if (maxInboundMessageSize != null) { builder.maxInboundMessageSize((int) maxInboundMessageSize.toBytes()); } + final DataSize maxInboundMetadataSize = properties.getMaxInboundMetadataSize(); + if (maxInboundMetadataSize != null) { + builder.maxInboundMetadataSize((int) maxInboundMetadataSize.toBytes()); + } } /** diff --git a/grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/config/GrpcChannelProperties.java b/grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/config/GrpcChannelProperties.java index c19ad320e..dff796cc1 100644 --- a/grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/config/GrpcChannelProperties.java +++ b/grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/config/GrpcChannelProperties.java @@ -333,6 +333,43 @@ public void setMaxInboundMessageSize(final DataSize maxInboundMessageSize) { } } + @DataSizeUnit(DataUnit.BYTES) + private DataSize maxInboundMetadataSize = null; + + /** + * Sets the maximum size of metadata in bytes allowed to be received. If not set ({@code null}) then it will default + * to gRPC's default. The default is implementation-dependent, but is not generally less than 8 KiB and may be + * unlimited. If set to {@code -1} then it will use the highest possible limit (not recommended). Integer.MAX_VALUE + * disables the enforcement. + * + * @return The maximum size of metadata in bytes allowed to be received or null if the default should be used. + * + * @see ManagedChannelBuilder#maxInboundMetadataSize(int) (int) + */ + public DataSize getMaxInboundMetadataSize() { + return maxInboundMetadataSize; + } + + /** + * Sets the maximum size of metadata in bytes allowed to be received. If not set ({@code null}) then it will + * default.The default is implementation-dependent, but is not generally less than 8 KiB and may be unlimited. If + * set to {@code -1} then it will use the highest possible limit (not recommended). Integer.MAX_VALUE disables the + * enforcement. + * + * @param maxInboundMetadataSize The new maximum size of metadata in bytes allowed to be received. {@code -1} for + * max possible. Null to use the gRPC's default. + * + * @see ManagedChannelBuilder#maxInboundMetadataSize(int) (int) + */ + public void setMaxInboundMetadataSize(DataSize maxInboundMetadataSize) { + if (maxInboundMetadataSize == null || maxInboundMetadataSize.toBytes() >= 0) { + this.maxInboundMetadataSize = maxInboundMetadataSize; + } else if (maxInboundMetadataSize.toBytes() == -1) { + this.maxInboundMetadataSize = DataSize.ofBytes(Integer.MAX_VALUE); + } else { + throw new IllegalArgumentException("Unsupported maxInboundMetadataSize: " + maxInboundMetadataSize); + } + } // -------------------------------------------------- private Boolean fullStreamDecompression; diff --git a/grpc-client-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/grpc-client-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json index c58150d25..c3f599700 100644 --- a/grpc-client-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/grpc-client-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -94,6 +94,12 @@ "sourceType": "net.devh.boot.grpc.client.config.GrpcChannelProperties", "description": "The maximum message size allowed to be received by the channel.\nIf not set (null) then it will default to gRPC's default.\nIf set to -1 then it will use the highest possible limit (not recommended)." }, + { + "name": "grpc.client.GLOBAL.max-inbound-metadata-size", + "type": "org.springframework.util.unit.DataSize", + "sourceType": "net.devh.boot.grpc.client.config.GrpcChannelProperties", + "description": "the maximum size of metadata in bytes allowed to be received. \nIf not set (null) then it will default to gRPC's default. \nIf set to {@code -1} then it will use the highest possible limit (not recommended)." + }, { "name": "grpc.client.GLOBAL.negotiation-type", "type": "net.devh.boot.grpc.client.config.NegotiationType", @@ -158,4 +164,4 @@ "description": "The path to the trusted certificate collection.\nIf not set (null) it will use the system's default collection (Default).\nThis collection will be used to verify server certificates." } ] -} \ No newline at end of file +} diff --git a/grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/config/GrpcChannelPropertiesGivenUnitTest.java b/grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/config/GrpcChannelPropertiesGivenUnitTest.java index 4403eef3d..21f7c47f1 100644 --- a/grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/config/GrpcChannelPropertiesGivenUnitTest.java +++ b/grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/config/GrpcChannelPropertiesGivenUnitTest.java @@ -33,7 +33,8 @@ @ExtendWith(SpringExtension.class) @SpringBootTest(properties = { "grpc.client.test.keepAliveTime=42m", - "grpc.client.test.maxInboundMessageSize=5MB" + "grpc.client.test.maxInboundMessageSize=5MB", + "grpc.client.test.maxInboundMetadataSize=3MB" }) class GrpcChannelPropertiesGivenUnitTest { @@ -45,6 +46,7 @@ void test() { final GrpcChannelProperties properties = this.grpcChannelsProperties.getChannel("test"); assertEquals(Duration.ofMinutes(42), properties.getKeepAliveTime()); assertEquals(DataSize.ofMegabytes(5), properties.getMaxInboundMessageSize()); + assertEquals(DataSize.ofMegabytes(3), properties.getMaxInboundMetadataSize()); } } diff --git a/grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/config/GrpcChannelPropertiesNoUnitTest.java b/grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/config/GrpcChannelPropertiesNoUnitTest.java index 09cbe7521..71316c492 100644 --- a/grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/config/GrpcChannelPropertiesNoUnitTest.java +++ b/grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/config/GrpcChannelPropertiesNoUnitTest.java @@ -33,7 +33,8 @@ @ExtendWith(SpringExtension.class) @SpringBootTest(properties = { "grpc.client.test.keepAliveTime=42", - "grpc.client.test.maxInboundMessageSize=5242880" + "grpc.client.test.maxInboundMessageSize=5242880", + "grpc.client.test.maxInboundMetadataSize=3145728" }) class GrpcChannelPropertiesNoUnitTest { @@ -45,6 +46,7 @@ void test() { final GrpcChannelProperties properties = this.grpcChannelsProperties.getChannel("test"); assertEquals(Duration.ofSeconds(42), properties.getKeepAliveTime()); assertEquals(DataSize.ofMegabytes(5), properties.getMaxInboundMessageSize()); + assertEquals(DataSize.ofMegabytes(3), properties.getMaxInboundMetadataSize()); } }