Add ConnAck message builder method to handle the creation of related properties. (#10812)
Motivation: The CONNACK message builder `ConnAckBuilder` doesn't provide a smooth way to assign the message properties. This PR try to provide an simpler way to create them, in a lazy way. Modification: This PR permit to store properties in the ConnAck message, collecting them and inserting during the build phase. The syntax this PR introduces is: ```java MqttMessageBuilders.connAck().properties(new MqttMessageBuilders.PropertiesInitializer<MqttMessageBuilders.ConnAckPropertiesBuilder>() { @Override public void apply(MqttMessageBuilders.ConnAckPropertiesBuilder builder) { builder.assignedClientId("client1234"); builder.userProperty("custom_property", "value"); } }).build() ``` The name of the properties are defined in the `ConnAckPropertiesBuilder` so that is can be easily used by autocompletion tools. Result: This PR adds the builder class `ConnAckPropertiesBuilder`which is used by newly introduced method `properties` inside the message builder class `ConnAckBuilder`.
This commit is contained in:
parent
fdf09ee243
commit
689929ff8b
@ -17,6 +17,7 @@ package io.netty.handler.codec.mqtt;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.handler.codec.mqtt.MqttProperties.MqttPropertyType;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -295,13 +296,18 @@ public final class MqttMessageBuilders {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface PropertiesInitializer<T> {
|
||||||
|
void apply(T builder);
|
||||||
|
}
|
||||||
|
|
||||||
public static final class ConnAckBuilder {
|
public static final class ConnAckBuilder {
|
||||||
|
|
||||||
private MqttConnectReturnCode returnCode;
|
private MqttConnectReturnCode returnCode;
|
||||||
private boolean sessionPresent;
|
private boolean sessionPresent;
|
||||||
private MqttProperties properties = MqttProperties.NO_PROPERTIES;
|
private MqttProperties properties = MqttProperties.NO_PROPERTIES;
|
||||||
|
private ConnAckPropertiesBuilder propsBuilder;
|
||||||
|
|
||||||
ConnAckBuilder() {
|
private ConnAckBuilder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConnAckBuilder returnCode(MqttConnectReturnCode returnCode) {
|
public ConnAckBuilder returnCode(MqttConnectReturnCode returnCode) {
|
||||||
@ -319,7 +325,18 @@ public final class MqttMessageBuilders {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConnAckBuilder properties(PropertiesInitializer<ConnAckPropertiesBuilder> consumer) {
|
||||||
|
if (propsBuilder == null) {
|
||||||
|
propsBuilder = new ConnAckPropertiesBuilder();
|
||||||
|
}
|
||||||
|
consumer.apply(propsBuilder);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public MqttConnAckMessage build() {
|
public MqttConnAckMessage build() {
|
||||||
|
if (propsBuilder != null) {
|
||||||
|
properties = propsBuilder.build();
|
||||||
|
}
|
||||||
MqttFixedHeader mqttFixedHeader =
|
MqttFixedHeader mqttFixedHeader =
|
||||||
new MqttFixedHeader(MqttMessageType.CONNACK, false, MqttQoS.AT_MOST_ONCE, false, 0);
|
new MqttFixedHeader(MqttMessageType.CONNACK, false, MqttQoS.AT_MOST_ONCE, false, 0);
|
||||||
MqttConnAckVariableHeader mqttConnAckVariableHeader =
|
MqttConnAckVariableHeader mqttConnAckVariableHeader =
|
||||||
@ -328,6 +345,183 @@ public final class MqttMessageBuilders {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class ConnAckPropertiesBuilder {
|
||||||
|
private String clientId;
|
||||||
|
private Long sessionExpiryInterval;
|
||||||
|
private int receiveMaximum;
|
||||||
|
private Byte maximumQos;
|
||||||
|
private boolean retain;
|
||||||
|
private Long maximumPacketSize;
|
||||||
|
private int topicAliasMaximum;
|
||||||
|
private String reasonString;
|
||||||
|
private MqttProperties.UserProperties userProperties = new MqttProperties.UserProperties();
|
||||||
|
private Boolean wildcardSubscriptionAvailable;
|
||||||
|
private Boolean subscriptionIdentifiersAvailable;
|
||||||
|
private Boolean sharedSubscriptionAvailable;
|
||||||
|
private Integer serverKeepAlive;
|
||||||
|
private String responseInformation;
|
||||||
|
private String serverReference;
|
||||||
|
private String authenticationMethod;
|
||||||
|
private byte[] authenticationData;
|
||||||
|
|
||||||
|
public MqttProperties build() {
|
||||||
|
final MqttProperties props = new MqttProperties();
|
||||||
|
if (clientId != null) {
|
||||||
|
props.add(new MqttProperties.StringProperty(MqttPropertyType.ASSIGNED_CLIENT_IDENTIFIER.value(),
|
||||||
|
clientId));
|
||||||
|
}
|
||||||
|
if (sessionExpiryInterval != null) {
|
||||||
|
props.add(new MqttProperties.IntegerProperty(
|
||||||
|
MqttPropertyType.SESSION_EXPIRY_INTERVAL.value(), sessionExpiryInterval.intValue()));
|
||||||
|
}
|
||||||
|
if (receiveMaximum > 0) {
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.RECEIVE_MAXIMUM.value(), receiveMaximum));
|
||||||
|
}
|
||||||
|
if (maximumQos != null) {
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.MAXIMUM_QOS.value(), receiveMaximum));
|
||||||
|
}
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.RETAIN_AVAILABLE.value(), retain ? 1 : 0));
|
||||||
|
if (maximumPacketSize != null) {
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.MAXIMUM_PACKET_SIZE.value(),
|
||||||
|
maximumPacketSize.intValue()));
|
||||||
|
}
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.TOPIC_ALIAS_MAXIMUM.value(),
|
||||||
|
topicAliasMaximum));
|
||||||
|
if (reasonString != null) {
|
||||||
|
props.add(new MqttProperties.StringProperty(MqttPropertyType.REASON_STRING.value(), reasonString));
|
||||||
|
}
|
||||||
|
props.add(userProperties);
|
||||||
|
if (wildcardSubscriptionAvailable != null) {
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.WILDCARD_SUBSCRIPTION_AVAILABLE.value(),
|
||||||
|
wildcardSubscriptionAvailable ? 1 : 0));
|
||||||
|
}
|
||||||
|
if (subscriptionIdentifiersAvailable != null) {
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.SUBSCRIPTION_IDENTIFIER_AVAILABLE.value(),
|
||||||
|
subscriptionIdentifiersAvailable ? 1 : 0));
|
||||||
|
}
|
||||||
|
if (sharedSubscriptionAvailable != null) {
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.SHARED_SUBSCRIPTION_AVAILABLE.value(),
|
||||||
|
sharedSubscriptionAvailable ? 1 : 0));
|
||||||
|
}
|
||||||
|
if (serverKeepAlive != null) {
|
||||||
|
props.add(new MqttProperties.IntegerProperty(MqttPropertyType.SERVER_KEEP_ALIVE.value(),
|
||||||
|
serverKeepAlive));
|
||||||
|
}
|
||||||
|
if (responseInformation != null) {
|
||||||
|
props.add(new MqttProperties.StringProperty(MqttPropertyType.RESPONSE_INFORMATION.value(),
|
||||||
|
responseInformation));
|
||||||
|
}
|
||||||
|
if (serverReference != null) {
|
||||||
|
props.add(new MqttProperties.StringProperty(MqttPropertyType.SERVER_REFERENCE.value(),
|
||||||
|
serverReference));
|
||||||
|
}
|
||||||
|
if (authenticationMethod != null) {
|
||||||
|
props.add(new MqttProperties.StringProperty(MqttPropertyType.AUTHENTICATION_METHOD.value(),
|
||||||
|
authenticationMethod));
|
||||||
|
}
|
||||||
|
if (authenticationData != null) {
|
||||||
|
props.add(new MqttProperties.BinaryProperty(MqttPropertyType.AUTHENTICATION_DATA.value(),
|
||||||
|
authenticationData));
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder sessionExpiryInterval(long seconds) {
|
||||||
|
this.sessionExpiryInterval = seconds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder receiveMaximum(int value) {
|
||||||
|
if (value <= 0) {
|
||||||
|
throw new IllegalArgumentException("receive maximum property must be > 0");
|
||||||
|
}
|
||||||
|
this.receiveMaximum = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder maximumQos(byte value) {
|
||||||
|
if (value != 0 && value != 1) {
|
||||||
|
throw new IllegalArgumentException("maximum QoS property could be 0 or 1");
|
||||||
|
}
|
||||||
|
this.maximumQos = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder retainAvailable(boolean retain) {
|
||||||
|
this.retain = retain;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder maximumPacketSize(long size) {
|
||||||
|
if (size <= 0) {
|
||||||
|
throw new IllegalArgumentException("maximum packet size property must be > 0");
|
||||||
|
}
|
||||||
|
this.maximumPacketSize = size;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder assignedClientId(String clientId) {
|
||||||
|
this.clientId = clientId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder topicAliasMaximum(int value) {
|
||||||
|
this.topicAliasMaximum = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder reasonString(String reason) {
|
||||||
|
this.reasonString = reason;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder userProperty(String name, String value) {
|
||||||
|
userProperties.add(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder wildcardSubscriptionAvailable(boolean value) {
|
||||||
|
this.wildcardSubscriptionAvailable = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder subscriptionIdentifiersAvailable(boolean value) {
|
||||||
|
this.subscriptionIdentifiersAvailable = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder sharedSubscriptionAvailable(boolean value) {
|
||||||
|
this.sharedSubscriptionAvailable = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder serverKeepAlive(int seconds) {
|
||||||
|
this.serverKeepAlive = seconds;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder responseInformation(String value) {
|
||||||
|
this.responseInformation = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder serverReference(String host) {
|
||||||
|
this.serverReference = host;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder authenticationMethod(String methodName) {
|
||||||
|
this.authenticationMethod = methodName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnAckPropertiesBuilder authenticationData(byte[] rawData) {
|
||||||
|
this.authenticationData = rawData.clone();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final class PubAckBuilder {
|
public static final class PubAckBuilder {
|
||||||
|
|
||||||
private short packetId;
|
private short packetId;
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project 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:
|
||||||
|
*
|
||||||
|
* https://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 io.netty.handler.codec.mqtt;
|
||||||
|
|
||||||
|
import io.netty.handler.codec.mqtt.MqttMessageBuilders.PropertiesInitializer;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class MqttMessageBuildersTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConnAckWithProperties() {
|
||||||
|
final MqttConnAckMessage ackMsg = MqttMessageBuilders.connAck()
|
||||||
|
.properties(new PropertiesInitializer<MqttMessageBuilders.ConnAckPropertiesBuilder>() {
|
||||||
|
@Override
|
||||||
|
public void apply(MqttMessageBuilders.ConnAckPropertiesBuilder builder) {
|
||||||
|
builder.assignedClientId("client1234");
|
||||||
|
builder.userProperty("custom_property", "value");
|
||||||
|
}
|
||||||
|
}).build();
|
||||||
|
|
||||||
|
final String clientId = (String) ackMsg.variableHeader()
|
||||||
|
.properties()
|
||||||
|
.getProperty(MqttProperties.MqttPropertyType.ASSIGNED_CLIENT_IDENTIFIER.value())
|
||||||
|
.value();
|
||||||
|
|
||||||
|
assertEquals("client1234", clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user