summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-06-17 17:34:34 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-06-17 17:34:34 +0200
commit207effdd7112141ad4fc5cdd46f332870a0c065c (patch)
treeb750cbecda149b4a4ae86eb156e59f4a070bbb5c
parentb2f52e3ffc5b2305f5275f18376daac7612f2e7b (diff)
downloadsink-207effdd7112141ad4fc5cdd46f332870a0c065c.tar.gz
sink-207effdd7112141ad4fc5cdd46f332870a0c065c.zip
A working mailtransport resource
-rw-r--r--common/domain/applicationdomaintype.h1
-rw-r--r--common/domain/mail.cpp2
-rw-r--r--common/domain/mail.fbs1
-rw-r--r--common/synchronizer.cpp20
-rw-r--r--common/synchronizer.h7
-rw-r--r--examples/mailtransportresource/mailtransportresource.cpp70
-rw-r--r--examples/mailtransportresource/tests/mailtransporttest.cpp20
7 files changed, 77 insertions, 44 deletions
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h
index 12a9e56..928ea58 100644
--- a/common/domain/applicationdomaintype.h
+++ b/common/domain/applicationdomaintype.h
@@ -211,6 +211,7 @@ struct SINK_EXPORT Mail : public Entity {
211 SINK_BLOB_PROPERTY(MimeMessage, mimeMessage); 211 SINK_BLOB_PROPERTY(MimeMessage, mimeMessage);
212 SINK_PROPERTY(bool, Draft, draft); 212 SINK_PROPERTY(bool, Draft, draft);
213 SINK_PROPERTY(bool, Trash, trash); 213 SINK_PROPERTY(bool, Trash, trash);
214 SINK_PROPERTY(bool, Sent, sent);
214}; 215};
215 216
216/** 217/**
diff --git a/common/domain/mail.cpp b/common/domain/mail.cpp
index dd4eca8..5b35a9a 100644
--- a/common/domain/mail.cpp
+++ b/common/domain/mail.cpp
@@ -86,6 +86,7 @@ QSharedPointer<ReadPropertyMapper<TypeImplementation<Mail>::Buffer> > TypeImplem
86 propertyMapper->addMapping<Mail::MimeMessage, Buffer>(&Buffer::mimeMessage); 86 propertyMapper->addMapping<Mail::MimeMessage, Buffer>(&Buffer::mimeMessage);
87 propertyMapper->addMapping<Mail::Draft, Buffer>(&Buffer::draft); 87 propertyMapper->addMapping<Mail::Draft, Buffer>(&Buffer::draft);
88 propertyMapper->addMapping<Mail::Trash, Buffer>(&Buffer::trash); 88 propertyMapper->addMapping<Mail::Trash, Buffer>(&Buffer::trash);
89 propertyMapper->addMapping<Mail::Sent, Buffer>(&Buffer::sent);
89 return propertyMapper; 90 return propertyMapper;
90} 91}
91 92
@@ -104,5 +105,6 @@ QSharedPointer<WritePropertyMapper<TypeImplementation<Mail>::BufferBuilder> > Ty
104 propertyMapper->addMapping<Mail::MimeMessage>(&BufferBuilder::add_mimeMessage); 105 propertyMapper->addMapping<Mail::MimeMessage>(&BufferBuilder::add_mimeMessage);
105 propertyMapper->addMapping<Mail::Draft>(&BufferBuilder::add_draft); 106 propertyMapper->addMapping<Mail::Draft>(&BufferBuilder::add_draft);
106 propertyMapper->addMapping<Mail::Trash>(&BufferBuilder::add_trash); 107 propertyMapper->addMapping<Mail::Trash>(&BufferBuilder::add_trash);
108 propertyMapper->addMapping<Mail::Sent>(&BufferBuilder::add_sent);
107 return propertyMapper; 109 return propertyMapper;
108} 110}
diff --git a/common/domain/mail.fbs b/common/domain/mail.fbs
index 3a84ca1..a0c0d82 100644
--- a/common/domain/mail.fbs
+++ b/common/domain/mail.fbs
@@ -12,6 +12,7 @@ table Mail {
12 mimeMessage:string; 12 mimeMessage:string;
13 draft:bool = false; 13 draft:bool = false;
14 trash:bool = false; 14 trash:bool = false;
15 sent:bool = false;
15} 16}
16 17
17root_type Mail; 18root_type Mail;
diff --git a/common/synchronizer.cpp b/common/synchronizer.cpp
index be969d2..ee7a7ba 100644
--- a/common/synchronizer.cpp
+++ b/common/synchronizer.cpp
@@ -92,17 +92,20 @@ void Synchronizer::createEntity(const QByteArray &sinkId, const QByteArray &buff
92void Synchronizer::modifyEntity(const QByteArray &sinkId, qint64 revision, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject, 92void Synchronizer::modifyEntity(const QByteArray &sinkId, qint64 revision, const QByteArray &bufferType, const Sink::ApplicationDomain::ApplicationDomainType &domainObject,
93 DomainTypeAdaptorFactoryInterface &adaptorFactory, std::function<void(const QByteArray &)> callback) 93 DomainTypeAdaptorFactoryInterface &adaptorFactory, std::function<void(const QByteArray &)> callback)
94{ 94{
95 // FIXME removals
96 QByteArrayList deletedProperties;
95 // These changes are coming from the source 97 // These changes are coming from the source
96 const auto replayToSource = false; 98 const auto replayToSource = false;
97 flatbuffers::FlatBufferBuilder entityFbb; 99 flatbuffers::FlatBufferBuilder entityFbb;
98 adaptorFactory.createBuffer(domainObject, entityFbb); 100 adaptorFactory.createBuffer(domainObject, entityFbb);
99 flatbuffers::FlatBufferBuilder fbb; 101 flatbuffers::FlatBufferBuilder fbb;
100 auto entityId = fbb.CreateString(sinkId.toStdString()); 102 auto entityId = fbb.CreateString(sinkId.toStdString());
103 auto modifiedProperties = BufferUtils::toVector(fbb, domainObject.changedProperties());
104 auto deletions = BufferUtils::toVector(fbb, deletedProperties);
101 // This is the resource type and not the domain type 105 // This is the resource type and not the domain type
102 auto type = fbb.CreateString(bufferType.toStdString()); 106 auto type = fbb.CreateString(bufferType.toStdString());
103 auto delta = Sink::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); 107 auto delta = Sink::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize());
104 // FIXME removals 108 auto location = Sink::Commands::CreateModifyEntity(fbb, revision, entityId, deletions, type, delta, replayToSource, modifiedProperties);
105 auto location = Sink::Commands::CreateModifyEntity(fbb, revision, entityId, 0, type, delta, replayToSource);
106 Sink::Commands::FinishModifyEntityBuffer(fbb, location); 109 Sink::Commands::FinishModifyEntityBuffer(fbb, location);
107 callback(BufferUtils::extractBuffer(fbb)); 110 callback(BufferUtils::extractBuffer(fbb));
108} 111}
@@ -223,6 +226,16 @@ void Synchronizer::createOrModify(const QByteArray &bufferType, const QByteArray
223 } 226 }
224} 227}
225 228
229template<typename DomainType>
230void Synchronizer::modify(const DomainType &entity)
231{
232 const auto bufferType = ApplicationDomain::getTypeName<DomainType>();
233 const auto adaptorFactory = Sink::AdaptorFactoryRegistry::instance().getFactory(mResourceType, bufferType);
234 Q_ASSERT(adaptorFactory);
235 modifyEntity(entity.identifier(), entity.revision(), bufferType, entity, *adaptorFactory,
236 [this](const QByteArray &buffer) { enqueueCommand(Sink::Commands::ModifyEntityCommand, buffer); });
237}
238
226KAsync::Job<void> Synchronizer::synchronize() 239KAsync::Job<void> Synchronizer::synchronize()
227{ 240{
228 Trace() << "Synchronizing"; 241 Trace() << "Synchronizing";
@@ -263,7 +276,8 @@ Sink::Storage::Transaction &Synchronizer::syncTransaction()
263} 276}
264 277
265#define REGISTER_TYPE(T) \ 278#define REGISTER_TYPE(T) \
266 template void Synchronizer::createOrModify(const QByteArray &bufferType, const QByteArray &remoteId, const T &entity, const QHash<QByteArray, Sink::Query::Comparator> &mergeCriteria) 279 template void Synchronizer::createOrModify(const QByteArray &bufferType, const QByteArray &remoteId, const T &entity, const QHash<QByteArray, Sink::Query::Comparator> &mergeCriteria); \
280 template void Synchronizer::modify(const T &entity);
267 281
268REGISTER_TYPE(ApplicationDomain::Event); 282REGISTER_TYPE(ApplicationDomain::Event);
269REGISTER_TYPE(ApplicationDomain::Mail); 283REGISTER_TYPE(ApplicationDomain::Mail);
diff --git a/common/synchronizer.h b/common/synchronizer.h
index 6521876..6f98f35 100644
--- a/common/synchronizer.h
+++ b/common/synchronizer.h
@@ -86,6 +86,13 @@ protected:
86 template <typename DomainType> 86 template <typename DomainType>
87 void createOrModify(const QByteArray &bufferType, const QByteArray &remoteId, const DomainType &entity, const QHash<QByteArray, Sink::Query::Comparator> &mergeCriteria); 87 void createOrModify(const QByteArray &bufferType, const QByteArray &remoteId, const DomainType &entity, const QHash<QByteArray, Sink::Query::Comparator> &mergeCriteria);
88 88
89 // template <typename DomainType>
90 // void create(const DomainType &entity);
91 template <typename DomainType>
92 void modify(const DomainType &entity);
93 // template <typename DomainType>
94 // void remove(const DomainType &entity);
95
89 virtual KAsync::Job<void> synchronizeWithSource() = 0; 96 virtual KAsync::Job<void> synchronizeWithSource() = 0;
90 97
91private: 98private:
diff --git a/examples/mailtransportresource/mailtransportresource.cpp b/examples/mailtransportresource/mailtransportresource.cpp
index e8a15ee..51e4976 100644
--- a/examples/mailtransportresource/mailtransportresource.cpp
+++ b/examples/mailtransportresource/mailtransportresource.cpp
@@ -34,6 +34,7 @@
34#include "resultprovider.h" 34#include "resultprovider.h"
35#include "mailtransport.h" 35#include "mailtransport.h"
36#include "mail_generated.h" 36#include "mail_generated.h"
37#include "inspection.h"
37#include <synchronizer.h> 38#include <synchronizer.h>
38#include <log.h> 39#include <log.h>
39#include <resourceconfig.h> 40#include <resourceconfig.h>
@@ -91,24 +92,6 @@ public:
91 QByteArray mResourceInstanceIdentifier; 92 QByteArray mResourceInstanceIdentifier;
92}; 93};
93 94
94static KAsync::Job<void>send(const ApplicationDomain::Mail &mail, const MailtransportResource::Settings &settings)
95{
96 const auto data = mail.getMimeMessage();
97 auto msg = KMime::Message::Ptr::create();
98 msg->setHead(KMime::CRLFtoLF(data));
99 msg->parse();
100 if (settings.testMode) {
101 Log() << "I would totally send that mail, but I'm in test mode.";
102 } else {
103 if (MailTransport::sendMessage(msg, settings.server.toUtf8(), settings.username.toUtf8(), settings.password.toUtf8(), settings.cacert.toUtf8())) {
104 Log() << "Sent message successfully";
105 } else {
106 Log() << "Failed to send message";
107 return KAsync::error<void>(1, "Failed to send the message.");
108 }
109 }
110 return KAsync::null<void>();
111}
112 95
113//TODO fold into synchronizer 96//TODO fold into synchronizer
114class MailtransportWriteback : public Sink::SourceWriteBack 97class MailtransportWriteback : public Sink::SourceWriteBack
@@ -137,11 +120,39 @@ public:
137class MailtransportSynchronizer : public Sink::Synchronizer { 120class MailtransportSynchronizer : public Sink::Synchronizer {
138public: 121public:
139 MailtransportSynchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) 122 MailtransportSynchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier)
140 : Sink::Synchronizer(resourceType, resourceInstanceIdentifier) 123 : Sink::Synchronizer(resourceType, resourceInstanceIdentifier),
124 mResourceInstanceIdentifier(resourceInstanceIdentifier)
141 { 125 {
142 126
143 } 127 }
144 128
129 KAsync::Job<void>send(const ApplicationDomain::Mail &mail, const MailtransportResource::Settings &settings)
130 {
131 const auto data = mail.getMimeMessage();
132 auto msg = KMime::Message::Ptr::create();
133 msg->setHead(KMime::CRLFtoLF(data));
134 msg->parse();
135 if (settings.testMode) {
136 Log() << "I would totally send that mail, but I'm in test mode." << mail.identifier();
137 auto path = resourceStorageLocation(mResourceInstanceIdentifier) + "/test/";
138 Trace() << path;
139 QDir dir;
140 dir.mkpath(path);
141 QFile f(path+ mail.identifier());
142 f.open(QIODevice::ReadWrite);
143 f.write("foo");
144 f.close();
145 } else {
146 if (MailTransport::sendMessage(msg, settings.server.toUtf8(), settings.username.toUtf8(), settings.password.toUtf8(), settings.cacert.toUtf8())) {
147 Log() << "Sent message successfully";
148 } else {
149 Log() << "Failed to send message";
150 return KAsync::error<void>(1, "Failed to send the message.");
151 }
152 }
153 return KAsync::null<void>();
154 }
155
145 KAsync::Job<void> synchronizeWithSource() Q_DECL_OVERRIDE 156 KAsync::Job<void> synchronizeWithSource() Q_DECL_OVERRIDE
146 { 157 {
147 Log() << " Synchronizing"; 158 Log() << " Synchronizing";
@@ -151,16 +162,18 @@ public:
151 Log() << " Looking for mail"; 162 Log() << " Looking for mail";
152 store().reader<ApplicationDomain::Mail>().query(query, [&](const ApplicationDomain::Mail &mail) -> bool { 163 store().reader<ApplicationDomain::Mail>().query(query, [&](const ApplicationDomain::Mail &mail) -> bool {
153 Trace() << "Found mail: " << mail.identifier(); 164 Trace() << "Found mail: " << mail.identifier();
154 // if (!mail.isSent()) { 165 if (!mail.getSent()) {
155 toSend << mail; 166 toSend << mail;
156 // } 167 }
157 return true; 168 return true;
158 }); 169 });
159 auto job = KAsync::null<void>(); 170 auto job = KAsync::null<void>();
160 for (const auto &m : toSend) { 171 for (const auto &m : toSend) {
161 job = job.then(send(m, mSettings)).then<void>([]() { 172 job = job.then(send(m, mSettings)).then<void>([this, m]() {
162 //on success, mark the mail as sent and move it to a separate place 173 auto modifiedMail = ApplicationDomain::Mail(mResourceInstanceIdentifier, m.identifier(), m.revision(), QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create());
163 //TODO 174 modifiedMail.setSent(true);
175 modify(modifiedMail);
176 //TODO copy to a sent mail folder as well
164 }); 177 });
165 } 178 }
166 job = job.then<void>([&future]() { 179 job = job.then<void>([&future]() {
@@ -208,6 +221,15 @@ void MailtransportResource::removeFromDisk(const QByteArray &instanceIdentifier)
208 221
209KAsync::Job<void> MailtransportResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) 222KAsync::Job<void> MailtransportResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue)
210{ 223{
224 if (domainType == ENTITY_TYPE_MAIL) {
225 if (inspectionType == Sink::ResourceControl::Inspection::ExistenceInspectionType) {
226 auto path = resourceStorageLocation(mResourceInstanceIdentifier) + "/test/" + entityId;
227 if (QFileInfo::exists(path)) {
228 return KAsync::null<void>();
229 }
230 return KAsync::error<void>(1, "Couldn't find message: " + path);
231 }
232 }
211 return KAsync::null<void>(); 233 return KAsync::null<void>();
212} 234}
213 235
diff --git a/examples/mailtransportresource/tests/mailtransporttest.cpp b/examples/mailtransportresource/tests/mailtransporttest.cpp
index 564b4cb..f1190a7 100644
--- a/examples/mailtransportresource/tests/mailtransporttest.cpp
+++ b/examples/mailtransportresource/tests/mailtransporttest.cpp
@@ -26,11 +26,6 @@ class MailtransportTest : public QObject
26 resource.setProperty("testmode", true); 26 resource.setProperty("testmode", true);
27 return resource; 27 return resource;
28 } 28 }
29
30 void removeResourceFromDisk(const QByteArray &identifier)
31 {
32 // ::MailtransportResource::removeFromDisk(identifier);
33 }
34 QByteArray mResourceInstanceIdentifier; 29 QByteArray mResourceInstanceIdentifier;
35 30
36private slots: 31private slots:
@@ -39,13 +34,10 @@ private slots:
39 { 34 {
40 Test::initTest(); 35 Test::initTest();
41 Log::setDebugOutputLevel(Sink::Log::Trace); 36 Log::setDebugOutputLevel(Sink::Log::Trace);
42 // resetTestEnvironment();
43 auto resource = createResource(); 37 auto resource = createResource();
44 QVERIFY(!resource.identifier().isEmpty()); 38 QVERIFY(!resource.identifier().isEmpty());
45 VERIFYEXEC(Store::create(resource)); 39 VERIFYEXEC(Store::create(resource));
46 mResourceInstanceIdentifier = resource.identifier(); 40 mResourceInstanceIdentifier = resource.identifier();
47 // mCapabilities = resource.getProperty("capabilities").value<QByteArrayList>();
48 qWarning() << "FOooooooooooooooooooo";
49 } 41 }
50 42
51 void cleanup() 43 void cleanup()
@@ -56,9 +48,6 @@ private slots:
56 48
57 void init() 49 void init()
58 { 50 {
59 // qDebug();
60 // qDebug() << "-----------------------------------------";
61 // qDebug();
62 // VERIFYEXEC(ResourceControl::start(mResourceInstanceIdentifier)); 51 // VERIFYEXEC(ResourceControl::start(mResourceInstanceIdentifier));
63 } 52 }
64 53
@@ -74,13 +63,10 @@ private slots:
74 VERIFYEXEC(Store::create(mail)); 63 VERIFYEXEC(Store::create(mail));
75 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); 64 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
76 VERIFYEXEC(Store::synchronize(Query::ResourceFilter(mResourceInstanceIdentifier))); 65 VERIFYEXEC(Store::synchronize(Query::ResourceFilter(mResourceInstanceIdentifier)));
66 VERIFYEXEC(ResourceControl::inspect<ApplicationDomain::Mail>(ResourceControl::Inspection::ExistenceInspection(mail, true)));
77 67
78 //TODO verify the mail has been sent 68 auto sentMail = Store::readOne<ApplicationDomain::Mail>(Query::IdentityFilter(mail).request<Mail::Sent>());
79 69 QVERIFY(sentMail.getSent());
80 // auto modifiedMail = Store::readOne<ApplicationDomain::Mail>(Query::IdentityFilter(mail));
81 // VERIFYEXEC(Store::modify(modifiedMail));
82 // VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
83 // VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier));
84 70
85 } 71 }
86 72