diff --git a/build.gradle.kts b/build.gradle.kts index b48932f92..1595327c5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -128,6 +128,45 @@ dependencies { testRuntimeOnly("org.slf4j:slf4j-simple:${property("slf4j.version")}") } +/* ******************** integration Tests ******************** */ + +sourceSets.create("integrationTest") { + compileClasspath += sourceSets.main.get().output + runtimeClasspath += sourceSets.main.get().output +} + +val integrationTestImplementation: Configuration by configurations.getting { + extendsFrom(configurations.testImplementation.get()) +} +val integrationTestRuntimeOnly: Configuration by configurations.getting { + extendsFrom(configurations.testRuntimeOnly.get()) +} + +dependencies { + integrationTestImplementation("com.hivemq:hivemq-testcontainer-junit5:${property("hivemq-testcontainer.version")}") + integrationTestImplementation("com.hivemq:hivemq-extension-sdk:${property("hivemq-extension-sdk.version")}") + integrationTestImplementation("org.awaitility:awaitility:${property("awaitility.version")}") +} + +tasks.named("compileIntegrationTestJava") { + javaCompiler.set(javaToolchains.compilerFor { + languageVersion.set(JavaLanguageVersion.of(11)) + }) +} + +val integrationTest by tasks.registering(Test::class) { + group = "verification" + description = "Runs integration tests." + useJUnitPlatform() + testClassesDirs = sourceSets["integrationTest"].output.classesDirs + classpath = sourceSets["integrationTest"].runtimeClasspath + shouldRunAfter(tasks.test) + javaLauncher.set(javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(11)) + }) +} + +tasks.check { dependsOn(integrationTest) } /* ******************** jars ******************** */ diff --git a/gradle.properties b/gradle.properties index 6b993f8b0..3de294e29 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,6 +22,12 @@ guava.version=24.1-jre bouncycastle.version=1.59 paho.version=1.2.0 # +# integration test dependencies +# +hivemq-testcontainer.version=2.0.0 +hivemq-extension-sdk.version=4.7.2 +awaitility.version=4.1.1 +# # plugins # plugin.shadow.version=5.2.0 diff --git a/src/integrationTest/java/com/hivemq/client/restrictions/Mqtt3SendMaximumIT.java b/src/integrationTest/java/com/hivemq/client/restrictions/Mqtt3SendMaximumIT.java new file mode 100644 index 000000000..7c587315f --- /dev/null +++ b/src/integrationTest/java/com/hivemq/client/restrictions/Mqtt3SendMaximumIT.java @@ -0,0 +1,128 @@ +/* + * Copyright 2018-present HiveMQ and the HiveMQ Community + * + * 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.hivemq.client.restrictions; + +import com.hivemq.client.mqtt.MqttGlobalPublishFilter; +import com.hivemq.client.mqtt.datatypes.MqttQos; +import com.hivemq.client.mqtt.mqtt3.Mqtt3Client; +import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient; +import com.hivemq.client.mqtt.mqtt5.Mqtt5Client; +import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5Publish; +import com.hivemq.extension.sdk.api.ExtensionMain; +import com.hivemq.extension.sdk.api.client.ClientContext; +import com.hivemq.extension.sdk.api.client.parameter.InitializerInput; +import com.hivemq.extension.sdk.api.interceptor.puback.PubackOutboundInterceptor; +import com.hivemq.extension.sdk.api.interceptor.puback.parameter.PubackOutboundInput; +import com.hivemq.extension.sdk.api.interceptor.puback.parameter.PubackOutboundOutput; +import com.hivemq.extension.sdk.api.parameter.ExtensionStartInput; +import com.hivemq.extension.sdk.api.parameter.ExtensionStartOutput; +import com.hivemq.extension.sdk.api.parameter.ExtensionStopInput; +import com.hivemq.extension.sdk.api.parameter.ExtensionStopOutput; +import com.hivemq.extension.sdk.api.services.Services; +import com.hivemq.extension.sdk.api.services.intializer.ClientInitializer; +import com.hivemq.testcontainer.core.HiveMQExtension; +import com.hivemq.testcontainer.junit5.HiveMQTestContainerExtension; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.testcontainers.utility.MountableFile; + +import java.time.Duration; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.TimeUnit; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author Yannick Weber + */ +public class Mqtt3SendMaximumIT { + + public static final int RECEIVE_MAXIMUM = 10; + public static final @NotNull HiveMQExtension NO_PUBACK_EXTENSION = HiveMQExtension.builder() + .version("1.0.0") + .priority(100) + .name("No PUBACK Extension") + .id("no-puback-extension") + .mainClass(NoPubackExtension.class) + .build(); + + @RegisterExtension + public final @NotNull HiveMQTestContainerExtension hivemq = + new HiveMQTestContainerExtension().withExtension(NO_PUBACK_EXTENSION) + .withHiveMQConfig(MountableFile.forClasspathResource("/config.xml")); + + @Test + void mqtt3_sendMaximum_applied() throws InterruptedException { + + final Mqtt3Client publisher = Mqtt3Client.builder().serverPort(hivemq.getMqttPort()).build(); + publisher.toBlocking().connectWith().restrictions().sendMaximum(RECEIVE_MAXIMUM).applyRestrictions().send(); + + final ConcurrentLinkedQueue publishes = new ConcurrentLinkedQueue<>(); + final Mqtt5BlockingClient subscriber = Mqtt5Client.builder().serverPort(hivemq.getMqttPort()).buildBlocking(); + subscriber.connect(); + subscriber.toAsync().publishes(MqttGlobalPublishFilter.ALL, publishes::add); + subscriber.subscribeWith().topicFilter("#").send(); + + for (int i = 0; i < 12; i++) { + publisher.toAsync().publishWith().topic("test").qos(MqttQos.AT_LEAST_ONCE).send(); + } + + await().until(() -> publishes.size() == RECEIVE_MAXIMUM); + + TimeUnit.SECONDS.sleep(2); + + assertEquals(RECEIVE_MAXIMUM, publishes.size()); + } + + public static class NoPubackExtension implements ExtensionMain { + + @Override + public void extensionStart( + final @NotNull ExtensionStartInput extensionStartInput, + final @NotNull ExtensionStartOutput extensionStartOutput) { + Services.initializerRegistry().setClientInitializer(new MyClientInitializer()); + } + + @Override + public void extensionStop( + final @NotNull ExtensionStopInput extensionStopInput, + final @NotNull ExtensionStopOutput extensionStopOutput) { + + } + } + + public static class MyClientInitializer implements ClientInitializer { + + @Override + public void initialize( + final @NotNull InitializerInput initializerInput, final @NotNull ClientContext clientContext) { + clientContext.addPubackOutboundInterceptor(new NoPubackInterceptorHandler()); + } + } + + public static class NoPubackInterceptorHandler implements PubackOutboundInterceptor { + + @Override + public void onOutboundPuback( + final @NotNull PubackOutboundInput pubackOutboundInput, + final @NotNull PubackOutboundOutput pubackOutboundOutput) { + pubackOutboundOutput.async(Duration.ofHours(1)); + } + } + +} diff --git a/src/integrationTest/resources/config.xml b/src/integrationTest/resources/config.xml new file mode 100644 index 000000000..b5f2eaf0d --- /dev/null +++ b/src/integrationTest/resources/config.xml @@ -0,0 +1,23 @@ + + + + + in-memory + + \ No newline at end of file diff --git a/src/main/java/com/hivemq/client/internal/mqtt/message/connect/MqttConnectRestrictions.java b/src/main/java/com/hivemq/client/internal/mqtt/message/connect/MqttConnectRestrictions.java index 31f9000bd..cbef3db32 100644 --- a/src/main/java/com/hivemq/client/internal/mqtt/message/connect/MqttConnectRestrictions.java +++ b/src/main/java/com/hivemq/client/internal/mqtt/message/connect/MqttConnectRestrictions.java @@ -17,6 +17,7 @@ package com.hivemq.client.internal.mqtt.message.connect; import com.hivemq.client.annotations.Immutable; +import com.hivemq.client.mqtt.mqtt3.message.connect.Mqtt3ConnectRestrictions; import com.hivemq.client.mqtt.mqtt5.message.connect.Mqtt5ConnectRestrictions; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,7 +26,7 @@ * @author Silvio Giebl */ @Immutable -public class MqttConnectRestrictions implements Mqtt5ConnectRestrictions { +public class MqttConnectRestrictions implements Mqtt5ConnectRestrictions, Mqtt3ConnectRestrictions { public static final @NotNull MqttConnectRestrictions DEFAULT = new MqttConnectRestrictions(DEFAULT_RECEIVE_MAXIMUM, DEFAULT_SEND_MAXIMUM, DEFAULT_MAXIMUM_PACKET_SIZE, diff --git a/src/main/java/com/hivemq/client/internal/mqtt/message/connect/MqttConnectRestrictionsBuilder.java b/src/main/java/com/hivemq/client/internal/mqtt/message/connect/MqttConnectRestrictionsBuilder.java index be9e533af..8d35bcd44 100644 --- a/src/main/java/com/hivemq/client/internal/mqtt/message/connect/MqttConnectRestrictionsBuilder.java +++ b/src/main/java/com/hivemq/client/internal/mqtt/message/connect/MqttConnectRestrictionsBuilder.java @@ -18,6 +18,7 @@ import com.hivemq.client.internal.mqtt.util.MqttChecks; import com.hivemq.client.internal.util.Checks; +import com.hivemq.client.mqtt.mqtt3.message.connect.Mqtt3ConnectRestrictionsBuilder; import com.hivemq.client.mqtt.mqtt5.message.connect.Mqtt5ConnectRestrictionsBuilder; import org.jetbrains.annotations.NotNull; @@ -98,7 +99,7 @@ public abstract class MqttConnectRestrictionsBuilder - implements Mqtt5ConnectRestrictionsBuilder { + implements Mqtt5ConnectRestrictionsBuilder, Mqtt3ConnectRestrictionsBuilder { public Default() {} @@ -113,9 +114,9 @@ public Default() {} } public static class Nested

extends MqttConnectRestrictionsBuilder> - implements Mqtt5ConnectRestrictionsBuilder.Nested

{ + implements Mqtt5ConnectRestrictionsBuilder.Nested

, Mqtt3ConnectRestrictionsBuilder.Nested

{ - Nested( + public Nested( final @NotNull MqttConnectRestrictions restrictions, final @NotNull Function parentConsumer) { diff --git a/src/main/java/com/hivemq/client/internal/mqtt/message/connect/mqtt3/Mqtt3ConnectView.java b/src/main/java/com/hivemq/client/internal/mqtt/message/connect/mqtt3/Mqtt3ConnectView.java index 12bc13374..10c2f6335 100644 --- a/src/main/java/com/hivemq/client/internal/mqtt/message/connect/mqtt3/Mqtt3ConnectView.java +++ b/src/main/java/com/hivemq/client/internal/mqtt/message/connect/mqtt3/Mqtt3ConnectView.java @@ -26,6 +26,7 @@ import com.hivemq.client.internal.mqtt.message.publish.mqtt3.Mqtt3PublishView; import com.hivemq.client.mqtt.mqtt3.message.auth.Mqtt3SimpleAuth; import com.hivemq.client.mqtt.mqtt3.message.connect.Mqtt3Connect; +import com.hivemq.client.mqtt.mqtt3.message.connect.Mqtt3ConnectRestrictions; import com.hivemq.client.mqtt.mqtt3.message.publish.Mqtt3Publish; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,26 +39,28 @@ @Immutable public class Mqtt3ConnectView implements Mqtt3Connect { - public static final @NotNull Mqtt3ConnectView DEFAULT = of(DEFAULT_KEEP_ALIVE, DEFAULT_CLEAN_SESSION, null, null); + public static final @NotNull Mqtt3ConnectView DEFAULT = + of(DEFAULT_KEEP_ALIVE, DEFAULT_CLEAN_SESSION, MqttConnectRestrictions.DEFAULT, null, null); private static @NotNull MqttConnect delegate( final int keepAlive, final boolean cleanSession, + final @NotNull MqttConnectRestrictions restrictions, final @Nullable MqttSimpleAuth simpleAuth, final @Nullable MqttWillPublish willPublish) { - return new MqttConnect(keepAlive, cleanSession, cleanSession ? 0 : MqttConnect.NO_SESSION_EXPIRY, - MqttConnectRestrictions.DEFAULT, simpleAuth, null, willPublish, - MqttUserPropertiesImpl.NO_USER_PROPERTIES); + return new MqttConnect(keepAlive, cleanSession, cleanSession ? 0 : MqttConnect.NO_SESSION_EXPIRY, restrictions, + simpleAuth, null, willPublish, MqttUserPropertiesImpl.NO_USER_PROPERTIES); } static @NotNull Mqtt3ConnectView of( final int keepAlive, final boolean cleanSession, + final @NotNull MqttConnectRestrictions restrictions, final @Nullable MqttSimpleAuth simpleAuth, final @Nullable MqttWillPublish willPublish) { - return new Mqtt3ConnectView(delegate(keepAlive, cleanSession, simpleAuth, willPublish)); + return new Mqtt3ConnectView(delegate(keepAlive, cleanSession, restrictions, simpleAuth, willPublish)); } public static @NotNull Mqtt3ConnectView of(final @NotNull MqttConnect delegate) { @@ -80,6 +83,11 @@ public boolean isCleanSession() { return delegate.isCleanStart(); } + @Override + public @NotNull Mqtt3ConnectRestrictions getRestrictions() { + return delegate.getRestrictions(); + } + @Override public @NotNull Optional getSimpleAuth() { return Optional.ofNullable(getRawSimpleAuth()); @@ -112,7 +120,8 @@ public boolean isCleanSession() { private @NotNull String toAttributeString() { final Mqtt3SimpleAuth simpleAuth = getRawSimpleAuth(); final Mqtt3Publish willPublish = getRawWillPublish(); - return "keepAlive=" + getKeepAlive() + ", cleanSession=" + isCleanSession() + + final Mqtt3ConnectRestrictions restrictions = getRestrictions(); + return "keepAlive=" + getKeepAlive() + ", cleanSession=" + isCleanSession() + ", restrictions=" + restrictions + ((simpleAuth == null) ? "" : ", simpleAuth=" + simpleAuth) + ((willPublish == null) ? "" : ", willPublish=" + willPublish); } diff --git a/src/main/java/com/hivemq/client/internal/mqtt/message/connect/mqtt3/Mqtt3ConnectViewBuilder.java b/src/main/java/com/hivemq/client/internal/mqtt/message/connect/mqtt3/Mqtt3ConnectViewBuilder.java index 81325a6c2..ff4024512 100644 --- a/src/main/java/com/hivemq/client/internal/mqtt/message/connect/mqtt3/Mqtt3ConnectViewBuilder.java +++ b/src/main/java/com/hivemq/client/internal/mqtt/message/connect/mqtt3/Mqtt3ConnectViewBuilder.java @@ -20,12 +20,15 @@ import com.hivemq.client.internal.mqtt.message.auth.mqtt3.Mqtt3SimpleAuthView; import com.hivemq.client.internal.mqtt.message.auth.mqtt3.Mqtt3SimpleAuthViewBuilder; import com.hivemq.client.internal.mqtt.message.connect.MqttConnect; +import com.hivemq.client.internal.mqtt.message.connect.MqttConnectRestrictions; +import com.hivemq.client.internal.mqtt.message.connect.MqttConnectRestrictionsBuilder; import com.hivemq.client.internal.mqtt.message.publish.MqttWillPublish; import com.hivemq.client.internal.mqtt.message.publish.mqtt3.Mqtt3PublishView; import com.hivemq.client.internal.mqtt.message.publish.mqtt3.Mqtt3PublishViewBuilder; import com.hivemq.client.internal.util.Checks; import com.hivemq.client.mqtt.mqtt3.message.auth.Mqtt3SimpleAuth; import com.hivemq.client.mqtt.mqtt3.message.connect.Mqtt3ConnectBuilder; +import com.hivemq.client.mqtt.mqtt3.message.connect.Mqtt3ConnectRestrictions; import com.hivemq.client.mqtt.mqtt3.message.publish.Mqtt3Publish; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,6 +42,7 @@ public abstract class Mqtt3ConnectViewBuilder restrictions() { + return new MqttConnectRestrictionsBuilder.Nested<>(restrictions, this::restrictions); + } + public @NotNull B simpleAuth(final @Nullable Mqtt3SimpleAuth simpleAuth) { this.simpleAuth = (simpleAuth == null) ? null : Checks.notImplemented(simpleAuth, Mqtt3SimpleAuthView.class, "Simple auth").getDelegate(); @@ -90,7 +104,7 @@ public abstract class Mqtt3ConnectViewBuilder implements Mqtt3ConnectBuilder { diff --git a/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3Connect.java b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3Connect.java index 2ec330c77..8f0403634 100644 --- a/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3Connect.java +++ b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3Connect.java @@ -67,6 +67,12 @@ public interface Mqtt3Connect extends Mqtt3Message { */ boolean isCleanSession(); + /** + * @return the restrictions set from the client. + * @since 1.3 + */ + @NotNull Mqtt3ConnectRestrictions getRestrictions(); + /** * @return the optional simple authentication and/or authorization related data of this Connect message. */ diff --git a/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectBuilderBase.java b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectBuilderBase.java index 4d8cfffb9..6022948c5 100644 --- a/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectBuilderBase.java +++ b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectBuilderBase.java @@ -63,6 +63,29 @@ public interface Mqtt3ConnectBuilderBase> { @CheckReturnValue @NotNull B cleanSession(boolean cleanSession); + /** + * Sets the {@link Mqtt3Connect#getRestrictions() restrictions} from the client. + * + * @param restrictions the restrictions from the client. + * @return the builder. + * @since 1.3 + */ + @CheckReturnValue + @NotNull B restrictions(@NotNull Mqtt3ConnectRestrictions restrictions); + + /** + * Fluent counterpart of {@link #restrictions(Mqtt3ConnectRestrictions)}. + *

+ * Calling {@link Mqtt3ConnectRestrictionsBuilder.Nested#applyRestrictions()} on the returned builder has the effect + * of {@link Mqtt3ConnectRestrictions#extend() extending} the current restrictions. + * + * @return the fluent builder for the restrictions. + * @see #restrictions(Mqtt3ConnectRestrictions) + * @since 1.3 + */ + @CheckReturnValue + Mqtt3ConnectRestrictionsBuilder.@NotNull Nested restrictions(); + /** * Sets the optional {@link Mqtt3Connect#getSimpleAuth() simple authentication and/or authorization related data}. * diff --git a/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictions.java b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictions.java new file mode 100644 index 000000000..2da1e7620 --- /dev/null +++ b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictions.java @@ -0,0 +1,64 @@ +/* + * Copyright 2018-present HiveMQ and the HiveMQ Community + * + * 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.hivemq.client.mqtt.mqtt3.message.connect; + +import com.hivemq.client.annotations.DoNotImplement; +import com.hivemq.client.internal.mqtt.message.connect.MqttConnectRestrictionsBuilder; +import org.jetbrains.annotations.NotNull; + +/** + * Restrictions applied by the client in an {@link Mqtt3Connect MQTT 3 Connect message}. + * + * @author Yannick Weber + * @since 1.3 + */ +@DoNotImplement +public interface Mqtt3ConnectRestrictions { + + /** + * Creates a builder for Connect restrictions. + * + * @return the created builder. + */ + static @NotNull Mqtt3ConnectRestrictionsBuilder builder() { + return new MqttConnectRestrictionsBuilder.Default(); + } + + /** + * Returns the maximum amount of not acknowledged publishes with QoS 1 or 2 the client sends to the server + * concurrently. The default is {@link com.hivemq.client.mqtt.mqtt5.message.connect.Mqtt5ConnectRestrictions#DEFAULT_SEND_MAXIMUM}. + * + * @return the maximum amount of not acknowledged publishes with QoS 1 or 2 the client sends to the server + * concurrently. + */ + int getSendMaximum(); + + /** + * Returns the maximum packet size the client sends to the server. The default is {@link + * com.hivemq.client.mqtt.mqtt5.message.connect.Mqtt5ConnectRestrictions#DEFAULT_SEND_MAXIMUM_PACKET_SIZE}. + * + * @return the maximum packet size the client sends to the server. + */ + int getSendMaximumPacketSize(); + + /** + * Creates a builder for extending this Connect restrictions. + * + * @return the created builder. + */ + @NotNull Mqtt3ConnectRestrictionsBuilder extend(); +} diff --git a/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictionsBuilder.java b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictionsBuilder.java new file mode 100644 index 000000000..619225511 --- /dev/null +++ b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictionsBuilder.java @@ -0,0 +1,56 @@ +/* + * Copyright 2018-present HiveMQ and the HiveMQ Community + * + * 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.hivemq.client.mqtt.mqtt3.message.connect; + +import com.hivemq.client.annotations.CheckReturnValue; +import com.hivemq.client.annotations.DoNotImplement; +import org.jetbrains.annotations.NotNull; + +/** + * Builder for {@link Mqtt3ConnectRestrictions}. + * + * @author Yannick Weber + * @since 1.3 + */ +@DoNotImplement +public interface Mqtt3ConnectRestrictionsBuilder + extends Mqtt3ConnectRestrictionsBuilderBase { + + /** + * Builds the {@link Mqtt3ConnectRestrictions}. + * + * @return the built {@link Mqtt3ConnectRestrictions}. + */ + @CheckReturnValue + @NotNull Mqtt3ConnectRestrictions build(); + + /** + * Builder for {@link Mqtt3ConnectRestrictions} that are applied to a parent. + * + * @param

the type of the result when the built {@link Mqtt3ConnectRestrictions} are applied to the parent. + */ + @DoNotImplement + interface Nested

extends Mqtt3ConnectRestrictionsBuilderBase> { + + /** + * Builds the {@link Mqtt3ConnectRestrictions} and applies them to the parent. + * + * @return the result when the built {@link Mqtt3ConnectRestrictions} are applied to the parent. + */ + @NotNull P applyRestrictions(); + } +} diff --git a/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictionsBuilderBase.java b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictionsBuilderBase.java new file mode 100644 index 000000000..fbdc965ec --- /dev/null +++ b/src/main/java/com/hivemq/client/mqtt/mqtt3/message/connect/Mqtt3ConnectRestrictionsBuilderBase.java @@ -0,0 +1,55 @@ +/* + * Copyright 2018-present HiveMQ and the HiveMQ Community + * + * 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.hivemq.client.mqtt.mqtt3.message.connect; + +import com.hivemq.client.annotations.CheckReturnValue; +import com.hivemq.client.annotations.DoNotImplement; +import org.jetbrains.annotations.NotNull; + +/** + * Builder base for {@link Mqtt3ConnectRestrictions}. + * + * @param the type of the builder. + * @author Yannick Weber + * @since 1.3 + */ +@DoNotImplement +public interface Mqtt3ConnectRestrictionsBuilderBase> { + + /** + * Sets the {@link Mqtt3ConnectRestrictions#getSendMaximum() send maximum}. + *

+ * The value must not be zero and must be in the range of an unsigned short: [1, 65_535]. + * + * @param receiveMaximum the send maximum. + * @return the builder. + */ + @CheckReturnValue + @NotNull B sendMaximum(int receiveMaximum); + + /** + * Sets the {@link Mqtt3ConnectRestrictions#getSendMaximumPacketSize() maximum packet size for sending}. + *

+ * The value must not be zero and in the range: [1, 268_435_460]. + * + * @param maximumPacketSize the maximum packet size for sending. + * @return the builder. + */ + @CheckReturnValue + @NotNull B sendMaximumPacketSize(int maximumPacketSize); + +}