com.hivemq.client.internal.mqtt.MqttRxClient Maven / Gradle / Ivy
Show all versions of hivemq-mqtt-client Show documentation
/*
* Copyright 2018 dc-square and the HiveMQ MQTT Client Project
*
* 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.handler.auth.MqttReAuthCompletable;
import com.hivemq.client.internal.mqtt.handler.connect.MqttConnAckSingle;
import com.hivemq.client.internal.mqtt.handler.disconnect.MqttDisconnectCompletable;
import com.hivemq.client.internal.mqtt.handler.publish.incoming.MqttGlobalIncomingPublishFlowable;
import com.hivemq.client.internal.mqtt.handler.publish.incoming.MqttSubscribedPublishFlowable;
import com.hivemq.client.internal.mqtt.handler.publish.outgoing.MqttAckFlowable;
import com.hivemq.client.internal.mqtt.handler.publish.outgoing.MqttAckSingle;
import com.hivemq.client.internal.mqtt.handler.publish.outgoing.MqttAckSingleFlowable;
import com.hivemq.client.internal.mqtt.handler.subscribe.MqttSubAckSingle;
import com.hivemq.client.internal.mqtt.handler.subscribe.MqttUnsubAckSingle;
import com.hivemq.client.internal.mqtt.message.connect.MqttConnect;
import com.hivemq.client.internal.mqtt.message.disconnect.MqttDisconnect;
import com.hivemq.client.internal.mqtt.message.publish.MqttPublish;
import com.hivemq.client.internal.mqtt.message.subscribe.MqttSubscribe;
import com.hivemq.client.internal.mqtt.message.unsubscribe.MqttUnsubscribe;
import com.hivemq.client.internal.mqtt.util.MqttChecks;
import com.hivemq.client.internal.util.Checks;
import com.hivemq.client.mqtt.MqttGlobalPublishFilter;
import com.hivemq.client.mqtt.mqtt5.Mqtt5RxClient;
import com.hivemq.client.mqtt.mqtt5.message.connect.Mqtt5Connect;
import com.hivemq.client.mqtt.mqtt5.message.connect.connack.Mqtt5ConnAck;
import com.hivemq.client.mqtt.mqtt5.message.disconnect.Mqtt5Disconnect;
import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5Publish;
import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5PublishResult;
import com.hivemq.client.mqtt.mqtt5.message.subscribe.Mqtt5Subscribe;
import com.hivemq.client.mqtt.mqtt5.message.subscribe.suback.Mqtt5SubAck;
import com.hivemq.client.mqtt.mqtt5.message.unsubscribe.Mqtt5Unsubscribe;
import com.hivemq.client.mqtt.mqtt5.message.unsubscribe.unsuback.Mqtt5UnsubAck;
import com.hivemq.client.rx.FlowableWithSingle;
import io.reactivex.Completable;
import io.reactivex.Flowable;
import io.reactivex.Scheduler;
import io.reactivex.Single;
import io.reactivex.functions.Function;
import io.reactivex.internal.fuseable.ScalarCallable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Silvio Giebl
*/
public class MqttRxClient implements Mqtt5RxClient {
private static final @NotNull Function PUBLISH_MAPPER = MqttChecks::publish;
private final @NotNull MqttClientConfig clientConfig;
public MqttRxClient(final @NotNull MqttClientConfig clientConfig) {
this.clientConfig = clientConfig;
}
@Override
public @NotNull Single connect(final @Nullable Mqtt5Connect connect) {
return connect(MqttChecks.connect(connect));
}
@NotNull Single connect(final @NotNull MqttConnect connect) {
return connectUnsafe(connect).observeOn(clientConfig.getExecutorConfig().getApplicationScheduler());
}
@NotNull Single connectUnsafe(final @NotNull MqttConnect connect) {
return new MqttConnAckSingle(clientConfig, connect);
}
@Override
public @NotNull Single subscribe(final @Nullable Mqtt5Subscribe subscribe) {
return subscribe(MqttChecks.subscribe(subscribe));
}
@NotNull Single subscribe(final @NotNull MqttSubscribe subscribe) {
return subscribeUnsafe(subscribe).observeOn(clientConfig.getExecutorConfig().getApplicationScheduler());
}
@NotNull Single subscribeUnsafe(final @NotNull MqttSubscribe subscribe) {
return new MqttSubAckSingle(subscribe, clientConfig);
}
@Override
public @NotNull FlowableWithSingle subscribeStream(
final @Nullable Mqtt5Subscribe subscribe) {
return subscribeStream(MqttChecks.subscribe(subscribe));
}
@NotNull FlowableWithSingle subscribeStream(final @NotNull MqttSubscribe subscribe) {
return subscribeStreamUnsafe(subscribe).observeOnBoth(
clientConfig.getExecutorConfig().getApplicationScheduler(), true);
}
@NotNull FlowableWithSingle subscribeStreamUnsafe(
final @NotNull MqttSubscribe subscribe) {
return new MqttSubscribedPublishFlowable(subscribe, clientConfig);
}
@Override
public @NotNull Flowable publishes(final @Nullable MqttGlobalPublishFilter filter) {
Checks.notNull(filter, "Global publish filter");
return publishesUnsafe(filter).observeOn(clientConfig.getExecutorConfig().getApplicationScheduler(), true);
}
@NotNull Flowable publishesUnsafe(final @NotNull MqttGlobalPublishFilter filter) {
return new MqttGlobalIncomingPublishFlowable(filter, clientConfig);
}
@Override
public @NotNull Single unsubscribe(final @Nullable Mqtt5Unsubscribe unsubscribe) {
return unsubscribe(MqttChecks.unsubscribe(unsubscribe));
}
@NotNull Single unsubscribe(final @NotNull MqttUnsubscribe unsubscribe) {
return unsubscribeUnsafe(unsubscribe).observeOn(clientConfig.getExecutorConfig().getApplicationScheduler());
}
@NotNull Single unsubscribeUnsafe(final @NotNull MqttUnsubscribe unsubscribe) {
return new MqttUnsubAckSingle(unsubscribe, clientConfig);
}
@NotNull Single publish(final @NotNull MqttPublish publish) {
return publishUnsafe(publish).observeOn(clientConfig.getExecutorConfig().getApplicationScheduler());
}
@NotNull Single publishUnsafe(final @NotNull MqttPublish publish) {
return new MqttAckSingle(clientConfig, publish);
}
@Override
public @NotNull Flowable publish(final @Nullable Flowable publishFlowable) {
Checks.notNull(publishFlowable, "Publish flowable");
return publish(publishFlowable, PUBLISH_MAPPER);
}
public @NotNull Flowable publish(
final @NotNull Flowable publishFlowable, final @NotNull Function
publishMapper) {
final Scheduler applicationScheduler = clientConfig.getExecutorConfig().getApplicationScheduler();
if (publishFlowable instanceof ScalarCallable) {
//noinspection unchecked
final P publish = ((ScalarCallable
) publishFlowable).call();
if (publish == null) {
return Flowable.empty();
}
final MqttPublish mqttPublish;
try {
mqttPublish = publishMapper.apply(publish);
} catch (final Throwable t) {
return Flowable.error(t);
}
return new MqttAckSingleFlowable(clientConfig, mqttPublish).observeOn(applicationScheduler, true);
}
return new MqttAckFlowable(
clientConfig, publishFlowable.subscribeOn(applicationScheduler).map(publishMapper)).observeOn(
applicationScheduler, true);
}
@Override
public @NotNull Completable reauth() {
return reauthUnsafe().observeOn(clientConfig.getExecutorConfig().getApplicationScheduler());
}
@NotNull Completable reauthUnsafe() {
return new MqttReAuthCompletable(clientConfig);
}
@Override
public @NotNull Completable disconnect(final @Nullable Mqtt5Disconnect disconnect) {
return disconnect(MqttChecks.disconnect(disconnect));
}
@NotNull Completable disconnect(final @NotNull MqttDisconnect disconnect) {
return disconnectUnsafe(disconnect).observeOn(clientConfig.getExecutorConfig().getApplicationScheduler());
}
@NotNull Completable disconnectUnsafe(final @NotNull MqttDisconnect disconnect) {
return new MqttDisconnectCompletable(clientConfig, disconnect);
}
@Override
public @NotNull MqttClientConfig getConfig() {
return clientConfig;
}
@Override
public @NotNull MqttAsyncClient toAsync() {
return new MqttAsyncClient(this);
}
@Override
public @NotNull MqttBlockingClient toBlocking() {
return new MqttBlockingClient(this);
}
}