diff --git a/pom.xml b/pom.xml index ea3b1fc..1500473 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 it.tdlight tdlib-session-container - 3.169.50 + 3.169.52 TDLib Session Container UTF-8 @@ -84,7 +84,7 @@ it.tdlight tdlight-java - 3.169.50 + 3.169.52 it.cavallium diff --git a/src/main/java/it/tdlight/tdlibsession/td/TdResult.java b/src/main/java/it/tdlight/tdlibsession/td/TdResult.java index 05c06cf..47d2596 100644 --- a/src/main/java/it/tdlight/tdlibsession/td/TdResult.java +++ b/src/main/java/it/tdlight/tdlibsession/td/TdResult.java @@ -2,6 +2,7 @@ package it.tdlight.tdlibsession.td; import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi.Error; +import java.util.StringJoiner; import java.util.concurrent.CompletionException; import java.util.function.Function; import org.jetbrains.annotations.NotNull; @@ -273,5 +274,13 @@ public interface TdResult { public boolean failed() { return error != null; } + + @Override + public String toString() { + return new StringJoiner(", ", TdResultImpl.class.getSimpleName() + "[", "]") + .add("value=" + value) + .add("error=" + error) + .toString(); + } } } diff --git a/src/main/java/it/tdlight/tdlibsession/td/TdResultMessage.java b/src/main/java/it/tdlight/tdlibsession/td/TdResultMessage.java index 84fadd1..c7af65b 100644 --- a/src/main/java/it/tdlight/tdlibsession/td/TdResultMessage.java +++ b/src/main/java/it/tdlight/tdlibsession/td/TdResultMessage.java @@ -3,6 +3,7 @@ package it.tdlight.tdlibsession.td; import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi.Error; import it.tdlight.jni.TdApi.Object; +import java.util.StringJoiner; public class TdResultMessage { public final TdApi.Object value; @@ -21,4 +22,12 @@ public class TdResultMessage { return TdResult.failed(cause); } } + + @Override + public String toString() { + return new StringJoiner(", ", TdResultMessage.class.getSimpleName() + "[", "]") + .add("value=" + value) + .add("cause=" + cause) + .toString(); + } } diff --git a/src/main/java/it/tdlight/tdlibsession/td/easy/AsyncTdEasy.java b/src/main/java/it/tdlight/tdlibsession/td/easy/AsyncTdEasy.java index 24a2280..84d6a43 100644 --- a/src/main/java/it/tdlight/tdlibsession/td/easy/AsyncTdEasy.java +++ b/src/main/java/it/tdlight/tdlibsession/td/easy/AsyncTdEasy.java @@ -144,7 +144,7 @@ public class AsyncTdEasy { * @return The response or {@link TdApi.Error}. */ public Mono> send(TdApi.Function request) { - return td.execute(request, false); + return td.execute(request, false); } private Mono> sendDirectly(TdApi.Function obj) { @@ -156,7 +156,7 @@ public class AsyncTdEasy { * @param i level */ public Mono setVerbosityLevel(int i) { - return sendDirectly(new TdApi.SetLogVerbosityLevel(i)).then(); + return MonoUtils.thenOrError(sendDirectly(new TdApi.SetLogVerbosityLevel(i))); } /** @@ -164,7 +164,7 @@ public class AsyncTdEasy { * @param name option name */ public Mono clearOption(String name) { - return sendDirectly(new TdApi.SetOption(name, new TdApi.OptionValueEmpty())).then(); + return MonoUtils.thenOrError(sendDirectly(new TdApi.SetOption(name, new TdApi.OptionValueEmpty()))); } /** @@ -173,7 +173,7 @@ public class AsyncTdEasy { * @param value option value */ public Mono setOptionString(String name, String value) { - return sendDirectly(new TdApi.SetOption(name, new TdApi.OptionValueString(value))).then(); + return MonoUtils.thenOrError(sendDirectly(new TdApi.SetOption(name, new TdApi.OptionValueString(value)))); } /** @@ -182,7 +182,7 @@ public class AsyncTdEasy { * @param value option value */ public Mono setOptionInteger(String name, long value) { - return sendDirectly(new TdApi.SetOption(name, new TdApi.OptionValueInteger(value))).then(); + return MonoUtils.thenOrError(sendDirectly(new TdApi.SetOption(name, new TdApi.OptionValueInteger(value)))); } /** @@ -191,7 +191,7 @@ public class AsyncTdEasy { * @param value option value */ public Mono setOptionBoolean(String name, boolean value) { - return sendDirectly(new TdApi.SetOption(name, new TdApi.OptionValueBoolean(value))).then(); + return MonoUtils.thenOrError(sendDirectly(new TdApi.SetOption(name, new TdApi.OptionValueBoolean(value)))); } /** @@ -349,7 +349,7 @@ public class AsyncTdEasy { this.authState.onNext(new AuthorizationStateReady()); switch (obj.getConstructor()) { case AuthorizationStateWaitTdlibParameters.CONSTRUCTOR: - return Mono.from(this.settings).map(settings -> { + return MonoUtils.thenOrError(Mono.from(this.settings).map(settings -> { var parameters = new TdlibParameters(); parameters.useTestDc = settings.useTestDc; parameters.databaseDirectory = settings.databaseDirectory; @@ -367,11 +367,11 @@ public class AsyncTdEasy { parameters.enableStorageOptimizer = settings.enableStorageOptimizer; parameters.ignoreFileNames = settings.ignoreFileNames; return new SetTdlibParameters(parameters); - }).flatMap(this::sendDirectly).then(); + }).flatMap(this::sendDirectly)); case AuthorizationStateWaitEncryptionKey.CONSTRUCTOR: - return sendDirectly(new CheckDatabaseEncryptionKey()).then(); + return MonoUtils.thenOrError(sendDirectly(new CheckDatabaseEncryptionKey())); case AuthorizationStateWaitPhoneNumber.CONSTRUCTOR: - return Mono.from(this.settings).flatMap(settings -> { + return MonoUtils.thenOrError(Mono.from(this.settings).flatMap(settings -> { if (settings.isPhoneNumberSet()) { return sendDirectly(new SetAuthenticationPhoneNumber(String.valueOf(settings.getPhoneNumber()), new PhoneNumberAuthenticationSettings(false, false, false) @@ -381,7 +381,7 @@ public class AsyncTdEasy { } else { return Mono.error(new IllegalArgumentException("A bot is neither an user or a bot")); } - }).then(); + })); case AuthorizationStateWaitRegistration.CONSTRUCTOR: var authorizationStateWaitRegistration = (AuthorizationStateWaitRegistration) obj; RegisterUser registerUser = new RegisterUser(); @@ -398,7 +398,7 @@ public class AsyncTdEasy { registerUser.lastName = ScannerUtils.askParameter(this.logName, "Enter Last Name").trim(); } - return sendDirectly(registerUser).then(); + return MonoUtils.thenOrError(sendDirectly(registerUser)); case AuthorizationStateWaitPassword.CONSTRUCTOR: var authorizationStateWaitPassword = (AuthorizationStateWaitPassword) obj; String passwordMessage = "Password authorization of '" + this.logName + "':"; @@ -409,7 +409,7 @@ public class AsyncTdEasy { var password = ScannerUtils.askParameter(this.logName, "Enter your password"); - return sendDirectly(new CheckAuthenticationPassword(password)).then(); + return MonoUtils.thenOrError(sendDirectly(new CheckAuthenticationPassword(password))); case AuthorizationStateReady.CONSTRUCTOR: { return Mono.empty(); } diff --git a/src/main/java/it/tdlight/tdlibsession/td/middle/client/AsyncTdMiddleEventBusClient.java b/src/main/java/it/tdlight/tdlibsession/td/middle/client/AsyncTdMiddleEventBusClient.java index 5f11a2f..d4662e5 100644 --- a/src/main/java/it/tdlight/tdlibsession/td/middle/client/AsyncTdMiddleEventBusClient.java +++ b/src/main/java/it/tdlight/tdlibsession/td/middle/client/AsyncTdMiddleEventBusClient.java @@ -288,7 +288,7 @@ public class AsyncTdMiddleEventBusClient extends AbstractVerticle implements Asy @Override public Flux getUpdates() { - return incomingUpdatesCo.filter(Objects::nonNull).take(1).single().flatMapMany(v -> v); + return incomingUpdatesCo.filter(Objects::nonNull).flatMap(v -> v); } @Override @@ -305,19 +305,19 @@ public class AsyncTdMiddleEventBusClient extends AbstractVerticle implements Asy return Mono.from(tdClosed).single() .filter(tdClosed -> !tdClosed) - .>handle((_x, sink) -> { + .>flatMap((_x) -> Mono.create(sink -> { cluster.getEventBus().request(botAddress + ".execute", req, cluster.newDeliveryOpts().setLocalOnly(local), (AsyncResult> event) -> { if (event.succeeded()) { if (event.result().body() == null) { - sink.complete(); + sink.error(new NullPointerException("Response is empty")); } else { - sink.next(Objects.requireNonNull(event.result().body()).toTdResult()); + sink.success(Objects.requireNonNull(event.result().body()).toTdResult()); } } else { sink.error(ResponseError.newResponseError(request, botAlias, event.cause())); } }); - }).handle((response, sink) -> { + })).>handle((response, sink) -> { try { Objects.requireNonNull(response); if (OUTPUT_REQUESTS) { @@ -331,6 +331,8 @@ public class AsyncTdMiddleEventBusClient extends AbstractVerticle implements Asy } catch (ClassCastException | NullPointerException e) { sink.error(e); } - }); + }).switchIfEmpty(Mono.fromSupplier(() -> { + return TdResult.failed(new TdApi.Error(500, "Client is closed or response is empty")); + })); } } diff --git a/src/main/java/it/tdlight/tdlibsession/td/middle/direct/AsyncTdMiddleLocal.java b/src/main/java/it/tdlight/tdlibsession/td/middle/direct/AsyncTdMiddleLocal.java index 6adf053..edae8d7 100644 --- a/src/main/java/it/tdlight/tdlibsession/td/middle/direct/AsyncTdMiddleLocal.java +++ b/src/main/java/it/tdlight/tdlibsession/td/middle/direct/AsyncTdMiddleLocal.java @@ -40,7 +40,7 @@ public class AsyncTdMiddleLocal implements AsyncTdMiddle { masterClusterManager .getVertx() .deployVerticle(srv, - new DeploymentOptions().setConfig(new JsonObject().put("botAddress", botAddress).put("local", true)), + new DeploymentOptions().setConfig(new JsonObject().put("botAddress", botAddress).put("botAlias", botAlias).put("local", true)), MonoUtils.toHandler(sink) ); }).onErrorMap(InitializationException::new).flatMap(_x -> { @@ -62,6 +62,9 @@ public class AsyncTdMiddleLocal implements AsyncTdMiddle { @Override public Mono> execute(Function request, boolean executeDirectly) { - return cli.filter(Objects::nonNull).single().flatMap(c -> c.execute(request, executeDirectly)); + return cli + .filter(obj -> Objects.nonNull(obj)) + .single() + .flatMap(c -> c.execute(request, executeDirectly)); } } diff --git a/src/main/java/it/tdlight/tdlibsession/td/middle/server/AsyncTdMiddleEventBusServer.java b/src/main/java/it/tdlight/tdlibsession/td/middle/server/AsyncTdMiddleEventBusServer.java index 17fe198..a4cd8d9 100644 --- a/src/main/java/it/tdlight/tdlibsession/td/middle/server/AsyncTdMiddleEventBusServer.java +++ b/src/main/java/it/tdlight/tdlibsession/td/middle/server/AsyncTdMiddleEventBusServer.java @@ -7,6 +7,7 @@ import io.vertx.core.AsyncResult; import io.vertx.core.Promise; import io.vertx.core.eventbus.Message; import it.tdlight.common.ConstructorDetector; +import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi.AuthorizationStateClosed; import it.tdlight.jni.TdApi.Update; import it.tdlight.jni.TdApi.UpdateAuthorizationState; @@ -210,15 +211,22 @@ public class AsyncTdMiddleEventBusServer extends AbstractVerticle { .replace(" ", "") .replace(" = ", "=")); } - td.execute(msg.body().getRequest(), msg.body().isExecuteDirectly()).single().subscribe(response -> { - msg.reply(new TdResultMessage(response.result(), response.cause()), cluster.newDeliveryOpts().setLocalOnly(local)); - }, ex -> { - msg.fail(500, ex.getLocalizedMessage()); - logger.error("Error when processing a request", ex); - }); + td + .execute(msg.body().getRequest(), msg.body().isExecuteDirectly()) + .switchIfEmpty(Mono.fromSupplier(() -> { + return TdResult.failed(new TdApi.Error(500, "Received null response")); + })) + .subscribe(response -> { + msg.reply(new TdResultMessage(response.result(), response.cause()), + cluster.newDeliveryOpts().setLocalOnly(local) + ); + }, ex -> { + logger.error("Error when processing a request", ex); + msg.fail(500, ex.getLocalizedMessage()); + }); } catch (ClassCastException ex) { - msg.fail(500, ex.getMessage()); logger.error("Error when deserializing a request", ex); + msg.fail(500, ex.getMessage()); } }).completionHandler(MonoUtils.toHandler(registrationSink)); diff --git a/src/main/java/it/tdlight/utils/MonoUtils.java b/src/main/java/it/tdlight/utils/MonoUtils.java index 414296e..48e16f6 100644 --- a/src/main/java/it/tdlight/utils/MonoUtils.java +++ b/src/main/java/it/tdlight/utils/MonoUtils.java @@ -125,4 +125,14 @@ public class MonoUtils { //sink.error(new TdError(value.cause().code, value.cause().message)); } } + + public static Mono thenOrError(Mono> optionalMono) { + return optionalMono.handle((optional, sink) -> { + if (optional.succeeded()) { + sink.complete(); + } else { + sink.error(new TdError(optional.cause().code, optional.cause().message)); + } + }); + } }