com.hivemq.client.internal.mqtt.MqttClientConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hivemq-mqtt-client Show documentation
Show all versions of hivemq-mqtt-client Show documentation
HiveMQ MQTT Client is an MQTT 5.0 and MQTT 3.1.1 compatible and feature-rich high-performance Java client library with different API flavours and backpressure support
/*
* 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.internal.mqtt;
import com.hivemq.client.internal.mqtt.advanced.MqttClientAdvancedConfig;
import com.hivemq.client.internal.mqtt.datatypes.MqttClientIdentifierImpl;
import com.hivemq.client.internal.mqtt.ioc.ClientComponent;
import com.hivemq.client.internal.mqtt.ioc.SingletonComponent;
import com.hivemq.client.internal.mqtt.message.auth.MqttSimpleAuth;
import com.hivemq.client.internal.mqtt.message.publish.MqttWillPublish;
import com.hivemq.client.internal.netty.NettyEventLoopProvider;
import com.hivemq.client.internal.util.ExecutorUtil;
import com.hivemq.client.internal.util.collections.ImmutableList;
import com.hivemq.client.mqtt.MqttClientState;
import com.hivemq.client.mqtt.MqttVersion;
import com.hivemq.client.mqtt.datatypes.MqttClientIdentifier;
import com.hivemq.client.mqtt.lifecycle.MqttClientAutoReconnect;
import com.hivemq.client.mqtt.lifecycle.MqttClientConnectedListener;
import com.hivemq.client.mqtt.lifecycle.MqttClientDisconnectedListener;
import com.hivemq.client.mqtt.mqtt5.Mqtt5ClientConfig;
import com.hivemq.client.mqtt.mqtt5.Mqtt5ClientConnectionConfig;
import com.hivemq.client.mqtt.mqtt5.auth.Mqtt5EnhancedAuthMechanism;
import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth;
import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5WillPublish;
import io.netty.channel.EventLoop;
import io.netty.handler.ssl.SslContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
/**
* @author Silvio Giebl
*/
public class MqttClientConfig implements Mqtt5ClientConfig {
private final @NotNull MqttVersion mqttVersion;
private volatile @NotNull MqttClientIdentifierImpl clientIdentifier;
private final @NotNull MqttClientTransportConfigImpl transportConfig;
private final @NotNull MqttClientExecutorConfigImpl executorConfig;
private final @NotNull MqttClientAdvancedConfig advancedConfig;
private final @NotNull ConnectDefaults connectDefaults;
private final @NotNull ImmutableList connectedListeners;
private final @NotNull ImmutableList disconnectedListeners;
private final @NotNull ClientComponent clientComponent;
private volatile @Nullable EventLoop eventLoop;
private int eventLoopAcquires;
private long eventLoopAcquireCount;
private final @NotNull AtomicReference<@NotNull MqttClientState> state;
private volatile @Nullable MqttClientConnectionConfig connectionConfig;
private @NotNull MqttClientTransportConfigImpl currentTransportConfig;
private @Nullable SslContext currentSslContext;
private boolean resubscribeIfSessionExpired;
private boolean republishIfSessionExpired;
public MqttClientConfig(
final @NotNull MqttVersion mqttVersion,
final @NotNull MqttClientIdentifierImpl clientIdentifier,
final @NotNull MqttClientTransportConfigImpl transportConfig,
final @NotNull MqttClientExecutorConfigImpl executorConfig,
final @NotNull MqttClientAdvancedConfig advancedConfig,
final @NotNull ConnectDefaults connectDefaults,
final @NotNull ImmutableList connectedListeners,
final @NotNull ImmutableList disconnectedListeners) {
this.mqttVersion = mqttVersion;
this.clientIdentifier = clientIdentifier;
this.transportConfig = transportConfig;
this.executorConfig = executorConfig;
this.advancedConfig = advancedConfig;
this.connectDefaults = connectDefaults;
this.connectedListeners = connectedListeners;
this.disconnectedListeners = disconnectedListeners;
clientComponent = SingletonComponent.INSTANCE.clientComponentBuilder().clientConfig(this).build();
state = new AtomicReference<>(MqttClientState.DISCONNECTED);
currentTransportConfig = transportConfig;
}
@Override
public @NotNull MqttVersion getMqttVersion() {
return mqttVersion;
}
@Override
public @NotNull Optional getClientIdentifier() {
return (clientIdentifier == MqttClientIdentifierImpl.REQUEST_CLIENT_IDENTIFIER_FROM_SERVER) ? Optional.empty() :
Optional.of(clientIdentifier);
}
public @NotNull MqttClientIdentifierImpl getRawClientIdentifier() {
return clientIdentifier;
}
public void setClientIdentifier(final @NotNull MqttClientIdentifierImpl clientIdentifier) {
this.clientIdentifier = clientIdentifier;
}
@Override
public @NotNull MqttClientTransportConfigImpl getTransportConfig() {
return transportConfig;
}
@Override
public @NotNull MqttClientExecutorConfigImpl getExecutorConfig() {
return executorConfig;
}
@Override
public @NotNull MqttClientAdvancedConfig getAdvancedConfig() {
return advancedConfig;
}
@Override
public @NotNull Optional getSimpleAuth() {
return Optional.ofNullable(connectDefaults.simpleAuth);
}
@Override
public @NotNull Optional getEnhancedAuthMechanism() {
return Optional.ofNullable(connectDefaults.enhancedAuthMechanism);
}
@Override
public @NotNull Optional getWillPublish() {
return Optional.ofNullable(connectDefaults.willPublish);
}
public @NotNull ConnectDefaults getConnectDefaults() {
return connectDefaults;
}
@Override
public @NotNull Optional getAutomaticReconnect() {
for (final MqttClientDisconnectedListener disconnectedListener : disconnectedListeners) {
if (disconnectedListener instanceof MqttClientAutoReconnect) {
return Optional.of((MqttClientAutoReconnect) disconnectedListener);
}
}
return Optional.empty();
}
@Override
public @NotNull ImmutableList getConnectedListeners() {
return connectedListeners;
}
@Override
public @NotNull ImmutableList getDisconnectedListeners() {
return disconnectedListeners;
}
public @NotNull ClientComponent getClientComponent() {
return clientComponent;
}
public @NotNull EventLoop acquireEventLoop() {
synchronized (state) {
eventLoopAcquires++;
eventLoopAcquireCount++;
EventLoop eventLoop = this.eventLoop;
if (eventLoop == null) {
this.eventLoop = eventLoop =
NettyEventLoopProvider.INSTANCE.acquireEventLoop(executorConfig.getRawNettyExecutor(),
executorConfig.getRawNettyThreads());
}
return eventLoop;
}
}
public void releaseEventLoop() {
synchronized (state) {
if (--eventLoopAcquires == 0) {
final EventLoop eventLoop = this.eventLoop;
final long eventLoopAcquireCount = this.eventLoopAcquireCount;
assert eventLoop != null : "eventLoopAcquires was > 0 -> eventLoop != null";
eventLoop.execute(() -> { // release eventLoop after all tasks are finished
synchronized (state) {
if (eventLoopAcquireCount == this.eventLoopAcquireCount) { // eventLoop has not been reacquired
this.eventLoop = null;
// releaseEventLoop must be the last statement so everything is cleaned up even if it throws
NettyEventLoopProvider.INSTANCE.releaseEventLoop(executorConfig.getRawNettyExecutor());
}
}
});
}
}
}
public boolean executeInEventLoop(final @NotNull Runnable runnable) {
final EventLoop eventLoop = this.eventLoop;
if (eventLoop == null) {
return false;
}
return ExecutorUtil.execute(eventLoop, runnable);
}
@Override
public @NotNull MqttClientState getState() {
return state.get();
}
public @NotNull AtomicReference<@NotNull MqttClientState> getRawState() {
return state;
}
@Override
public @NotNull Optional getConnectionConfig() {
return Optional.ofNullable(connectionConfig);
}
public @Nullable MqttClientConnectionConfig getRawConnectionConfig() {
return connectionConfig;
}
public void setConnectionConfig(final @Nullable MqttClientConnectionConfig connectionConfig) {
this.connectionConfig = connectionConfig;
}
public @NotNull MqttClientTransportConfigImpl getCurrentTransportConfig() {
return currentTransportConfig;
}
public void setCurrentTransportConfig(final @NotNull MqttClientTransportConfigImpl currentTransportConfig) {
if (!this.currentTransportConfig.equals(currentTransportConfig)) {
this.currentTransportConfig = currentTransportConfig;
currentSslContext = null;
}
}
public @Nullable SslContext getCurrentSslContext() {
return currentSslContext;
}
public void setCurrentSslContext(final @Nullable SslContext currentSslContext) {
this.currentSslContext = currentSslContext;
}
public boolean isResubscribeIfSessionExpired() {
return resubscribeIfSessionExpired;
}
public void setResubscribeIfSessionExpired(final boolean resubscribeIfSessionExpired) {
this.resubscribeIfSessionExpired = resubscribeIfSessionExpired;
}
public boolean isRepublishIfSessionExpired() {
return republishIfSessionExpired;
}
public void setRepublishIfSessionExpired(final boolean republishIfSessionExpired) {
this.republishIfSessionExpired = republishIfSessionExpired;
}
public static class ConnectDefaults {
private static final @NotNull ConnectDefaults EMPTY = new ConnectDefaults(null, null, null);
public static @NotNull ConnectDefaults of(
final @Nullable MqttSimpleAuth simpleAuth,
final @Nullable Mqtt5EnhancedAuthMechanism enhancedAuthMechanism,
final @Nullable MqttWillPublish willPublish) {
if ((simpleAuth == null) && (enhancedAuthMechanism == null) && (willPublish == null)) {
return EMPTY;
}
return new ConnectDefaults(simpleAuth, enhancedAuthMechanism, willPublish);
}
final @Nullable MqttSimpleAuth simpleAuth;
final @Nullable Mqtt5EnhancedAuthMechanism enhancedAuthMechanism;
final @Nullable MqttWillPublish willPublish;
private ConnectDefaults(
final @Nullable MqttSimpleAuth simpleAuth,
final @Nullable Mqtt5EnhancedAuthMechanism enhancedAuthMechanism,
final @Nullable MqttWillPublish willPublish) {
this.simpleAuth = simpleAuth;
this.enhancedAuthMechanism = enhancedAuthMechanism;
this.willPublish = willPublish;
}
public @Nullable MqttSimpleAuth getSimpleAuth() {
return simpleAuth;
}
public @Nullable Mqtt5EnhancedAuthMechanism getEnhancedAuthMechanism() {
return enhancedAuthMechanism;
}
public @Nullable MqttWillPublish getWillPublish() {
return willPublish;
}
}
}