From 938554f267193b652478fc12343819fa45d76034 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 28 Nov 2016 19:33:01 +0100 Subject: Moved inspection commands to a separate inspector. --- examples/dummyresource/resourcefactory.cpp | 44 +-- examples/dummyresource/resourcefactory.h | 1 - examples/imapresource/imapresource.cpp | 306 +++++++++++---------- examples/imapresource/imapresource.h | 7 - examples/maildirresource/maildirresource.cpp | 185 +++++++------ examples/maildirresource/maildirresource.h | 3 +- .../mailtransportresource.cpp | 48 ++-- .../mailtransportresource/mailtransportresource.h | 2 - 8 files changed, 318 insertions(+), 278 deletions(-) (limited to 'examples') diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index f5ab2d9..8e81c79 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp @@ -37,6 +37,7 @@ #include "facadefactory.h" #include "adaptorfactoryregistry.h" #include "synchronizer.h" +#include "inspector.h" #include "mailpreprocessor.h" #include "remoteidmap.h" #include @@ -130,10 +131,36 @@ class DummySynchronizer : public Sink::Synchronizer { }; +class DummyInspector : public Sink::Inspector { +public: + DummyInspector(const Sink::ResourceContext &resourceContext) + : Sink::Inspector(resourceContext) + { + + } + +protected: + KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE + { + SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; + if (property == "testInspection") { + if (expectedValue.toBool()) { + //Success + return KAsync::null(); + } else { + //Failure + return KAsync::error(1, "Failed."); + } + } + return KAsync::null(); + } +}; + DummyResource::DummyResource(const Sink::ResourceContext &resourceContext, const QSharedPointer &pipeline) : Sink::GenericResource(resourceContext, pipeline) { setupSynchronizer(QSharedPointer::create(resourceContext)); + setupInspector(QSharedPointer::create(resourceContext)); setupPreprocessors(ENTITY_TYPE_MAIL, QVector() << new MailPropertyExtractor); setupPreprocessors(ENTITY_TYPE_FOLDER, @@ -159,23 +186,6 @@ KAsync::Job DummyResource::synchronizeWithSource(const Sink::QueryBase &qu return GenericResource::synchronizeWithSource(query); } -KAsync::Job DummyResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) -{ - - SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; - if (property == "testInspection") { - if (expectedValue.toBool()) { - //Success - return KAsync::null(); - } else { - //Failure - return KAsync::error(1, "Failed."); - } - } - return KAsync::null(); -} - - DummyResourceFactory::DummyResourceFactory(QObject *parent) : Sink::ResourceFactory(parent) { diff --git a/examples/dummyresource/resourcefactory.h b/examples/dummyresource/resourcefactory.h index 8ef27a6..2eb7558 100644 --- a/examples/dummyresource/resourcefactory.h +++ b/examples/dummyresource/resourcefactory.h @@ -33,7 +33,6 @@ public: virtual ~DummyResource(); KAsync::Job synchronizeWithSource(const Sink::QueryBase &) Q_DECL_OVERRIDE; - KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; }; class DummyResourceFactory : public Sink::ResourceFactory diff --git a/examples/imapresource/imapresource.cpp b/examples/imapresource/imapresource.cpp index 2aa5a2c..40fa75f 100644 --- a/examples/imapresource/imapresource.cpp +++ b/examples/imapresource/imapresource.cpp @@ -27,6 +27,7 @@ #include "definitions.h" #include "inspection.h" #include "synchronizer.h" +#include "inspector.h" #include "remoteidmap.h" #include "query.h" @@ -553,169 +554,192 @@ public: QByteArray mResourceInstanceIdentifier; }; -ImapResource::ImapResource(const ResourceContext &resourceContext) - : Sink::GenericResource(resourceContext) -{ - auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); - mServer = config.value("server").toString(); - mPort = config.value("port").toInt(); - mUser = config.value("username").toString(); - mPassword = config.value("password").toString(); - if (mServer.startsWith("imap")) { - mServer.remove("imap://"); - mServer.remove("imaps://"); - } - if (mServer.contains(':')) { - auto list = mServer.split(':'); - mServer = list.at(0); - mPort = list.at(1).toInt(); - } - - auto synchronizer = QSharedPointer::create(resourceContext); - synchronizer->mServer = mServer; - synchronizer->mPort = mPort; - synchronizer->mUser = mUser; - synchronizer->mPassword = mPassword; - setupSynchronizer(synchronizer); - - setupPreprocessors(ENTITY_TYPE_MAIL, QVector() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MimeMessageMover << new MailPropertyExtractor); - setupPreprocessors(ENTITY_TYPE_FOLDER, QVector()); -} +class ImapInspector : public Sink::Inspector { +public: + ImapInspector(const Sink::ResourceContext &resourceContext) + : Sink::Inspector(resourceContext) + { -KAsync::Job ImapResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) -{ - auto synchronizationStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly); - auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); + } - auto mainStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); - auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); +protected: + KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE { + auto synchronizationStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly); + auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); - Sink::Storage::EntityStore entityStore(mResourceContext); - auto syncStore = QSharedPointer::create(synchronizationTransaction); + auto mainStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); + auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); - SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; + Sink::Storage::EntityStore entityStore(mResourceContext); + auto syncStore = QSharedPointer::create(synchronizationTransaction); - if (domainType == ENTITY_TYPE_MAIL) { - const auto mail = entityStore.readLatest(entityId); - const auto folder = entityStore.readLatest(mail.getFolder()); - const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); - const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); - if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) { - SinkWarning() << "Missing remote id for folder or mail. " << mailRemoteId << folderRemoteId; - return KAsync::error(); - } - const auto uid = uidFromMailRid(mailRemoteId); - SinkTrace() << "Mail remote id: " << folderRemoteId << mailRemoteId << mail.identifier() << folder.identifier(); + SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; - KIMAP2::ImapSet set; - set.add(uid); - if (set.isEmpty()) { - return KAsync::error(1, "Couldn't determine uid of mail."); - } - KIMAP2::FetchJob::FetchScope scope; - scope.mode = KIMAP2::FetchJob::FetchScope::Full; - auto imap = QSharedPointer::create(mServer, mPort); - auto messageByUid = QSharedPointer>::create(); - SinkTrace() << "Connecting to:" << mServer << mPort; - SinkTrace() << "as:" << mUser; - auto inspectionJob = imap->login(mUser, mPassword) - .then(imap->select(folderRemoteId)) - .syncThen([](Imap::SelectResult){}) - .then(imap->fetch(set, scope, [imap, messageByUid](const Imap::Message &message) { - messageByUid->insert(message.uid, message); - })); - - if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { - if (property == "unread") { - return inspectionJob.then([=]() { - auto msg = messageByUid->value(uid); - if (expectedValue.toBool() && msg.flags.contains(Imap::Flags::Seen)) { - return KAsync::error(1, "Expected unread but couldn't find it."); - } - if (!expectedValue.toBool() && !msg.flags.contains(Imap::Flags::Seen)) { - return KAsync::error(1, "Expected read but couldn't find it."); - } - return KAsync::null(); - }); - } - if (property == "subject") { - return inspectionJob.then([=]() { - auto msg = messageByUid->value(uid); - if (msg.msg->subject(true)->asUnicodeString() != expectedValue.toString()) { - return KAsync::error(1, "Subject not as expected: " + msg.msg->subject(true)->asUnicodeString()); - } - return KAsync::null(); - }); + if (domainType == ENTITY_TYPE_MAIL) { + const auto mail = entityStore.readLatest(entityId); + const auto folder = entityStore.readLatest(mail.getFolder()); + const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); + const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); + if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) { + SinkWarning() << "Missing remote id for folder or mail. " << mailRemoteId << folderRemoteId; + return KAsync::error(); } - } - if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { - return inspectionJob.then([=]() { - if (!messageByUid->contains(uid)) { - SinkWarning() << "Existing messages are: " << messageByUid->keys(); - SinkWarning() << "We're looking for: " << uid; - return KAsync::error(1, "Couldn't find message: " + mailRemoteId); - } - return KAsync::null(); - }); - } - } - if (domainType == ENTITY_TYPE_FOLDER) { - const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); - const auto folder = entityStore.readLatest(entityId); - - if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { - SinkLog() << "Inspecting cache integrity" << remoteId; + const auto uid = uidFromMailRid(mailRemoteId); + SinkTrace() << "Mail remote id: " << folderRemoteId << mailRemoteId << mail.identifier() << folder.identifier(); - int expectedCount = 0; - Index index("mail.index.folder", transaction); - index.lookup(entityId, [&](const QByteArray &sinkId) { - expectedCount++; - }, - [&](const Index::Error &error) { - SinkWarning() << "Error in index: " << error.message << property; - }); - - auto set = KIMAP2::ImapSet::fromImapSequenceSet("1:*"); + KIMAP2::ImapSet set; + set.add(uid); + if (set.isEmpty()) { + return KAsync::error(1, "Couldn't determine uid of mail."); + } KIMAP2::FetchJob::FetchScope scope; - scope.mode = KIMAP2::FetchJob::FetchScope::Headers; + scope.mode = KIMAP2::FetchJob::FetchScope::Full; auto imap = QSharedPointer::create(mServer, mPort); auto messageByUid = QSharedPointer>::create(); - return imap->login(mUser, mPassword) - .then(imap->select(remoteId).syncThen([](){})) - .then(imap->fetch(set, scope, [=](const Imap::Message message) { + SinkTrace() << "Connecting to:" << mServer << mPort; + SinkTrace() << "as:" << mUser; + auto inspectionJob = imap->login(mUser, mPassword) + .then(imap->select(folderRemoteId)) + .syncThen([](Imap::SelectResult){}) + .then(imap->fetch(set, scope, [imap, messageByUid](const Imap::Message &message) { messageByUid->insert(message.uid, message); - })) - .then([imap, messageByUid, expectedCount]() { - if (messageByUid->size() != expectedCount) { - return KAsync::error(1, QString("Wrong number of messages on the server; found %1 instead of %2.").arg(messageByUid->size()).arg(expectedCount)); + })); + + if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { + if (property == "unread") { + return inspectionJob.then([=]() { + auto msg = messageByUid->value(uid); + if (expectedValue.toBool() && msg.flags.contains(Imap::Flags::Seen)) { + return KAsync::error(1, "Expected unread but couldn't find it."); + } + if (!expectedValue.toBool() && !msg.flags.contains(Imap::Flags::Seen)) { + return KAsync::error(1, "Expected read but couldn't find it."); + } + return KAsync::null(); + }); + } + if (property == "subject") { + return inspectionJob.then([=]() { + auto msg = messageByUid->value(uid); + if (msg.msg->subject(true)->asUnicodeString() != expectedValue.toString()) { + return KAsync::error(1, "Subject not as expected: " + msg.msg->subject(true)->asUnicodeString()); + } + return KAsync::null(); + }); + } + } + if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { + return inspectionJob.then([=]() { + if (!messageByUid->contains(uid)) { + SinkWarning() << "Existing messages are: " << messageByUid->keys(); + SinkWarning() << "We're looking for: " << uid; + return KAsync::error(1, "Couldn't find message: " + mailRemoteId); } return KAsync::null(); }); + } } - if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { - auto folderByPath = QSharedPointer>::create(); - auto folderByName = QSharedPointer>::create(); + if (domainType == ENTITY_TYPE_FOLDER) { + const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); + const auto folder = entityStore.readLatest(entityId); - auto imap = QSharedPointer::create(mServer, mPort); - auto inspectionJob = imap->login(mUser, mPassword) - .then(imap->fetchFolders([=](const Imap::Folder &f) { - *folderByPath << f.normalizedPath(); - *folderByName << f.name(); - })) - .then([this, folderByName, folderByPath, folder, remoteId, imap]() { - if (!folderByName->contains(folder.getName())) { - SinkWarning() << "Existing folders are: " << *folderByPath; - SinkWarning() << "We're looking for: " << folder.getName(); - return KAsync::error(1, "Wrong folder name: " + remoteId); - } - return KAsync::null(); + if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { + SinkLog() << "Inspecting cache integrity" << remoteId; + + int expectedCount = 0; + Index index("mail.index.folder", transaction); + index.lookup(entityId, [&](const QByteArray &sinkId) { + expectedCount++; + }, + [&](const Index::Error &error) { + SinkWarning() << "Error in index: " << error.message << property; }); - return inspectionJob; + auto set = KIMAP2::ImapSet::fromImapSequenceSet("1:*"); + KIMAP2::FetchJob::FetchScope scope; + scope.mode = KIMAP2::FetchJob::FetchScope::Headers; + auto imap = QSharedPointer::create(mServer, mPort); + auto messageByUid = QSharedPointer>::create(); + return imap->login(mUser, mPassword) + .then(imap->select(remoteId).syncThen([](){})) + .then(imap->fetch(set, scope, [=](const Imap::Message message) { + messageByUid->insert(message.uid, message); + })) + .then([imap, messageByUid, expectedCount]() { + if (messageByUid->size() != expectedCount) { + return KAsync::error(1, QString("Wrong number of messages on the server; found %1 instead of %2.").arg(messageByUid->size()).arg(expectedCount)); + } + return KAsync::null(); + }); + } + if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { + auto folderByPath = QSharedPointer>::create(); + auto folderByName = QSharedPointer>::create(); + + auto imap = QSharedPointer::create(mServer, mPort); + auto inspectionJob = imap->login(mUser, mPassword) + .then(imap->fetchFolders([=](const Imap::Folder &f) { + *folderByPath << f.normalizedPath(); + *folderByName << f.name(); + })) + .then([this, folderByName, folderByPath, folder, remoteId, imap]() { + if (!folderByName->contains(folder.getName())) { + SinkWarning() << "Existing folders are: " << *folderByPath; + SinkWarning() << "We're looking for: " << folder.getName(); + return KAsync::error(1, "Wrong folder name: " + remoteId); + } + return KAsync::null(); + }); + + return inspectionJob; + } + } + return KAsync::null(); + } + +public: + QString mServer; + int mPort; + QString mUser; + QString mPassword; +}; + +ImapResource::ImapResource(const ResourceContext &resourceContext) + : Sink::GenericResource(resourceContext) +{ + auto config = ResourceConfig::getConfiguration(resourceContext.instanceId()); + auto server = config.value("server").toString(); + auto port = config.value("port").toInt(); + auto user = config.value("username").toString(); + auto password = config.value("password").toString(); + if (server.startsWith("imap")) { + server.remove("imap://"); + server.remove("imaps://"); + } + if (server.contains(':')) { + auto list = server.split(':'); + server = list.at(0); + port = list.at(1).toInt(); } - return KAsync::null(); + + auto synchronizer = QSharedPointer::create(resourceContext); + synchronizer->mServer = server; + synchronizer->mPort = port; + synchronizer->mUser = user; + synchronizer->mPassword = password; + setupSynchronizer(synchronizer); + + auto inspector = QSharedPointer::create(resourceContext); + inspector->mServer = server; + inspector->mPort = port; + inspector->mUser = user; + inspector->mPassword = password; + setupInspector(inspector); + + setupPreprocessors(ENTITY_TYPE_MAIL, QVector() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MimeMessageMover << new MailPropertyExtractor); + setupPreprocessors(ENTITY_TYPE_FOLDER, QVector()); } ImapResourceFactory::ImapResourceFactory(QObject *parent) diff --git a/examples/imapresource/imapresource.h b/examples/imapresource/imapresource.h index d345d64..aeb1200 100644 --- a/examples/imapresource/imapresource.h +++ b/examples/imapresource/imapresource.h @@ -40,13 +40,6 @@ class ImapResource : public Sink::GenericResource { public: ImapResource(const Sink::ResourceContext &resourceContext); - KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; - -private: - QString mServer; - int mPort; - QString mUser; - QString mPassword; }; class ImapResourceFactory : public Sink::ResourceFactory diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index ee84bde..2b19789 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp @@ -27,6 +27,7 @@ #include "libmaildir/maildir.h" #include "inspection.h" #include "synchronizer.h" +#include "inspector.h" #include "facadefactory.h" #include "adaptorfactoryregistry.h" @@ -425,6 +426,102 @@ public: QString mMaildirPath; }; +class MaildirInspector : public Sink::Inspector { +public: + MaildirInspector(const Sink::ResourceContext &resourceContext) + : Sink::Inspector(resourceContext) + { + + } +protected: + + KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE { + auto synchronizationStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly); + auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); + + auto mainStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); + auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); + + Sink::Storage::EntityStore entityStore(mResourceContext); + auto syncStore = QSharedPointer::create(synchronizationTransaction); + + SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; + + if (domainType == ENTITY_TYPE_MAIL) { + auto mail = entityStore.readLatest(entityId); + const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); + + if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { + if (property == "unread") { + const auto flags = KPIM::Maildir::readEntryFlags(filePath.split('/').last()); + if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) { + return KAsync::error(1, "Expected unread but couldn't find it."); + } + if (!expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) { + return KAsync::error(1, "Expected read but couldn't find it."); + } + return KAsync::null(); + } + if (property == "subject") { + KMime::Message *msg = new KMime::Message; + msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath))); + msg->parse(); + + if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) { + return KAsync::error(1, "Subject not as expected: " + msg->subject(true)->asUnicodeString()); + } + return KAsync::null(); + } + } + if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { + if (QFileInfo(filePath).exists() != expectedValue.toBool()) { + return KAsync::error(1, "Wrong file existence: " + filePath); + } + } + } + if (domainType == ENTITY_TYPE_FOLDER) { + const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); + auto folder = entityStore.readLatest(entityId); + + if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { + SinkTrace() << "Inspecting cache integrity" << remoteId; + if (!QDir(remoteId).exists()) { + return KAsync::error(1, "The directory is not existing: " + remoteId); + } + + int expectedCount = 0; + Index index("mail.index.folder", transaction); + index.lookup(entityId, [&](const QByteArray &sinkId) { + expectedCount++; + }, + [&](const Index::Error &error) { + SinkWarning() << "Error in index: " << error.message << property; + }); + + QDir dir(remoteId + "/cur"); + const QFileInfoList list = dir.entryInfoList(QDir::Files); + if (list.size() != expectedCount) { + for (const auto &fileInfo : list) { + SinkWarning() << "Found in cache: " << fileInfo.fileName(); + } + return KAsync::error(1, QString("Wrong number of files; found %1 instead of %2.").arg(list.size()).arg(expectedCount)); + } + } + if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { + if (!remoteId.endsWith(folder.getName().toUtf8())) { + return KAsync::error(1, "Wrong folder name: " + remoteId); + } + //TODO we shouldn't use the remoteId here to figure out the path, it could be gone/changed already + if (QDir(remoteId).exists() != expectedValue.toBool()) { + return KAsync::error(1, "Wrong folder existence: " + remoteId); + } + } + + } + return KAsync::null(); + } +}; + MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext) : Sink::GenericResource(resourceContext) @@ -439,6 +536,7 @@ MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext) auto synchronizer = QSharedPointer::create(resourceContext); synchronizer->mMaildirPath = mMaildirPath; setupSynchronizer(synchronizer); + setupInspector(QSharedPointer::create(resourceContext)); setupPreprocessors(ENTITY_TYPE_MAIL, QVector() << new SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) << new MaildirMimeMessageMover(resourceContext.instanceId(), mMaildirPath) << new MaildirMailPropertyExtractor); setupPreprocessors(ENTITY_TYPE_FOLDER, QVector() << new FolderPreprocessor(mMaildirPath)); @@ -458,93 +556,6 @@ MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext) synchronizer->commit(); } -KAsync::Job MaildirResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) -{ - auto synchronizationStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId() + ".synchronization", Sink::Storage::DataStore::ReadOnly); - auto synchronizationTransaction = synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); - - auto mainStore = QSharedPointer::create(Sink::storageLocation(), mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); - auto transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); - - Sink::Storage::EntityStore entityStore(mResourceContext); - auto syncStore = QSharedPointer::create(synchronizationTransaction); - - SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; - - if (domainType == ENTITY_TYPE_MAIL) { - auto mail = entityStore.readLatest(entityId); - const auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); - - if (inspectionType == Sink::ResourceControl::Inspection::PropertyInspectionType) { - if (property == "unread") { - const auto flags = KPIM::Maildir::readEntryFlags(filePath.split('/').last()); - if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) { - return KAsync::error(1, "Expected unread but couldn't find it."); - } - if (!expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) { - return KAsync::error(1, "Expected read but couldn't find it."); - } - return KAsync::null(); - } - if (property == "subject") { - KMime::Message *msg = new KMime::Message; - msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath))); - msg->parse(); - - if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) { - return KAsync::error(1, "Subject not as expected: " + msg->subject(true)->asUnicodeString()); - } - return KAsync::null(); - } - } - if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { - if (QFileInfo(filePath).exists() != expectedValue.toBool()) { - return KAsync::error(1, "Wrong file existence: " + filePath); - } - } - } - if (domainType == ENTITY_TYPE_FOLDER) { - const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, entityId); - auto folder = entityStore.readLatest(entityId); - - if (inspectionType == Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { - SinkTrace() << "Inspecting cache integrity" << remoteId; - if (!QDir(remoteId).exists()) { - return KAsync::error(1, "The directory is not existing: " + remoteId); - } - - int expectedCount = 0; - Index index("mail.index.folder", transaction); - index.lookup(entityId, [&](const QByteArray &sinkId) { - expectedCount++; - }, - [&](const Index::Error &error) { - SinkWarning() << "Error in index: " << error.message << property; - }); - - QDir dir(remoteId + "/cur"); - const QFileInfoList list = dir.entryInfoList(QDir::Files); - if (list.size() != expectedCount) { - for (const auto &fileInfo : list) { - SinkWarning() << "Found in cache: " << fileInfo.fileName(); - } - return KAsync::error(1, QString("Wrong number of files; found %1 instead of %2.").arg(list.size()).arg(expectedCount)); - } - } - if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { - if (!remoteId.endsWith(folder.getName().toUtf8())) { - return KAsync::error(1, "Wrong folder name: " + remoteId); - } - //TODO we shouldn't use the remoteId here to figure out the path, it could be gone/changed already - if (QDir(remoteId).exists() != expectedValue.toBool()) { - return KAsync::error(1, "Wrong folder existence: " + remoteId); - } - } - - } - return KAsync::null(); -} - MaildirResourceFactory::MaildirResourceFactory(QObject *parent) : Sink::ResourceFactory(parent) diff --git a/examples/maildirresource/maildirresource.h b/examples/maildirresource/maildirresource.h index 4eb2042..61fe438 100644 --- a/examples/maildirresource/maildirresource.h +++ b/examples/maildirresource/maildirresource.h @@ -43,9 +43,8 @@ class MaildirResource : public Sink::GenericResource { public: MaildirResource(const Sink::ResourceContext &resourceContext); - KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; -private: +private: QStringList listAvailableFolders(); QString mMaildirPath; QString mDraftsFolder; diff --git a/examples/mailtransportresource/mailtransportresource.cpp b/examples/mailtransportresource/mailtransportresource.cpp index c135de9..524b411 100644 --- a/examples/mailtransportresource/mailtransportresource.cpp +++ b/examples/mailtransportresource/mailtransportresource.cpp @@ -22,7 +22,7 @@ #include "facadefactory.h" #include "resourceconfig.h" #include "definitions.h" -#include "domainadaptor.h" +#include "inspector.h" #include #include #include @@ -124,6 +124,31 @@ public: MailtransportResource::Settings mSettings; }; +class MailtransportInspector : public Sink::Inspector { +public: + MailtransportInspector(const Sink::ResourceContext &resourceContext) + : Sink::Inspector(resourceContext) + { + + } + +protected: + KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE + { + if (domainType == ENTITY_TYPE_MAIL) { + if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { + auto path = resourceStorageLocation(mResourceContext.instanceId()) + "/test/" + entityId; + if (QFileInfo::exists(path)) { + return KAsync::null(); + } + return KAsync::error(1, "Couldn't find message: " + path); + } + } + return KAsync::null(); + } +}; + + MailtransportResource::MailtransportResource(const Sink::ResourceContext &resourceContext) : Sink::GenericResource(resourceContext) { @@ -138,30 +163,11 @@ MailtransportResource::MailtransportResource(const Sink::ResourceContext &resour auto synchronizer = QSharedPointer::create(resourceContext); synchronizer->mSettings = mSettings; setupSynchronizer(synchronizer); + setupInspector(QSharedPointer::create(resourceContext)); setupPreprocessors(ENTITY_TYPE_MAIL, QVector() << new MimeMessageMover << new MailPropertyExtractor); } -void MailtransportResource::removeFromDisk(const QByteArray &instanceIdentifier) -{ - GenericResource::removeFromDisk(instanceIdentifier); - Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::DataStore::ReadWrite).removeFromDisk(); -} - -KAsync::Job MailtransportResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) -{ - if (domainType == ENTITY_TYPE_MAIL) { - if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) { - auto path = resourceStorageLocation(mResourceContext.instanceId()) + "/test/" + entityId; - if (QFileInfo::exists(path)) { - return KAsync::null(); - } - return KAsync::error(1, "Couldn't find message: " + path); - } - } - return KAsync::null(); -} - MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent) : Sink::ResourceFactory(parent) { diff --git a/examples/mailtransportresource/mailtransportresource.h b/examples/mailtransportresource/mailtransportresource.h index 95a9cd7..531fcd5 100644 --- a/examples/mailtransportresource/mailtransportresource.h +++ b/examples/mailtransportresource/mailtransportresource.h @@ -26,8 +26,6 @@ class MailtransportResource : public Sink::GenericResource { public: MailtransportResource(const Sink::ResourceContext &resourceContext); - KAsync::Job inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE; - static void removeFromDisk(const QByteArray &instanceIdentifier); struct Settings { QString server; -- cgit v1.2.3