summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Mollekopf <mollekopf@kolabsys.com>2013-11-11 23:54:19 (GMT)
committerChristian Mollekopf <mollekopf@kolabsys.com>2013-11-11 23:54:19 (GMT)
commitb7007176dfb57218d7e4ea50bbca53c6fadc38cc (patch)
treefa2b9518dec042d44227a7b2f8a912c83aa7b5f6
parentbb70af914b7080e5a6a11b20bfe0873b84d01aea (diff)
downloadkolab-utils-b7007176dfb57218d7e4ea50bbca53c6fadc38cc.tar.gz
Async logout and user retrieval.
-rw-r--r--lib/kolabaccount.cpp27
-rw-r--r--lib/kolabaccount.h3
-rw-r--r--migrationutility/coordinationjob.cpp16
-rw-r--r--migrationutility/coordinationjob.h2
-rw-r--r--migrationutility/imapsourceaccount.cpp3
-rw-r--r--migrationutility/migrateuserjob.cpp18
-rw-r--r--migrationutility/migrateuserjob.h1
-rw-r--r--migrationutility/sourceserver.cpp153
-rw-r--r--migrationutility/sourceserver.h75
-rw-r--r--migrationutility/tests/exchangeimaptest.cpp4
-rw-r--r--migrationutility/tests/migrationscenariotest.cpp4
-rw-r--r--migrationutility/tests/migrationtest.cpp4
12 files changed, 236 insertions, 74 deletions
diff --git a/lib/kolabaccount.cpp b/lib/kolabaccount.cpp
index a0b616c..a395f2f 100644
--- a/lib/kolabaccount.cpp
+++ b/lib/kolabaccount.cpp
@@ -50,6 +50,14 @@ KolabAccount::KolabAccount(QObject* parent)
}
+KolabAccount::~KolabAccount()
+{
+ if (mSession) {
+ mSession->close();
+ mSession->deleteLater();
+ }
+}
+
void KolabAccount::setVersion(Kolab::Version version)
{
mVersion = version;
@@ -212,17 +220,12 @@ void KolabAccount::appendObjectSync(Object obj, const QString& folder)
}
}
-void KolabAccount::logout()
+KJob *KolabAccount::logout()
{
if (!mSession) {
- return;
+ return 0;
}
- KIMAP::LogoutJob *logoutJob = new KIMAP::LogoutJob(mSession);
- logoutJob->exec();
- mSession->close();
-// mSession->deleteLater();
- mSession = 0;
- Debug() << "logout done";
+ return new KIMAP::LogoutJob(mSession);
}
const char* FlagDeleted2 = "\\Deleted";
@@ -303,7 +306,13 @@ void KolabAccount::cleanAccount()
mFolders.append(QLatin1String("inbox"));
//logging out and logging in again seems to help with the "NO Mailbox is locked" problem when creating folders afterwards.
- logout();
+ KJob *logoutJob = logout();
+ if (logoutJob) {
+ logoutJob->exec();
+ }
+ mSession->close();
+ mSession->deleteLater();
+ mSession = 0;
init();
}
diff --git a/lib/kolabaccount.h b/lib/kolabaccount.h
index e541a30..a80f2a5 100644
--- a/lib/kolabaccount.h
+++ b/lib/kolabaccount.h
@@ -34,6 +34,7 @@ class KolabAccount: public QObject
Q_OBJECT
public:
explicit KolabAccount(QObject* parent = 0);
+ virtual ~KolabAccount();
void setHost(const QString &host, qint16 port);
void setCredentials(const QString &username, const QString &pw, const QString &authorizationName);
@@ -51,7 +52,7 @@ public:
void setDryRun(bool);
void setWipeTargetFolders(bool);
- void logout();
+ KJob *logout();
QList<Object> getObjects(const QString& folder);
QStringList lookupFolderList();
diff --git a/migrationutility/coordinationjob.cpp b/migrationutility/coordinationjob.cpp
index f7a402f..ae063df 100644
--- a/migrationutility/coordinationjob.cpp
+++ b/migrationutility/coordinationjob.cpp
@@ -32,12 +32,22 @@ CoordinationJob::CoordinationJob(SourceServer *sourceServer, KolabServer *kolabS
void CoordinationJob::start()
{
- QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
+ UserListJob *listJob = mSourceServer->listUsers();
+ Q_ASSERT(listJob);
+ connect(listJob, SIGNAL(result(KJob*)), this, SLOT(onUserListJobDone(KJob*)));
+ listJob->start();
}
-void CoordinationJob::doStart()
+void CoordinationJob::onUserListJobDone(KJob* job)
{
- mUserList = mSourceServer->getUserList();
+ if (job->error()) {
+ setError(UserDefinedError);
+ setErrorText("Failed to get user list: " + job->errorString());
+ emitResult();
+ return;
+ }
+ UserListJob *listJob = static_cast<UserListJob*>(job);
+ mUserList = listJob->getUserList();
if (mUserList.isEmpty()) {
Debug() << "no users found";
} else {
diff --git a/migrationutility/coordinationjob.h b/migrationutility/coordinationjob.h
index 94a57a6..2f25a63 100644
--- a/migrationutility/coordinationjob.h
+++ b/migrationutility/coordinationjob.h
@@ -31,7 +31,7 @@ public:
explicit CoordinationJob(SourceServer *sourceServer, KolabServer *kolabServer, QObject* parent = 0);
virtual void start();
private slots:
- void doStart();
+ void onUserListJobDone(KJob *job);
void userMigrated(KJob *job);
private:
void processUser();
diff --git a/migrationutility/imapsourceaccount.cpp b/migrationutility/imapsourceaccount.cpp
index 3e470e6..39d9d76 100644
--- a/migrationutility/imapsourceaccount.cpp
+++ b/migrationutility/imapsourceaccount.cpp
@@ -182,6 +182,5 @@ KJob *IMAPSourceAccount::login()
KJob *IMAPSourceAccount::logout()
{
- KIMAP::LogoutJob *logoutJob = new KIMAP::LogoutJob(mSession);
- return logoutJob;
+ return new KIMAP::LogoutJob(mSession);
} \ No newline at end of file
diff --git a/migrationutility/migrateuserjob.cpp b/migrationutility/migrateuserjob.cpp
index a4cf4ed..783bf8e 100644
--- a/migrationutility/migrateuserjob.cpp
+++ b/migrationutility/migrateuserjob.cpp
@@ -48,8 +48,14 @@ void MigrateUserJob::migrateNextAccount()
mCurrentSourceAccount->deleteLater();
}
if (mSourceAccounts.isEmpty()) {
- mKolabAccount->logout();
- emitResult();
+ KJob *logoutJob = mKolabAccount->logout();
+ if (logoutJob) {
+ Debug() << "running target logout job";
+ connect(logoutJob, SIGNAL(result(KJob*)), this, SLOT(onLogoutDone(KJob*)));
+ logoutJob->start();
+ } else {
+ onLogoutDone(0);
+ }
return;
}
mCurrentSourceAccount = mSourceAccounts.takeFirst();
@@ -71,6 +77,14 @@ void MigrateUserJob::onLoginDone(KJob *job)
QMetaObject::invokeMethod(this, "fetchFolders", Qt::QueuedConnection);
}
+void MigrateUserJob::onLogoutDone(KJob *job)
+{
+ if (job && job->error()) {
+ Error() << "Failed to logout" << job->errorString();
+ }
+ emitResult();
+}
+
void MigrateUserJob::fetchFolders()
{
FetchFoldersJob *fetchJob = mCurrentSourceAccount->fetchFolderList();
diff --git a/migrationutility/migrateuserjob.h b/migrationutility/migrateuserjob.h
index de5442b..ebd3459 100644
--- a/migrationutility/migrateuserjob.h
+++ b/migrationutility/migrateuserjob.h
@@ -40,6 +40,7 @@ private slots:
void onFolderMigrated(KJob*);
void onFoldersFetched(KJob*);
void onFoldersReceived(const QStringList &);
+ void onLogoutDone(KJob *);
void fetchFolders();
void migrateNextFolder();
void migrateNextAccount();
diff --git a/migrationutility/sourceserver.cpp b/migrationutility/sourceserver.cpp
index 934ca6e..47f60d1 100644
--- a/migrationutility/sourceserver.cpp
+++ b/migrationutility/sourceserver.cpp
@@ -26,6 +26,35 @@
#include "exchangesourceaccount.h"
+UserListJob::UserListJob(QObject* parent)
+: KJob(parent)
+{
+
+}
+
+FixedUserListJob::FixedUserListJob(const QStringList& userList, QObject* parent)
+: UserListJob(parent),
+ mUserList(userList)
+{
+
+}
+
+void FixedUserListJob::start()
+{
+ QMetaObject::invokeMethod(this, "doEmitResult", Qt::QueuedConnection);
+}
+
+void FixedUserListJob::doEmitResult()
+{
+ emitResult();
+}
+
+QStringList FixedUserListJob::getUserList() const
+{
+ return mUserList;
+}
+
+
SourceServer::SourceServer(QObject* parent): QObject(parent)
{
@@ -40,10 +69,10 @@ QList<SourceAccount*> SourceServer::getSourceAccounts(const QString &user)
return accounts;
}
-QStringList SourceServer::getUserList()
+UserListJob *SourceServer::listUsers()
{
if (!mExplicitUsers.isEmpty()) {
- return mExplicitUsers;
+ return new FixedUserListJob(mExplicitUsers, this);
}
return retrieveUserList();
}
@@ -53,9 +82,9 @@ void SourceServer::setSingleUser(const QString &user)
mExplicitUsers.append(user);
}
-QStringList SourceServer::retrieveUserList()
+UserListJob *SourceServer::retrieveUserList()
{
- return QStringList();
+ return 0;
}
void SourceServer::setStatefile(const QString &statefile)
@@ -84,11 +113,6 @@ TestServer::TestServer(QObject* parent)
mUsers << QLatin1String("user3");
}
-QStringList TestServer::retrieveUserList()
-{
- return mUsers;
-}
-
QList<SourceAccount*> TestServer::getSourceAccountsImpl(const QString& user)
{
Q_UNUSED(user);
@@ -96,8 +120,82 @@ QList<SourceAccount*> TestServer::getSourceAccountsImpl(const QString& user)
return QList<SourceAccount*>() << new TestAccount(this);
}
+UserListJob *TestServer::retrieveUserList()
+{
+ return new FixedUserListJob(mUsers, this);
+}
+
//---------------------------------------------------------------------------
+IMAPUserListJob::IMAPUserListJob(const QString &host, qint16 port, const IMAPConnectionSettings &settings, QObject* parent)
+: UserListJob(parent),
+ mSession(createSession(host, port, this)),
+ mConnectionSettings(settings)
+{
+}
+
+IMAPUserListJob::~IMAPUserListJob()
+{
+ if (mSession) {
+ mSession->close();
+ mSession->deleteLater();
+ }
+}
+
+void IMAPUserListJob::start()
+{
+ KIMAP::LoginJob *loginJob = new KIMAP::LoginJob(mSession);
+ loginJob->setUserName(mConnectionSettings.username());
+ loginJob->setPassword(mConnectionSettings.password());
+ loginJob->setEncryptionMode(mConnectionSettings.encryptionMode());
+ loginJob->setAuthenticationMode(mConnectionSettings.authenticationMode());
+ connect(loginJob, SIGNAL(result(KJob*)), this, SLOT(onLoginDone(KJob*)));
+ loginJob->start();
+}
+
+void IMAPUserListJob::onLoginDone(KJob *job)
+{
+ if (job->error()) {
+ setError(KJob::UserDefinedError);
+ setErrorText("Failed to login: " + job->errorString());
+ emitResult();
+ return;
+ }
+ GetUserListJob *userListJob = new GetUserListJob(mSession, this);
+ connect(userListJob, SIGNAL(result(KJob*)), this, SLOT(onUserListJobDone(KJob*)));
+ userListJob->start();
+}
+
+void IMAPUserListJob::onUserListJobDone(KJob *job)
+{
+ if (job->error()) {
+ setError(KJob::UserDefinedError);
+ setErrorText("Failed to retrieve user list: " + job->errorString());
+ emitResult();
+ return;
+ }
+ GetUserListJob *userListJob = static_cast<GetUserListJob*>(job);
+ mUserList = userListJob->getUserList();
+ KIMAP::LogoutJob *logoutJob = new KIMAP::LogoutJob(mSession);
+ connect(logoutJob, SIGNAL(result(KJob*)), this, SLOT(onLogoutDone(KJob*)));
+ logoutJob->start();
+}
+
+void IMAPUserListJob::onLogoutDone(KJob *job)
+{
+ if (job->error()) {
+ setError(KJob::UserDefinedError);
+ setErrorText("Error during logout: " + job->errorString());
+ }
+ emitResult();
+}
+
+QStringList IMAPUserListJob::getUserList() const
+{
+ return mUserList;
+}
+
+
IMAPSourceServer::IMAPSourceServer(QObject* parent)
: SourceServer(parent),
mSession(0),
@@ -139,44 +237,11 @@ QList<SourceAccount*> IMAPSourceServer::getSourceAccountsImpl(const QString& use
return QList<SourceAccount*>() << account;
}
-QStringList IMAPSourceServer::retrieveUserList()
-{
- mSession = createSession(mHost, mPort, this);
-
- KIMAP::LoginJob *loginJob = new KIMAP::LoginJob( mSession );
- loginJob->setUserName( mUsername );
- loginJob->setPassword( mPw );
- loginJob->setEncryptionMode( mEncryptionMode );
- loginJob->setAuthenticationMode( mAuthenticationMode );
- loginJob->exec();
-
- if ( loginJob->error() ) {
- Warning() << "Failed to login: " << loginJob->errorString();
- } else {
- Debug() << "authentication successful";
- }
-
- GetUserListJob *userListJob = new GetUserListJob(mSession, this);
- userListJob->exec();
- const QStringList userList = userListJob->getUserList();
- logout();
-
- return userList;
-}
-
-
-void IMAPSourceServer::logout()
+UserListJob *IMAPSourceServer::retrieveUserList()
{
- Q_ASSERT(mSession);
- KIMAP::LogoutJob *logoutJob = new KIMAP::LogoutJob(mSession);
- logoutJob->exec();
- mSession->close();
- mSession->deleteLater();
- mSession = 0;
- Debug() << "logout done";
+ return new IMAPUserListJob(mHost, mPort, IMAPConnectionSettings(mUsername, mPw, mEncryptionMode, mAuthenticationMode), this);
}
-
//---------------------------------------------------------------------------
KolabSourceServer::KolabSourceServer(QObject* parent)
diff --git a/migrationutility/sourceserver.h b/migrationutility/sourceserver.h
index 08881d9..f3ab897 100644
--- a/migrationutility/sourceserver.h
+++ b/migrationutility/sourceserver.h
@@ -25,6 +25,34 @@
#include "sourceaccount.h"
/**
+ * Job interface to retrieve users from a server.
+ */
+class UserListJob: public KJob
+{
+ Q_OBJECT
+public:
+ explicit UserListJob(QObject* parent = 0);
+ virtual QStringList getUserList() const = 0;
+};
+
+class FixedUserListJob: public UserListJob
+{
+ Q_OBJECT
+public:
+ explicit FixedUserListJob(const QStringList &userList, QObject* parent = 0);
+ virtual void start();
+ virtual QStringList getUserList() const;
+
+private slots:
+ void doEmitResult();
+
+private:
+ QStringList mUserList;
+};
+
+
+
+/**
* The source server represents a server with user accounts that need to be migrated.
*
* The server can support multiple access protocols per user, that are each represented by a source account.
@@ -35,7 +63,7 @@ class SourceServer: public QObject
public:
explicit SourceServer(QObject* parent = 0);
QList<SourceAccount*> getSourceAccounts(const QString &user);
- QStringList getUserList();
+ UserListJob *listUsers();
void setSingleUser(const QString &);
void setStatefile(const QString &);
@@ -45,12 +73,12 @@ public:
void setIgnoredFolders(const QStringList &);
QStringList ignoredFolders() const;
protected:
+ virtual QList<SourceAccount*> getSourceAccountsImpl(const QString &user) = 0;
/**
* Reeimplement to retrieve a user list from the server.
* Note that the retrieved username is used to login to the users account on the source server.
*/
- virtual QStringList retrieveUserList();
- virtual QList<SourceAccount*> getSourceAccountsImpl(const QString &user) = 0;
+ virtual UserListJob *retrieveUserList();
QStringList mExplicitUsers;
QString mStatefile;
private:
@@ -66,10 +94,46 @@ public:
QStringList mUsers;
protected:
- virtual QStringList retrieveUserList();
+ virtual UserListJob *retrieveUserList();
virtual QList< SourceAccount* > getSourceAccountsImpl(const QString& user);
};
+class IMAPConnectionSettings {
+public:
+ IMAPConnectionSettings(const QString &username, const QString &pw, KIMAP::LoginJob::EncryptionMode encryptionMode, KIMAP::LoginJob::AuthenticationMode authenticationMode)
+ : mUsername(username), mPassword(pw), mEncryptionMode(encryptionMode), mAuthenticationMode(authenticationMode)
+ {}
+ QString username() const { return mUsername; }
+ QString password() const { return mPassword; }
+ KIMAP::LoginJob::EncryptionMode encryptionMode() const { return mEncryptionMode; }
+ KIMAP::LoginJob::AuthenticationMode authenticationMode() const { return mAuthenticationMode; }
+private:
+ const QString mUsername;
+ const QString mPassword;
+ const KIMAP::LoginJob::EncryptionMode mEncryptionMode;
+ const KIMAP::LoginJob::AuthenticationMode mAuthenticationMode;
+};
+
+class IMAPUserListJob: public UserListJob
+{
+ Q_OBJECT
+public:
+ explicit IMAPUserListJob(const QString &host, qint16 port, const IMAPConnectionSettings &settings, QObject* parent = 0);
+ virtual ~IMAPUserListJob();
+ virtual void start();
+ virtual QStringList getUserList() const;
+
+private slots:
+ void onLoginDone(KJob*);
+ void onUserListJobDone(KJob*);
+ void onLogoutDone(KJob*);
+
+private:
+ KIMAP::Session *mSession;
+ const IMAPConnectionSettings mConnectionSettings;
+ QStringList mUserList;
+};
+
class IMAPSourceServer: public SourceServer
{
Q_OBJECT
@@ -81,9 +145,8 @@ public:
void setEncryption(KIMAP::LoginJob::EncryptionMode);
void setAuthentication(KIMAP::LoginJob::AuthenticationMode);
protected:
- virtual QStringList retrieveUserList();
virtual QList< SourceAccount* > getSourceAccountsImpl(const QString& user);
- void logout();
+ virtual UserListJob *retrieveUserList();
KIMAP::Session *mSession;
QString mHost;
int mPort;
diff --git a/migrationutility/tests/exchangeimaptest.cpp b/migrationutility/tests/exchangeimaptest.cpp
index cf83b66..2d72459 100644
--- a/migrationutility/tests/exchangeimaptest.cpp
+++ b/migrationutility/tests/exchangeimaptest.cpp
@@ -183,7 +183,7 @@ void ExchangeIMAPTest::setupSourceAccount()
account->setWipeTargetFolders(true);
account->cleanAccount();
createFolders(account, folders);
- account->logout();
+ QVERIFY(account->logout()->exec());
}
void ExchangeIMAPTest::setupTargetAccount()
@@ -195,7 +195,7 @@ void ExchangeIMAPTest::setupTargetAccount()
KolabAccount *account = kolabServer->getAccount(user);
account->setWipeTargetFolders(true);
account->cleanAccount();
- account->logout();
+ QVERIFY(account->logout()->exec());
}
void ExchangeIMAPTest::executeMigration()
diff --git a/migrationutility/tests/migrationscenariotest.cpp b/migrationutility/tests/migrationscenariotest.cpp
index 1b7ec66..e4c441f 100644
--- a/migrationutility/tests/migrationscenariotest.cpp
+++ b/migrationutility/tests/migrationscenariotest.cpp
@@ -93,7 +93,7 @@ void MigrationScenarioTest::executeMigration(bool useStatefile)
kolabServer->setAdminCredentials(admin, adminpw);
CoordinationJob *job = new CoordinationJob(kolabSourceServer, kolabServer, &obj);
- job->exec();
+ QVERIFY(job->exec());
}
void MigrationScenarioTest::checkFolders(SourceAccount *account, const QList<Folder> &folders)
@@ -134,7 +134,7 @@ void MigrationScenarioTest::checkTargetAccount()
SourceAccount *account = kolabSourceServer->getSourceAccounts(user).first();
QVERIFY(account->login()->exec());
checkFolders(account, folders);
- account->logout();
+ QVERIFY(account->logout()->exec());
}
void MigrationScenarioTest::checkSourceAccount()
diff --git a/migrationutility/tests/migrationtest.cpp b/migrationutility/tests/migrationtest.cpp
index ffc8c7d..f29b946 100644
--- a/migrationutility/tests/migrationtest.cpp
+++ b/migrationutility/tests/migrationtest.cpp
@@ -29,7 +29,7 @@ void MigrationTest::testUsersProcessed()
KolabServer *kolabServer = new KolabServer(this);
kolabServer->setDryRun(true);
CoordinationJob *job = new CoordinationJob(server, kolabServer, this);
- job->exec();
+ QVERIFY(job->exec());
QVERIFY(server->mUsers.isEmpty());
}
@@ -39,7 +39,7 @@ void MigrationTest::testFoldersProcessed()
KolabAccount *kolabTargetAccount = new KolabAccount(this);
kolabTargetAccount->setDryRun(true);
MigrateUserJob *job = new MigrateUserJob(QList<SourceAccount*>() << testSourceAccount, kolabTargetAccount, this);
- job->exec();
+ QVERIFY(job->exec());
QVERIFY(testSourceAccount->mFolderList.isEmpty());
}