From f3eb97b9b4aabef41d8bc6514c74d85600e60d7f Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sat, 2 Sep 2017 15:59:51 -0600 Subject: Ensure we monitor resources for status changes that have been created after the query. This fixes status monitoring when creating a new account. --- common/resourcefacade.cpp | 48 +++++++++++++++++++++++++++++++++++------------ common/resourcefacade.h | 1 + tests/accountstest.cpp | 34 +++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp index 829375c..0687bbc 100644 --- a/common/resourcefacade.cpp +++ b/common/resourcefacade.cpp @@ -24,6 +24,7 @@ #include "store.h" #include "resourceaccess.h" #include "resource.h" +#include "facadefactory.h" using namespace Sink; @@ -358,27 +359,50 @@ QPair, typename Sink::ResultEmitter(query, mIdentifier, mTypeName, sConfigNotifier, ctx); auto monitoredResources = QSharedPointer>::create(); - runner->setStatusUpdater([runner, monitoredResources, ctx](ApplicationDomain::SinkAccount &account) { - Query query; + auto monitorResource = [monitoredResources, runner, ctx] (const QByteArray &accountIdentifier, const ApplicationDomain::SinkResource &resource, const ResourceAccess::Ptr &resourceAccess) { + if (!monitoredResources->contains(resource.identifier())) { + auto ret = QObject::connect(resourceAccess.data(), &ResourceAccess::notification, runner->guard(), [resource, runner, resourceAccess, accountIdentifier, ctx](const Notification ¬ification) { + SinkTraceCtx(ctx) << "Received notification in facade: " << notification.type; + if (notification.type == Notification::Status) { + runner->statusChanged(accountIdentifier); + } + }); + Q_ASSERT(ret); + monitoredResources->insert(resource.identifier()); + } + }; + runner->setStatusUpdater([this, runner, monitoredResources, ctx, monitorResource](ApplicationDomain::SinkAccount &account) { + Query query{Query::LiveQuery}; query.filter(account.identifier()); query.request() .request(); const auto resources = Store::read(query); SinkTraceCtx(ctx) << "Found resource belonging to the account " << account.identifier() << " : " << resources; auto accountIdentifier = account.identifier(); + + //Monitor for new resources so they can be monitored as well + if (!runner->mResourceEmitter.contains(accountIdentifier)) { + auto facade = Sink::FacadeFactory::instance().getFacade(); + Q_ASSERT(facade); + + auto emitter = facade->load(query, ctx).second; + emitter->onAdded([=](const ApplicationDomain::SinkResource::Ptr &resource) { + auto resourceAccess = Sink::ResourceAccessFactory::instance().getAccess(resource->identifier(), ResourceConfig::getResourceType(resource->identifier())); + monitorResource(accountIdentifier, *resource, resourceAccess); + }); + emitter->onModified([](const ApplicationDomain::SinkResource::Ptr &) {}); + emitter->onRemoved([](const ApplicationDomain::SinkResource::Ptr &) {}); + emitter->onInitialResultSetComplete([](const ApplicationDomain::SinkResource::Ptr &, bool) {}); + emitter->onComplete([]() {}); + emitter->fetch({}); + runner->mResourceEmitter[accountIdentifier] = emitter; + } + QList states; + //Gather all resources and ensure they are monitored for (const auto &resource : resources) { auto resourceAccess = ResourceAccessFactory::instance().getAccess(resource.identifier(), ResourceConfig::getResourceType(resource.identifier())); - if (!monitoredResources->contains(resource.identifier())) { - auto ret = QObject::connect(resourceAccess.data(), &ResourceAccess::notification, runner->guard(), [resource, runner, resourceAccess, accountIdentifier, ctx](const Notification ¬ification) { - SinkTraceCtx(ctx) << "Received notification in facade: " << notification.type; - if (notification.type == Notification::Status) { - runner->statusChanged(accountIdentifier); - } - }); - Q_ASSERT(ret); - monitoredResources->insert(resource.identifier()); - } + monitorResource(accountIdentifier, resource, resourceAccess); states << resourceAccess->getResourceStatus(); } const auto status = [&] { diff --git a/common/resourcefacade.h b/common/resourcefacade.h index 76fadce..36049c4 100644 --- a/common/resourcefacade.h +++ b/common/resourcefacade.h @@ -65,6 +65,7 @@ public: void setStatusUpdater(const std::function &); void statusChanged(const QByteArray &identifier); QObject *guard() const; + QMap > > > mResourceEmitter; private: void updateStatus(DomainType &entity); diff --git a/tests/accountstest.cpp b/tests/accountstest.cpp index cc67645..2eee9f9 100644 --- a/tests/accountstest.cpp +++ b/tests/accountstest.cpp @@ -148,6 +148,40 @@ private slots: } } + void testLoadAccountStatusLive() + { + using namespace Sink; + using namespace Sink::ApplicationDomain; + + { + //Create a live query for all accounts + Sink::Query query; + query.setFlags(Query::LiveQuery); + query.request(); + + auto model = Sink::Store::loadModel(query); + + //Create the account + auto account = ApplicationDomainType::createEntity(); + account.setAccountType("dummy"); + account.setName("name"); + VERIFYEXEC(Store::create(account)); + + auto res = Sink::ApplicationDomain::DummyResource::create(account.identifier()); + VERIFYEXEC(Sink::Store::create(res)); + + //Ensure the account was created + QTRY_COMPARE(model->rowCount(QModelIndex()), 1); + auto retrievedAccount = model->data(model->index(0, 0, QModelIndex()), Sink::Store::DomainObjectRole).value(); + QCOMPARE(retrievedAccount->getStatus(), static_cast(Sink::ApplicationDomain::NoStatus)); + + //Synchronize to connect and ensure we receive the update + VERIFYEXEC(Sink::Store::synchronize(Query().resourceFilter(res.identifier()))); + + QTRY_COMPARE_WITH_TIMEOUT(model->data(model->index(0, 0, QModelIndex()), Sink::Store::DomainObjectRole).value()->getStatus(), static_cast(Sink::ApplicationDomain::ConnectedStatus), 1000); + } + } + }; QTEST_GUILESS_MAIN(AccountsTest) -- cgit v1.2.3