From 6ae00a936b3fe64155a047c6e34ead57ee520174 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Sun, 22 Dec 2019 05:48:07 +0100 Subject: [PATCH] Login on startup --- .../org/mercury_im/messenger/Messenger.java | 16 +++++ .../messenger/usecase/AddAccount.java | 42 +---------- .../usecase/ConnectAccountsOnStartup.java | 47 +++++++++++++ .../messenger/usecase/LogIntoAccount.java | 69 +++++++++++++++++++ 4 files changed, 134 insertions(+), 40 deletions(-) create mode 100644 domain/src/main/java/org/mercury_im/messenger/usecase/ConnectAccountsOnStartup.java create mode 100644 domain/src/main/java/org/mercury_im/messenger/usecase/LogIntoAccount.java diff --git a/domain/src/main/java/org/mercury_im/messenger/Messenger.java b/domain/src/main/java/org/mercury_im/messenger/Messenger.java index 012cda8..43ad318 100644 --- a/domain/src/main/java/org/mercury_im/messenger/Messenger.java +++ b/domain/src/main/java/org/mercury_im/messenger/Messenger.java @@ -8,6 +8,7 @@ import org.mercury_im.messenger.data.repository.Repositories; import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.store.MercuryRosterStore; import org.mercury_im.messenger.usecase.AddAccount; +import org.mercury_im.messenger.usecase.ConnectAccountsOnStartup; import org.mercury_im.messenger.xmpp.MercuryConnection; import java.util.HashMap; @@ -18,6 +19,10 @@ import java.util.logging.Logger; import javax.inject.Inject; +import io.reactivex.Scheduler; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.schedulers.Schedulers; + public class Messenger implements ClientStateListener { public static final String TAG = "MercuryIM"; @@ -26,9 +31,20 @@ public class Messenger implements ClientStateListener { private final Map connections = new HashMap<>(); private Repositories repositories; + private CompositeDisposable disposable = new CompositeDisposable(); + @Inject public Messenger(Repositories repositories) { this.repositories = repositories; + initialLogin(); + } + + public void initialLogin() { + disposable.add(repositories.getAccountRepository().observeAllAccounts().firstOrError() + .subscribeOn(Schedulers.newThread()) + .subscribe(initialAccounts -> ConnectAccountsOnStartup + .with(this, initialAccounts) + .execute())); } public void addConnection(MercuryConnection connection) { diff --git a/domain/src/main/java/org/mercury_im/messenger/usecase/AddAccount.java b/domain/src/main/java/org/mercury_im/messenger/usecase/AddAccount.java index 8e3fc8c..3b0db1a 100644 --- a/domain/src/main/java/org/mercury_im/messenger/usecase/AddAccount.java +++ b/domain/src/main/java/org/mercury_im/messenger/usecase/AddAccount.java @@ -1,17 +1,11 @@ package org.mercury_im.messenger.usecase; -import org.jivesoftware.smack.AbstractXMPPConnection; -import org.jivesoftware.smack.SmackException; -import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.sasl.SASLErrorException; import org.mercury_im.messenger.Messenger; import org.mercury_im.messenger.data.repository.AccountRepository; import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.entity.IAccount; import org.mercury_im.messenger.xmpp.MercuryConnection; -import java.io.IOException; -import java.util.logging.Level; import java.util.logging.Logger; import io.reactivex.Completable; @@ -23,13 +17,6 @@ public class AddAccount { private static final Logger LOGGER = Logger.getLogger(AddAccount.class.getName()); - public enum ConnectionResult { - success, - credential_error, - server_error, - other_error - } - private Account account; private MercuryConnection connection; @@ -87,11 +74,8 @@ public class AddAccount { } private Completable logIntoAccount() { - return Completable.fromAction( - () -> { - getOrCreateConnection(); - doAuthenticateIfNecessary(); - }) + return Completable.fromAction(this::getOrCreateConnection) + .andThen(LogIntoAccount.with(connection).executeAndPossiblyThrow()) .subscribeOn(Schedulers.io()); } @@ -102,27 +86,5 @@ public class AddAccount { } } - private ConnectionResult authenticateIfNecessary() { - try { - doAuthenticateIfNecessary(); - return ConnectionResult.success; - } catch (SASLErrorException e) { - LOGGER.log(Level.WARNING, "SASL Error while connecting to account " + account.getAddress(), e); - return ConnectionResult.credential_error; - } catch (SmackException.ConnectionException e) { - LOGGER.log(Level.WARNING, "Connectivity error while connecting to account " + account.getAddress(), e); - return ConnectionResult.server_error; - } - catch (IOException | XMPPException | SmackException | InterruptedException e) { - LOGGER.log(Level.WARNING, "Error connecting to account " + account.getAddress(), e); - return ConnectionResult.other_error; - } - } - private void doAuthenticateIfNecessary() - throws InterruptedException, XMPPException, SmackException, IOException { - if (!connection.getConnection().isAuthenticated()) { - ((AbstractXMPPConnection) connection.getConnection()).connect().login(); - } - } } diff --git a/domain/src/main/java/org/mercury_im/messenger/usecase/ConnectAccountsOnStartup.java b/domain/src/main/java/org/mercury_im/messenger/usecase/ConnectAccountsOnStartup.java new file mode 100644 index 0000000..e7c7c3e --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/usecase/ConnectAccountsOnStartup.java @@ -0,0 +1,47 @@ +package org.mercury_im.messenger.usecase; + +import org.mercury_im.messenger.Messenger; +import org.mercury_im.messenger.entity.Account; +import org.mercury_im.messenger.xmpp.MercuryConnection; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.schedulers.Schedulers; + +public class ConnectAccountsOnStartup { + + private static final Logger LOGGER = Logger.getLogger(ConnectAccountsOnStartup.class.getName()); + + private final Messenger messenger; + private final List accounts = new ArrayList<>(); + + private CompositeDisposable disposable = new CompositeDisposable(); + + private ConnectAccountsOnStartup(Messenger messenger, List initialAccounts) { + this.messenger = messenger; + this.accounts.addAll(initialAccounts); + } + + public static ConnectAccountsOnStartup with(Messenger messenger, List initialAccounts) { + return new ConnectAccountsOnStartup(messenger, initialAccounts); + } + + public void execute() { + for (Account account : accounts) { + if (account.isEnabled()) { + MercuryConnection connection = new MercuryConnection(account); + disposable.add(LogIntoAccount.with(connection) + .executeAndPossiblyThrow() + .subscribeOn(Schedulers.newThread()) + .doOnComplete(() -> messenger.addConnection(connection)) + .subscribe( + () -> LOGGER.log(Level.INFO, "Successfully logged into account " + account.getAddress()), + error -> LOGGER.log(Level.SEVERE, "Error logging into account " + account.getAddress(), error))); + } + } + } +} diff --git a/domain/src/main/java/org/mercury_im/messenger/usecase/LogIntoAccount.java b/domain/src/main/java/org/mercury_im/messenger/usecase/LogIntoAccount.java new file mode 100644 index 0000000..0c7072a --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/usecase/LogIntoAccount.java @@ -0,0 +1,69 @@ +package org.mercury_im.messenger.usecase; + +import org.jivesoftware.smack.AbstractXMPPConnection; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.sasl.SASLErrorException; +import org.mercury_im.messenger.xmpp.MercuryConnection; + +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import io.reactivex.Completable; +import io.reactivex.Single; + +public class LogIntoAccount { + + public enum ConnectionResult { + success, + credential_error, + server_error, + other_error + } + + private static final Logger LOGGER = Logger.getLogger(LogIntoAccount.class.getName()); + + private final MercuryConnection connection; + + private LogIntoAccount(MercuryConnection connection) { + this.connection = connection; + } + + public static LogIntoAccount with(MercuryConnection connection) { + return new LogIntoAccount(connection); + } + + public Completable executeAndPossiblyThrow() { + return Completable.fromAction(this::doAuthenticateIfNecessary); + } + + public Single execute() { + return Single.fromCallable(this::authenticateIfNecessary); + } + + private ConnectionResult authenticateIfNecessary() { + try { + doAuthenticateIfNecessary(); + return ConnectionResult.success; + } catch (SASLErrorException e) { + LOGGER.log(Level.WARNING, "SASL Error while connecting to account " + connection.getAccount().getAddress(), e); + return ConnectionResult.credential_error; + } catch (SmackException.ConnectionException e) { + LOGGER.log(Level.WARNING, "Connectivity error while connecting to account " + connection.getAccount().getAddress(), e); + return ConnectionResult.server_error; + } + catch (IOException | XMPPException | SmackException | InterruptedException e) { + LOGGER.log(Level.WARNING, "Error connecting to account " + connection.getAccount().getAddress(), e); + return ConnectionResult.other_error; + } + } + + private void doAuthenticateIfNecessary() + throws InterruptedException, XMPPException, SmackException, IOException { + if (!connection.getConnection().isAuthenticated()) { + ((AbstractXMPPConnection) connection.getConnection()).connect().login(); + } + } + +}