C++: Some code cleanup
[smartapi.git] / Common / C++ / SmartAPI / tests / TestSequences.cpp
1 #include <QCoreApplication>
2 #include <QString>
3 #include <QtDebug>
4 #include <QDateTime>
5 #include <QUrl>
6 #include <QFile>
7 #include <QNetworkAccessManager>
8 #include <QNetworkRequest>
9 #include <QNetworkReply>
10 #include <QUrlQuery>
11 #include <QEventLoop>
12 #include <QJsonDocument>
13 #include <QJsonObject>
14 #include <QElapsedTimer>
15 #include <openssl/rand.h>
16 #include <unistd.h>
17
18 #include "smartapi/common/CONTENTTYPES.h"
19 #include "smartapi/common/SERIALIZATION.h"
20 #include "smartapi/common/DATATYPE.h"
21 #include "smartapi/common/HttpMessage.h"
22 #include "smartapi/common/NS.h"
23 #include "smartapi/common/PROPERTY.h"
24 #include "smartapi/common/Tools.h"
25 #include "smartapi/common/SmartAPICrypto.h"
26 #include "smartapi/common/UnitConverter.h"
27 #include "smartapi/agents/OAuthAgent.h"
28 #include "smartapi/agents/RegistrationAgent.h"
29 #include "smartapi/agents/SearchAgent.h"
30 #include "smartapi/agents/SharingAgent.h"
31 #include "smartapi/agents/TransactionAgent.h"
32 #include "smartapi/factory/Factory.h"
33 #include "smartapi/factory/ActivityFactory.h"
34 #include "smartapi/factory/RequestFactory.h"
35 #include "smartapi/factory/ResponseFactory.h"
36 #include "smartapi/factory/NotificationFactory.h"
37 #include "smartapi/model/Request.h"
38 #include "smartapi/model/Response.h"
39 #include "smartapi/model/Notification.h"
40 #include "smartapi/model/Activity.h"
41 #include "smartapi/model/Direction.h"
42 #include "smartapi/model/Enumeration.h"
43 #include "smartapi/model/Error.h"
44 #include "smartapi/model/Input.h"
45 #include "smartapi/model/InterfaceAddress.h"
46 #include "smartapi/model/Device.h"
47 #include "smartapi/model/ValueObject.h"
48 #include "smartapi/model/PhysicalEntity.h"
49 #include "smartapi/model/Service.h"
50 #include "smartapi/model/Size.h"
51 #include "smartapi/model/SomeItems.h"
52 #include "smartapi/model/Map.h"
53 #include "smartapi/model/Offering.h"
54 #include "smartapi/model/Orientation.h"
55 #include "smartapi/model/Output.h"
56 #include "smartapi/model/PriceSpecification.h"
57 #include "smartapi/model/DistanceDependentPriceSpecification.h"
58 #include "smartapi/model/PropertyDependentPriceSpecification.h"
59 #include "smartapi/model/TimeDependentPriceSpecification.h"
60 #include "smartapi/model/TimeDependentPriceListSpecification.h"
61 #include "smartapi/model/Restriction.h"
62 #include "smartapi/model/Ring.h"
63 #include "smartapi/model/SystemOfInterest.h"
64 #include "smartapi/model/TemporalContext.h"
65 #include "smartapi/model/UnitPriceSpecification.h"
66 #include "smartapi/model/Velocity.h"
67 #include "smartapi/model/Waypoints.h"
68 #include "smartapi/model/Waypoint.h"
69 #include "smartapi/model/Organization.h"
70 #include "smartapi/model/Address.h"
71 #include "smartapi/model/Capacity.h"
72 #include "smartapi/model/InterfaceAddress.h"
73
74 #include "smartapi/rdf/LinkedList.h"
75 #include "smartapi/rdf/OrderedList.h"
76 #include "smartapi/rdf/ItemizedList.h"
77 #include "smartapi/rdf/NudeList.h"
78 #include "smartapi/rdf/Model.h"
79
80 #include "RegisterDeregistertest.h"
81 #include "RegisterSearchTest.h"
82 #include <QThread>
83
84
85 bool modelReadTest()
86 {
87         QElapsedTimer timer;
88         timer.start();
89         QFile f("/home/jani/union-v1.0.ttl");
90
91         if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
92                 return false;
93         QByteArray all = f.readAll();
94         f.close();
95         qDebug() << "read file" << timer.elapsed();
96
97         Model* m = new Model();
98         m->read(all);
99         qDebug() << "parsed one" << timer.elapsed();
100         int parseOne = timer.elapsed();
101         delete m;
102
103         for (int i = 0; i < 10000; i++) {
104                 m = new Model();
105                 m->read(all);
106                 delete m;
107         }
108         int parseMulti = timer.elapsed();
109         qDebug() << "parsed multiple" << parseMulti << (parseMulti - parseOne);
110         return true;
111 }
112
113 bool variantTest()
114 {
115         Obj* o = new Obj();
116         Variant* v1 = new Variant(o);
117         Variant* v2 = new Variant(v1);
118         Variant* v3 = new Variant(v2);
119         Variant* v4 = new Variant(new Obj(v1->asObj()));
120         Variant* v5 = new Variant(v4);
121         
122         qDebug() << "Delete v1";
123         v1->destroyCascade();
124         qDebug() << "Delete v2";
125         v2->destroyCascade();
126         qDebug() << "Delete v3";
127         v3->destroyCascade();
128         qDebug() << "Delete v4";
129         v4->destroyCascade();
130         qDebug() << "Delete v5";
131         v5->destroyCascade();
132
133         return true;
134 }
135
136 bool serializeRequestTest()
137 {
138         int sampleValue = 9;
139
140         QString targetSystemUri = "http://localhost:8099/seas/v1.0/access/";
141         QString myId = "http://seasdemos.asema.com/csharp/controlcommandsender/Cabcd";
142         QString targetId = "http://seasdemos.asema.com/csharp/controlcommandreceiver/Cabcd";
143         QString sourceIdentity = "http://seasexamples.asema.com/dataservers/timeseries";
144         QString myIdentity = "http://seasexamples.asema.com/datafetchers/timeseries";
145
146         qDebug() << "Test routine for request serialization";
147
148         QDateTime seriesEnd = QDateTime::currentDateTime();
149         QDateTime seriesStart = seriesEnd.addDays(-7);
150
151         QList<QPair<QString, QString>> request_vars;
152         request_vars.append(qMakePair(QString("Temperature"), QString("DegreeCelsius")));
153         request_vars.append(qMakePair(QString("Cloudiness"), QString("Percent")));
154         request_vars.append(qMakePair(QString("Precipitation"), QString("MilliMeter")));
155
156         Request* tsRequest = RequestFactory::create(myIdentity);
157         Activity* a = new Activity();
158         SystemOfInterest* system = new SystemOfInterest();
159         system->setSameAs(sourceIdentity);
160         tsRequest->addActivity(a);
161         tsRequest->setSystemOfInterest(system);
162
163         TemporalContext* tc = new TemporalContext();
164         tc->setStart(seriesStart);
165         tc->setEnd(seriesEnd);
166
167         Input* i = new Input();
168         i->setTemporalContext(tc);
169         a->setInput(i);
170
171         if (request_vars.length() == 1){
172                 tsRequest->setQuantity(NS__SMARTAPI + request_vars.at(0).first);
173                 tsRequest->setUnit(NS__SMARTAPI + request_vars.at(0).second);
174         } else {
175                 for (int idx = 0; idx < request_vars.length(); idx++) {
176                         ValueObject* v = new ValueObject();
177                         v->setQuantity(NS__SMARTAPI + request_vars.at(idx).first);
178                         v->setUnit(NS__SMARTAPI + request_vars.at(idx).second);
179                         v->setValue(new Variant(++sampleValue));
180                         tsRequest->add(NS__SMARTAPI + request_vars.at(idx).first, v);
181                 }
182         }
183
184         QString payload = Tools::toString(tsRequest, SERIALIZATION__JSON_LD);
185         printf("%s\n", payload.toUtf8().constData());
186         tsRequest->destroyCascade();
187
188         return true;
189 }
190
191 bool shortSerializeParseTest()
192 {
193         QString myId = "http://seasdemos.asema.com/cpluplus/controlcommandsender/Cabcd";
194
195         qDebug() << "Test routine for serialization + parse of a request (with activity)";
196
197         Activity* a = new Activity("http://asema.com/activitySeasIdentifier");
198         a->setMethod(RESOURCE__READ);
199         TemporalContext* tc = new TemporalContext();
200         tc->setStart(QDateTime::currentDateTime());
201         tc->setEnd(QDateTime::currentDateTime());
202
203         Response* resp = ResponseFactory::create(myId);
204         resp->setName("test request");
205         resp->setActivity(a);
206         resp->setTemporalContext(tc);
207         resp->setIdentifierUri("http://bogus.seas.identifier.uri");
208         a->setTemporalContext(new TemporalContext());
209
210         PhysicalEntity* entity = new PhysicalEntity("http://www.volvo.com/cars/electric");
211         entity->addType(RESOURCE__CAR);
212         entity->setName("A car");
213         entity->setCoordinates(60.185847, 24.867435);
214         a->addEntity(entity);
215
216         Error* e = new Error();
217         e->setErrorCode(100);
218         e->setErrorMessage("This is a dummy error for testing");
219         resp->addError(e);
220
221         QString payload = Tools::toString(resp, SERIALIZATION__TURTLE);
222         resp->destroyCascade();
223
224         qDebug() << "Serialized payload:";
225         printf("%s\n", payload.toLatin1().data());
226
227         qDebug() << "Parsing back the serialized payload...";
228
229         Response* tsRequest = (Response*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
230         Activity* a2 = tsRequest->firstActivity();
231         qDebug() << "hasTemporalContext? " << a2->hasTemporalContext();
232         qDebug() << "temporal context start" << a2->getTemporalContext()->getStart();
233         qDebug() << "is generated at " << tsRequest->getGeneratedAt();
234         qDebug() << "method" << a2->getMethod();
235         qDebug() << "entity" << a2->firstEntity()->getName();
236
237         qDebug() << "\nRe-serializing!";
238         QString reserializedPayload = Tools::toString(tsRequest, SERIALIZATION__JSON_LD);
239         printf("%s\n", reserializedPayload.toLatin1().data());
240         tsRequest->destroyCascade();
241
242         return true;
243 }
244
245 bool automaticSerializeParseTest()
246 {
247         QString myId = "http://seasdemos.asema.com/cpluplus/sometest/Cabcd";
248
249         qDebug() << "Test routine for serialization + parse of some object which must be deduced from the message automatically";
250
251         // Try first with an ID node at tope
252         Activity* a = new Activity("http://asema.com/activitySeasIdentifier");
253         Output* o = new Output();
254
255         TemporalContext* tc = new TemporalContext();
256         tc->setStart(QDateTime::currentDateTime());
257         tc->setEnd(QDateTime::currentDateTime());
258
259         a->setOutput(o);
260         o->setTemporalContext(tc);
261
262         QString payload = Tools::toString(a, SERIALIZATION__TURTLE);
263         a->destroyCascade();
264
265         qDebug() << "Serialized form:";
266         printf("%s\n", payload.toLatin1().data());
267
268         Obj* oo = Tools::fromStringAsObj(payload);
269         if (Activity* aa = dynamic_cast<Activity*>(oo)) {
270                 qDebug() << "Autoparsed, hasTemporalContext? " << aa->getOutputs().at(0)->hasTemporalContext();
271                 qDebug() << "temporal context start" << aa->getOutputs().at(0)->getTemporalContext()->getStart();
272         }
273         oo->destroyCascade();
274
275         qDebug() << "Serialize second round, now with fully blank top node.";
276         // Then a blank node at top
277         Activity* a2 = new Activity();
278         Output* o2 = new Output();
279
280         TemporalContext* tc2 = new TemporalContext();
281         tc2->setStart(QDateTime::currentDateTime());
282         tc2->setEnd(QDateTime::currentDateTime());
283
284         a2->setOutput(o2);
285         o2->setTemporalContext(tc2);
286
287         payload = Tools::toString(a2, SERIALIZATION__TURTLE);
288     a2->destroyCascade();
289
290         qDebug() << "Serialized form:";
291         printf("%s\n", payload.toLatin1().data());
292
293         qDebug() << "Parsing the string...";
294
295         Obj* oo2 = Tools::fromStringAsObj(payload);
296         if (Activity* aa2 = dynamic_cast<Activity*>(oo2)) {
297                 qDebug() << "Autoparsed, second round, hasTemporalContext? " << aa2->getOutputs().at(0)->hasTemporalContext();
298                 qDebug() << "temporal context start" << aa2->getOutputs().at(0)->getTemporalContext()->getStart();
299         }
300         oo2->destroyCascade();
301
302         return true;
303 }
304
305
306 bool longSerializeParseTest()
307 {
308         QString myId = "http://seasdemos.asema.com/cpluplus/controlcommandsender/Cabcd";
309         
310         qDebug() << "Test routine for serialization + parse of an activity";
311         
312         Activity* a = new Activity("http://asema.com/activitySeasIdentifier");
313         Input* i1 = new Input("http://input.uri", Input::TYPE_DATA);
314         i1->setName("data input");
315         Input* i2 = new Input("http://input2.uri", Input::TYPE_REFERENCE);
316         i2->setName("reference input");
317         a->setInput(i1);
318         a->addInput(i2);
319         Output* o1 = new Output("http://output.uri");
320         o1->setName("output 1");
321         Output* o2 = new Output("http://output.uri");
322         o2->setName("output 2");
323         a->setOutput(o1);
324         a->addOutput(o2);
325         
326         Availability* ab = new Availability();
327         ab->setIdentifierUri("http://availability.uri");
328         ab->setName("availability");
329         ab->setIsControlledBy("http://availability.controlled.by");
330         a->addAvailability(ab);
331         Availability* dab = new Availability();
332         dab->setIdentifierUri("http://data.availability.uri");
333         dab->setName("data availability");
334         a->addDataAvailability(dab);
335         
336         InterfaceAddress* iface1 = new InterfaceAddress();
337         iface1->setIdentifierUri("http://iface1.uri");
338         iface1->setName("eth0");
339         InterfaceAddress* iface2 = new InterfaceAddress();
340         iface2->setIdentifierUri("http://iface2.uri");
341         iface2->setType(RESOURCE__INTERFACEADDRESS);
342         iface2->addType(RESOURCE__BATTERY);
343         iface2->setName("eth1");
344         a->setInterface(iface1);
345         a->addInterface(iface2);
346         
347         Status* status = new Status();
348         status->setPercentage(50);
349         status->setCompleted(20);
350
351         Response* req = ResponseFactory::create(myId);
352         req->setSameAs("http://bogus.same.as");
353         req->setName("test request");
354         req->setActivity(a);
355         req->setMessageId(1);
356         req->setProcessId(2);
357         req->setStatus(status);
358         req->setIdentifierUri("http://bogus.seas.identifier.uri");
359         req->add("http://booleanProperty", true);
360         req->add("http://objectProperty", new Obj("http://foo.bar"));
361         req->add("http://stringProperty", "string value");
362         req->add("http://doubleProperty", -12.34);
363         req->add("http://integerProperty", 40);
364         req->add("http://datetimeProperty", QDateTime::currentDateTime());
365
366         QString payload = Tools::toString(req, SERIALIZATION__JSON_LD);
367         req->destroyCascade();
368         
369         qDebug() << "Serialized payload:";
370         qDebug() << payload;
371
372         qDebug() << "Parsing back the serialized payload...";
373
374         Model* model = Tools::fromString(payload, SERIALIZATION__JSON_LD);
375         Resource* res = Tools::getResourceByType(RESOURCE__RESPONSE, model);
376         Response* tsRequest = Obj::parse<Response>(res);
377         delete res;
378         delete model;
379         if (tsRequest->hasGeneratedBy())
380                 qDebug() << "is generated by " << tsRequest->getGeneratedBy();
381         qDebug() << "is generated at " << tsRequest->getGeneratedAt();
382         
383         qDebug() << "\nRe-serializing!";
384         QString reserializedPayload = Tools::toString(tsRequest, SERIALIZATION__JSON_LD);
385         qDebug() << reserializedPayload;
386         tsRequest->destroyCascade();
387
388         return true;
389 }
390
391 bool physicalEntityTest()
392 {
393         PhysicalEntity* entity = new PhysicalEntity();
394         
395         Size* size = new Size();
396         Velocity* speed = new Velocity();
397         Orientation* orientation = new Orientation();
398         Direction* direction = new Direction();
399         ValueObject* colorCoding = new ValueObject();
400         
401         size->setWidth(new ValueObject(NS__UNIT + "Centimeter", new Variant(100.2)));
402         size->setHeight(new ValueObject(NS__UNIT + "Centimeter", new Variant(301.9)));
403         size->setDepth(new ValueObject(NS__UNIT + "Centimeter", new Variant(11.222)));
404         
405         orientation->setYaw(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(270)));
406         orientation->setPitch(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(45)));
407         orientation->setRoll(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(301)));
408         
409         direction->setBearing(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(121)));
410         direction->setHeading(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(243)));
411
412         speed->setLinearVelocityX(new ValueObject(NS__UNIT + "MeterPerSecond", new Variant(3.4)));
413         speed->setLinearVelocityY(new ValueObject(NS__UNIT + "MeterPerSecond", new Variant(30.1)));
414         speed->setAngularVelocityY(new ValueObject(NS__UNIT + "RadianPerSecond", new Variant(54.3)));
415
416         colorCoding->setValue(new Variant("PANTONE"));
417         
418         entity->addType(RESOURCE__CAR);
419         entity->setName("This is a test entity");
420         entity->setVelocity(speed);
421         entity->setOrientation(orientation);
422         entity->setDirection(direction);
423         entity->setSize(size);
424         entity->add("colorCoding", colorCoding);
425         
426         entity->setCoordinates(60.185847, 24.867435);
427
428         Address* addr = new Address();
429         addr->setCity("Espoo");
430         addr->setCountry("Finland");
431         addr->setStreetAddress("Otakaari 1");
432         addr->setZipCode("02150");
433         entity->setAddress(addr);
434
435         entity->setWeight(new ValueObject(NS__UNIT + "Kilogram", new Variant(222)));
436         
437         QString serialized = Tools::toString(entity, SERIALIZATION__TURTLE);
438         qDebug() << "Serialized:";
439         printf("%s\n", serialized.toLatin1().data());
440         entity->destroyCascade();
441
442         qDebug() << "-------------------";      
443         PhysicalEntity* parsedEntity = (PhysicalEntity*)Tools::fromStringAsObj(serialized);
444         
445         qDebug() << "\nRe-serializing...";
446         QString reserializedPayload = Tools::toString(parsedEntity, SERIALIZATION__TURTLE);
447         printf("%s\n", reserializedPayload.toLatin1().data());
448
449         qDebug() << "---- Explain -----";
450         //parsedEntity->explain(true);
451         parsedEntity->destroyCascade(); // if explain is active, don't destroy (explain needs the object until ontologies have loaded)
452
453         return true;
454 }
455
456 bool waypointsTest()
457 {
458         Waypoints* waypoints = new Waypoints();
459
460         Waypoint* wp1 = new Waypoint();
461         Waypoint* wp2 = new Waypoint();
462         Waypoint* wp3 = new Waypoint();
463
464         waypoints->addWaypoint(wp1);
465         waypoints->addWaypoint(wp2);
466         waypoints->addWaypoint(wp3);
467
468         Address* loc1 = new Address();
469         Address* loc2 = new Address();
470         Address* loc3 = new Address();
471
472         Route* route = new Route;
473         route->addRoutePoint(new Coordinates(61.15, 25.89));
474         route->addRoutePoint(new Coordinates(61.14, 24.78));
475         route->addRoutePoint(new Coordinates(61.14, 24.61));
476
477         loc2->setCity("Espoo");
478         loc2->setCountry("Finland");
479         loc2->setStreetAddress("Otakaari 1");
480         loc2->setZipCode("02150");
481
482         wp1->setInstant(QDateTime::currentDateTime());
483         wp1->setAddress(loc1);
484         wp1->setCoordinates(new Coordinates(60.2, 24.1));
485
486         wp2->setAddress(loc2);
487         wp3->setAddress(loc3);
488         wp3->setRoute(route);
489
490
491         QString payload = Tools::toString(waypoints, SERIALIZATION__TURTLE);
492
493         qDebug() << "Serialized:";
494         printf("%s\n", payload.toLatin1().data());
495         waypoints->destroyCascade();
496
497         Obj* parsedObj = Tools::fromStringAsObj(payload);
498         QString reserialized = Tools::toString(parsedObj, SERIALIZATION__TURTLE);
499         qDebug() << "Re-Serialized:";
500         printf("%s\n", reserialized.toLatin1().data());
501
502         parsedObj->destroyCascade();
503         return true;
504 }
505
506 bool routeTest()
507 {
508         Route* route = new Route;
509         route->addRoutePoint(new Coordinates(61.00, 25.89));
510         route->addRoutePoint(new Coordinates(62.00, 26.78));
511         route->addRoutePoint(new Coordinates(63.00, 27.61));
512         Velocity* v = new Velocity();
513         v->setGroundSpeed(new ValueObject(NS__UNIT + "MeterPerSecond", new Variant(10200)));
514         route->setAverageVelocity(v);
515
516         QString payload = Tools::toString(route, SERIALIZATION__TURTLE);
517
518         qDebug() << "Serialized:";
519         printf("%s\n", payload.toLatin1().data());
520         route->destroyCascade();
521
522         Route* parsedObj = (Route*)Tools::fromStringAsObj(payload);
523         QString reserialized = Tools::toString(parsedObj, SERIALIZATION__TURTLE);
524         qDebug() << "Re-Serialized:";
525         printf("%s\n", reserialized.toLatin1().data());
526
527         qDebug() << "Ground speed on route" << parsedObj->getAverageVelocity()->getGroundSpeed()->getValue()->asDouble();
528         parsedObj->destroyCascade();
529         return true;
530 }
531
532 bool routeFetchTest()
533 {
534     //QNetworkAccessManager *networkManager = new QNetworkAccessManager();
535     //QEventLoop postWaitLoop;
536     //QString serviceUrl = "http://bemap-beta.benomad.com/bgis/seas/v1.0/access";
537         QString requesterIdentity = "http://seasexamples.asema.com/api/Crequest";
538
539         // Create a request
540         Request* r = RequestFactory::create(requesterIdentity);
541
542         // API payload data
543         Activity* a = new Activity();
544         Input* i = new Input();
545         a->addInput(i);
546         r->addActivity(a);
547
548         PhysicalEntity* trip = new PhysicalEntity();
549
550         trip->add("startCoordinates", new Coordinates(43.70059, 7.27696));
551         trip->add("stopCoordinates", new Coordinates(43.58035, 7.12125));
552         i->add("tripData", trip);
553         
554         PhysicalEntity* car = new PhysicalEntity();
555         car->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos"));
556         car->add("frontalAerodynamicCoefficient", new ValueObject(NS__UNIT + "SquareMeter", 0.75)); 
557         car->add("tireRollingResistanceCoefficient", new ValueObject(0.012));
558         car->add("gearEfficiencyCoefficient", new ValueObject(0.693));
559         car->add("batteryCapacity", new ValueObject(NS__UNIT + "KilowattHour", 22.0));
560         car->add("extraLoadWeight", new ValueObject(NS__UNIT + "Kilogram", 75.0));
561         car->add("auxiliaryEquipmentConsumption", new ValueObject(NS__UNIT + "Watt", 300.0));
562         car->add("maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 2.0));
563         car->add("maximumDeceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", -2.0));
564         car->add("maximumSpeed", new ValueObject(NS__UNIT + "KilometerPerHour", 90.0));
565         i->add("vehicleData", car);
566         
567         QString payload = Tools::toString(r, SERIALIZATION__TURTLE);
568         printf("%s\n", payload.toLatin1().data());
569         r->destroyCascade();
570         
571     /*
572         QNetworkRequest request(serviceUrl);
573         QByteArray authHash = QByteArray("Basic ") + QByteArray("smartapi:5Hq0j16818v1cDh507fP").toBase64();
574     request.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE__TURTLE);
575         request.setRawHeader(QByteArray("X-SmartAPI-CallId"), QByteArray("seasClientTest"));
576         request.setRawHeader(QByteArray("X-SmartAPI-Method"), QByteArray("routing"));
577     request.setRawHeader(QByteArray("Accept"), QByteArray(CONTENT_TYPE__TURTLE));
578         request.setRawHeader(QByteArray("Authorization"), authHash);
579     request.setRawHeader(QByteArray("Content-Type"), QByteArray(CONTENT_TYPE__TURTLE));
580         
581         QNetworkReply* reply = networkManager->post(request, payload.toUtf8());
582         QObject::connect( reply, SIGNAL(finished()), &postWaitLoop, SLOT(quit()));
583         postWaitLoop.exec( QEventLoop::ExcludeUserInputEvents );
584         
585         QByteArray result = reply->readAll();
586         reply->deleteLater();
587         networkManager->deleteLater();
588         
589           qDebug() << "Result: " << result;
590      */
591         return true;
592 }
593
594 bool entityCopyTest()
595 {
596         Activity* a1 = new Activity();
597         PhysicalEntity* p1 = new PhysicalEntity("http://www.p1.com");
598         PhysicalEntity* p2 = new PhysicalEntity("http://www.p2.com");
599         ValueObject* vo = new ValueObject(22.0);
600
601         p1->addValueObject(vo);
602         a1->addEntity(p1);
603         a1->addEntity(p2);
604
605         PhysicalEntity* p3 = new PhysicalEntity(p1);
606         Tools::destroy(2, a1, p3);
607         qDebug() << "Destroyed all objects ok";
608         return true;
609 }
610
611 bool entityManagedByTest()
612 {
613         PhysicalEntity* p1 = new PhysicalEntity("http://www.p1.com");
614         ValueObject* vo = new ValueObject(22.0);
615         p1->addValueObject(vo);
616         p1->setManagedBy("http://www.p2.com");
617
618         QString serialized = Tools::toString(p1, SERIALIZATION__TURTLE);
619         p1->destroyCascade();
620
621         printf("%s\n", serialized.toUtf8().data());
622
623         Obj* parsedObj = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
624
625         parsedObj->turtlePrint();
626         parsedObj->destroyCascade();
627         qDebug() << "Destroyed all objects ok";
628         return true;
629 }
630
631 bool propertyListCopyTest()
632 {
633         Activity* a1 = new Activity();
634         PhysicalEntity* p1 = new PhysicalEntity("http://www.p1.com");
635         PhysicalEntity* p2 = new PhysicalEntity("http://www.p2.com");
636
637         a1->addEntity(p1);
638         a1->addEntity(p2);
639
640         // This list becomes a copy of Entities in a1. Once a1 is destroyed
641         // also the entities are destroyed. The list should now have a shorter length
642         PropertyList<Entity*> ents = a1->getEntities();
643         a1->destroyCascade();
644
645         // Ents is now a copy. The Entities in a1 are not destroyed because there are still references
646         // to them in ents. However, ents is in the call stack now and will be automatically destroyed.
647         return true;
648 }
649
650 bool propertyListingTest()
651 {
652         Entity* e = new Entity("http://www.test.com/test");
653         e->add("color", new ValueObject(new Variant("Dark blue")));
654         e->setName("Test entity");
655         e->setCoordinates(60.1, 18.2);
656         QList<QString> propNames = e->activePropertyNames();
657         qDebug() << propNames;
658         e->destroyCascade();
659         return propNames.length() == 2;
660 }
661
662 bool propertyTest()
663 {
664         Activity* a = new Activity();
665         Entity* e = new Entity("http://www.hella.com/lightClassification");
666
667         PhysicalEntity* car1 = new PhysicalEntity("http://www.mazda.com/car1");
668         PhysicalEntity* car2 = new PhysicalEntity("http://www.volvo.com/car2");
669
670         car1->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 2000));
671         car2->add(NS__SMARTAPI + "weight", new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 1000));
672
673         car1->add("frontalAerodynamicCoefficient", new ValueObject(NS__UNIT + "SquareMeter", 0.75));
674         car1->add("tireRollingResistanceCoefficient", new ValueObject(0.012));
675         car1->add("gearEfficiencyCoefficient", new ValueObject(0.693));
676         car1->add("batteryCapacity", new ValueObject(NS__UNIT + "KilowattHour", 22.0));
677         car1->add(NS__SMARTAPI + "maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 2.0));
678
679         car2->add("color", new ValueObject(new Variant("Dark blue")));
680
681         a->addEntity(car1);
682         a->addEntity(car2);
683
684         e->add(NS__SMARTAPI + "Brightness", new ValueObject(NS__SMARTAPI + "brightness", NS__UNIT + "Lumen", 2112));
685         e->add("Color", new ValueObject(new Variant("BrightWhite")));
686         car1->add("frontLightEfficiency", e);
687
688         QString serialized = Tools::toString(a, SERIALIZATION__TURTLE);
689         a->destroyCascade();
690
691         printf("%s\n", serialized.toUtf8().data());
692
693         Obj* parsedObj = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
694
695         Activity* a1 = (Activity*)parsedObj;
696         PhysicalEntity* c1 = (PhysicalEntity*)a1->getEntities().first();
697         PhysicalEntity* c2 = (PhysicalEntity*)a1->getEntities().at(1);
698
699         qDebug() << "Car 1 -- id, weight quantity, weight value, front light brightness and front light color:"
700                         << c1->getIdentifierUri()
701                         << c1->getWeight()->getQuantity()
702                         << c1->getWeight()->getValueAsDouble()
703                         << c1->get<Entity>("frontLightEfficiency")->get<ValueObject>(NS__SMARTAPI + "Brightness")->getUnit()
704                         << c1->get<Entity>("frontLightEfficiency")->get<ValueObject>(NS__SMARTAPI + "Brightness")->getValueAsDouble()
705                         << c1->get<Entity>("frontLightEfficiency")->get<ValueObject>("Color")->getValueAsString();
706
707         qDebug() << "Car 2 -- id, weight and color:"
708                         << c2->getIdentifierUri()
709                         << c2->getWeight()->getValueAsDouble()
710                         << c2->get<ValueObject>("color")->getValueAsString();
711
712         QList<PrefixUriPair> addedPrefixes;
713         addedPrefixes << PrefixUriPair("custom", "http://custom.com");
714         QString reserialized = Tools::toString(parsedObj, SERIALIZATION__TURTLE, addedPrefixes);
715         parsedObj->destroyCascade();
716         printf("\n---\n%s\n", reserialized.toUtf8().data());
717
718         Obj* reParsedObj = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
719         Activity* a21 = (Activity*)reParsedObj;
720         PhysicalEntity* c21 = (PhysicalEntity*)a21->getEntities().first();
721         PhysicalEntity* c22 = (PhysicalEntity*)a21->getEntities().at(1);
722
723         qDebug() << "==== Re-read values ====";
724         qDebug() << "Car 1 -- id, weight quantity, weight value, front light brightness and front light color:"
725                         << c21->getIdentifierUri()
726                         << c21->getWeight()->getQuantity()
727                         << c22->getWeight()->getValueAsDouble()
728                         << c21->get<Entity>("frontLightEfficiency")->get<ValueObject>(NS__SMARTAPI + "Brightness")->getUnit()
729                         << c21->get<Entity>("frontLightEfficiency")->get<ValueObject>(NS__SMARTAPI + "Brightness")->getValueAsDouble()
730                         << c21->get<Entity>("frontLightEfficiency")->get<ValueObject>("Color")->getValueAsString();
731
732         qDebug() << "Car 2 -- id, weight and color:"
733                         << c22->getIdentifierUri()
734                         << c22->getWeight()->getValueAsDouble()
735                         << c22->get<ValueObject>("color")->getValueAsString();
736         reParsedObj->destroyCascade();
737         return true;
738 }
739
740 bool propertyRequestTest()
741 {
742         qDebug() << "\n\n=== The \"Give me everything\" request ===";
743         Request* rE = new Request("http://me.com/just/me/not/you");
744         Activity* aE = new Activity();
745         PhysicalEntity* car1E = new PhysicalEntity("http://www.mazda.com/supersmoothnewmodel");
746
747         rE->addActivity(aE);
748         aE->addEntity(car1E);
749
750         QString serialized = Tools::toString(rE, SERIALIZATION__TURTLE);
751         rE->destroyCascade();
752
753         printf("%s\n", serialized.toUtf8().data());
754
755         Request* parsedObj = Tools::parseRequest(serialized.toLatin1(), QByteArray(SERIALIZATION__TURTLE));
756         parsedObj->destroyCascade();
757
758
759         qDebug() << "\n\n=== The \"Give me something\" request ===";
760         Request* rS = new Request("http://me.com/definitely/just/me");
761         Activity* aS = new Activity();
762         PhysicalEntity* car1S = new PhysicalEntity("http://www.mazda.com/veryslickmodel");
763
764         rS->addActivity(aS);
765         aS->addEntity(car1S);
766
767         ValueObject* vo = new ValueObject();
768         vo->setUnit(NS__UNIT + "MeterPerSecondSquared");
769         car1S->addValueObject(vo);
770         car1S->addValueObject(new ValueObject(NS__QUANTITY + "InstantPower", NS__UNIT + "Watt"));
771
772         serialized = Tools::toString(rS, SERIALIZATION__TURTLE);
773         rS->destroyCascade();
774
775         printf("%s\n", serialized.toUtf8().data());
776
777         qDebug() << "\n\n=== The \"Give me this thing\" request ===";
778         Request* rT = new Request("http://me.com/solitaire/world/champ");
779         Activity* aT = new Activity();
780         PhysicalEntity* car1T = new PhysicalEntity("http://www.mazda.com/rustyoldmodel");
781
782         rT->addActivity(aT);
783         aT->addEntity(car1T);
784
785         ValueObject* accVo = new ValueObject();
786         accVo->setUnit(NS__UNIT + "MeterPerSecondSquared");
787         car1T->setWeight(new ValueObject(NS__QUANTITY + "Weight", NS__UNIT + "Kilogram"));
788         car1T->add(NS__SMARTAPI + "maximumAcceleration", accVo);
789         car1T->add("batteryCapacity", new ValueObject(NS__QUANTITY + "MaximumCharge", NS__UNIT + "KilowattHour"));
790         car1T->add(NS__SMARTAPI + "phase1Power", new ValueObject());
791         car1T->add(NS__SMARTAPI + "phase1Consumption", new ValueObject());
792         car1T->add(NS__SMARTAPI + "phase2Power", new ValueObject(NS__QUANTITY + "InstantPower", NS__UNIT + "Watt"));
793         car1T->add("http://alienproperties/et/call/home", new ValueObject("http://pointy.fingers/dial/a/number"));
794
795         serialized = Tools::toString(rT, SERIALIZATION__TURTLE);
796         rT->destroyCascade();
797
798         printf("%s\n", serialized.toUtf8().data());
799         parsedObj = (Request*)Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
800
801         PropertyList<Activity*> acts = parsedObj->getActivities();
802         Activity* pa = acts.at(0);
803         PhysicalEntity* pe = (PhysicalEntity*)pa->getEntities().first();
804         qDebug() << "Requesting" << pe->getIdentifierUri();
805         qDebug() << "Properties requested:" << pe->propertyNames();
806         qDebug() << "Request weight in" << pe->getWeight()->getUnit();
807         qDebug() << "Request battery capacity of " << pe->get<ValueObject>("batteryCapacity")->getQuantity() << "in" << pe->get<ValueObject>("batteryCapacity")->getUnit();
808         parsedObj->destroyCascade();
809         qDebug() << "Test done.";
810         return true;
811 }
812
813 bool timeseriesResponseTest()
814 {
815         Response* r = new Response("http://me.com/just/me/not/you");
816         Activity* a = new Activity();
817         TimeSeries* ts = new TimeSeries();
818
819         QList<GraphItem*> testList;
820         QDateTime now = QDateTime::currentDateTime();
821
822         for (int i = 0; i < 5; i++) {
823                 ValueObject* v = new ValueObject();
824                 v->setValue(new Variant(i));
825                 v->setInstant(now.addDays(i));
826                 testList.append(v);
827         }
828         ts->setList(testList);
829         a->setTimeSeries(ts);
830         r->addActivity(a);
831
832         QString serialized = Tools::toString(r, SERIALIZATION__TURTLE);
833         r->destroyCascade();
834
835         printf("%s\n", serialized.toUtf8().data());
836
837         Response* parsedObj = Tools::parseResponse(serialized.toLatin1(), QByteArray(SERIALIZATION__TURTLE));
838         parsedObj->destroyCascade();
839
840         qDebug() << "Test done.";
841         return true;
842 }
843
844 bool listSerializeParseTest()
845 {
846         QDateTime now = QDateTime::currentDateTime();
847         
848         TimeSeries* ts = new TimeSeries();
849         
850         QList<GraphItem*> testList;
851         
852         for (int i = 0; i < 5; i++) {
853                 Evaluation* e = new Evaluation();
854                 e->setValue(new Variant(i));
855                 e->setInstant(now.addDays(i));
856
857                 testList.append(e);
858         }
859         ts->setList(testList);
860         
861         QString stringData = Tools::toString(ts, SERIALIZATION__TURTLE);
862         ts->destroyCascade();
863         
864         qDebug() << "Serialized data:";
865         printf("%s\n", stringData.toUtf8().data());
866
867         qDebug() << "Parsing back the serialized data...";
868
869         TimeSeries* tsParsed = (TimeSeries*)Tools::fromStringAsObj(stringData, SERIALIZATION__TURTLE);
870
871         if (tsParsed->hasList()) {
872                 QList<GraphItem*> tsl = tsParsed->getList().toQList();
873                 qDebug() << "has list" << tsl.length();
874                 for (int j = 0; j < tsl.length(); j++) {
875                         Evaluation* e = (Evaluation*)tsl.at(j);
876                         QString instant = e->getInstant().toString();
877                         int value = e->getValue()->getValue().toInt();
878                         qDebug() << "Value:" << instant << value;
879                         if (value == j) {
880                                 qDebug() << "value ok";
881                         } else {
882                                 return false;
883                         }
884                         int msecDiff = now.addDays(j).msecsTo(QDateTime::fromString(instant, "ddd MMM dd HH:mm:ss yyyy"));
885                         if ((msecDiff < 1000) && (msecDiff > -1000)) {
886                                 qDebug() << "timestamp ok";
887                         } else {
888                                 return false;
889                         }
890                 }
891         } else {
892                 return false;
893         }
894         tsParsed->destroyCascade();
895
896         return true;
897 }
898
899 bool listSpeedTest()
900 {
901         Model* model = Factory::createModel();
902         QString stringData;
903         int i = 0;
904         LinkedList* ll = new LinkedList(model);
905         OrderedList* ol = new OrderedList(model);
906         ItemizedList* il = new ItemizedList(model);
907         NudeList* nl = new NudeList(model);
908         QVariantList ql;
909         
910         ll->setBaseObject(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "linked"));
911         ol->setBaseObject(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "ordered"));
912         il->setBaseObject(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "itemized"));
913         nl->setBaseObject(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "nude"));
914
915         //for (i = 0; i < 3000000; i++) {
916         for (i = 0; i < 5; i++) {
917                 ll->append(new Variant(i), true);
918                 ol->append(new Variant(i), true);
919                 il->append(new Variant(i), true);
920                 nl->append(new Variant(i), true);
921                 ql << i;
922         }
923         
924         QVariantMap m;
925         m.insert("a", ql);
926         qDebug() << "JSON list";
927         QDateTime jStart = QDateTime::currentDateTime();
928         QJsonObject jObject = QJsonObject::fromVariantMap(m);
929         QJsonDocument jData;
930         jData.setObject(jObject);
931         QByteArray data =  jData.toJson();
932         QDateTime jEnd = QDateTime::currentDateTime();
933         
934         qDebug() << "Ordered list";
935         QDateTime oStart = QDateTime::currentDateTime();
936         stringData = Tools::toString(ol, SERIALIZATION__TURTLE);
937         QDateTime oEnd = QDateTime::currentDateTime();
938         printf("\nOutput:\n%s\n", stringData.toUtf8().data());
939
940         qDebug() << "Itemized list";
941         QDateTime iStart = QDateTime::currentDateTime();
942         stringData = Tools::toString(il, SERIALIZATION__TURTLE);
943         QDateTime iEnd = QDateTime::currentDateTime();
944         printf("\nOutput:\n%s\n", stringData.toUtf8().data());
945         
946         qDebug() << "Nude list";
947         QDateTime nStart = QDateTime::currentDateTime();
948         stringData = Tools::toString(nl, SERIALIZATION__TURTLE);
949         QDateTime nEnd = QDateTime::currentDateTime();
950         printf("\nOutput:\n%s\n", stringData.toUtf8().data());
951
952         qDebug() << "Linked list";
953         QDateTime lStart = QDateTime::currentDateTime();
954         stringData = Tools::toString(ll, SERIALIZATION__TURTLE);
955         QDateTime lEnd = QDateTime::currentDateTime();
956         printf("\nOutput:\n%s\n", stringData.toUtf8().data());
957
958         qDebug() << "RESULTS";
959         qDebug() << "Ordered list" << oStart.msecsTo(oEnd)/1000.0;
960         qDebug() << "Unordered list" << iStart.msecsTo(iEnd)/1000.0;
961         qDebug() << "Nude list" << nStart.msecsTo(nEnd)/1000.0;
962         qDebug() << "Linked list" << lStart.msecsTo(lEnd)/1000.0;
963         qDebug() << "JSON reference" << jStart.msecsTo(jEnd)/1000.0;
964         
965         // Note that the lists do not need to be deleted, they are added directly to the resource
966         delete model;
967         return true;
968 }
969
970 bool baseObjectListSerializeParseTest()
971 {
972         Model* model = Factory::createModel();
973         ValueObject* base1 = new ValueObject();
974         ValueObject* base2 = new ValueObject();
975         ValueObject* base3 = new ValueObject();
976         ValueObject* base4 = new ValueObject();
977
978         base1->setUnit(NS__UNIT + "Centimeter");
979         base2->setUnit(NS__UNIT + "Meter");
980         base3->setUnit(NS__UNIT + "Millimeter");
981         base4->setUnit(NS__UNIT + "Kilometer");
982
983         // Explicitly create lists
984         LinkedList* ll = new LinkedList(model);
985         OrderedList* ol = new OrderedList(model);
986         ItemizedList* il = new ItemizedList(model);
987         NudeList* nl = new NudeList(model);
988         OrderedList* cl = new OrderedList(model);
989
990         ll->setBaseObject(base1);
991         il->setBaseObject(base2);
992         ol->setBaseObject(base3);
993         nl->setBaseObject(base4);
994
995         ll->setBaseObjectProperty(PROPERTY__FRESHNESS);
996         il->setBaseObjectProperty(PROPERTY__FRESHNESS);
997         ol->setBaseObjectProperty(PROPERTY__FRESHNESS);
998         nl->setBaseObjectProperty(PROPERTY__FRESHNESS);
999
1000         for (int i = 0; i < 5; i++) {
1001                 ll->append(new Variant(i), true);
1002                 ol->append(new Variant(i), true);
1003                 il->append(new Variant(i), true);
1004                 nl->append(new Variant(i), true);
1005         }
1006
1007         // add string
1008         ol->append(new Variant("Test item"), true);
1009         // or integer
1010         ol->append(new Variant(5), true);
1011         // or double
1012         ol->append(new Variant(3.4), true);
1013         // or boolean
1014         ol->append(new Variant(true), true);
1015         // or Date
1016         ol->append(new Variant(QDateTime::currentDateTime()), true);
1017         // or Time
1018         ol->append(new Variant(QTime::currentTime()), true);
1019
1020         Evaluation* item = new Evaluation();
1021         // add to list
1022         ol->append(new Variant(item), true);
1023
1024         qDebug() << "Linked list";
1025         QString stringData = Tools::toString(ll, SERIALIZATION__TURTLE);
1026         printf("%s\n", stringData.toUtf8().data());
1027
1028         qDebug() <<  "Itemized list";
1029         stringData = Tools::toString(il, SERIALIZATION__TURTLE);
1030         printf("%s\n", stringData.toUtf8().data());
1031
1032         qDebug() <<  "Ordered list";
1033         stringData = Tools::toString(ol, SERIALIZATION__TURTLE);
1034         printf("%s\n", stringData.toUtf8().data());
1035
1036         qDebug() <<  "Nude list";
1037         stringData = Tools::toString(nl, SERIALIZATION__TURTLE);
1038         printf("%s\n", stringData.toUtf8().data());
1039
1040         qDebug() << "Copied list";
1041         stringData = Tools::toString(cl, SERIALIZATION__TURTLE);
1042         printf("%s\n", stringData.toUtf8().data());
1043
1044         for ( int i = 0; i < cl->size(); i++ ) {
1045                 // get item at position
1046                 Variant* item = (Variant*)cl->get(i);
1047         }
1048
1049         delete model;
1050         return true;
1051 }
1052
1053 bool simpleTimeSeriesTest()
1054 {
1055         TimeSeries* timeSeries = new TimeSeries();
1056
1057         timeSeries->setQuantity(NS__QUANTITY + "Weight");
1058         timeSeries->setUnit(NS__UNIT + "Kilogram");
1059         timeSeries->setTimeStep("PT1S");
1060
1061         // add start datetime for timeseries
1062         timeSeries->setTemporalContext(new TemporalContext(QDateTime::currentDateTime()));
1063
1064         SystemOfInterest* systemOfInterest = new SystemOfInterest();
1065         systemOfInterest->setSameAs("http://seasexamples.asema.com/api/Ccommand");
1066         timeSeries->setSystemOfInterest(systemOfInterest);
1067
1068         for (int i = 0; i < 5; i++) {
1069                 timeSeries->addListItem(new Variant(i));
1070         }
1071         QString stringData = Tools::toString(timeSeries, SERIALIZATION__TURTLE);
1072         printf("%s\n", stringData.toUtf8().data());
1073         timeSeries->destroyCascade();
1074
1075         return true;
1076 }
1077
1078 bool valueObjectTimeSeriesTest()
1079 {
1080         TimeSeries* timeSeries = new TimeSeries();
1081         for (int i = 0; i < 5; i++) {
1082                 ValueObject* vo = new ValueObject();
1083                 vo->setQuantity(RESOURCE__ENERGYANDWORK);
1084                 vo->setUnit(RESOURCE__KILOWATTHOUR);
1085                 vo->setInstant(QDateTime::currentDateTime().addSecs(60*i));
1086                 vo->setValue(i);
1087                 timeSeries->addListItem(vo);
1088         }
1089
1090         // add start datetime for timeseries
1091         timeSeries->setTemporalContext(new TemporalContext(QDateTime::currentDateTime()));
1092
1093         QString stringData = Tools::toString(timeSeries, SERIALIZATION__TURTLE);
1094         printf("%s\n", stringData.toUtf8().data());
1095         timeSeries->destroyCascade();
1096
1097         return true;
1098 }
1099
1100 bool substitutiveValueObjectTimeSeriesTest()
1101 {
1102         TimeSeries* timeSeries = new TimeSeries();
1103         timeSeries->setBaseList(new ItemizedList());
1104         for (int i = 0; i < 5; i++) {
1105                 ValueObject* vo = new ValueObject();
1106                 vo->setQuantity(RESOURCE__ENERGYANDWORK);
1107                 vo->setUnit(RESOURCE__KILOWATTHOUR);
1108                 vo->setInstant(QDateTime::currentDateTime().addSecs(60*i));
1109                 vo->setValue(i);
1110                 timeSeries->addListItem(new Variant(vo));
1111         }
1112
1113         // add start datetime for timeseries
1114         timeSeries->setTemporalContext(new TemporalContext(QDateTime::currentDateTime()));
1115
1116         QString stringData = Tools::toString(timeSeries, SERIALIZATION__TURTLE);
1117         printf("%s\n", stringData.toUtf8().data());
1118         timeSeries->destroyCascade();
1119
1120         return true;
1121 }
1122
1123 bool timeSeriesManipulationTest()
1124 {
1125         TimeSeries* timeSeries = new TimeSeries();
1126         timeSeries->setBaseList(new ItemizedList());
1127
1128         for (int i = 0; i < 5; i++) {
1129                 ValueObject* vo = new ValueObject();
1130                 vo->setQuantity(RESOURCE__ENERGYANDWORK);
1131                 vo->setUnit(RESOURCE__KILOWATTHOUR);
1132                 vo->setInstant(QDateTime::currentDateTime().addSecs(60*i));
1133                 vo->setValue(i);
1134                 timeSeries->addListItem(vo);
1135         }
1136
1137         for ( int i = 0; i < timeSeries->getListSize(); i++ ) {
1138                 // assuming that the base object is ValueObject
1139                 Variant* item = (Variant*)timeSeries->getListItem(i);
1140                 if (item != NULL) {
1141                         QDateTime timeStamp = ((ValueObject*)item)->getInstant();
1142                         QString quantity = ((ValueObject*)item)->getQuantity();
1143                         QString unit = ((ValueObject*)item)->getUnit();
1144                 }
1145         }
1146
1147         TimeSeries* timeSeriesI = new TimeSeries(new NudeList());
1148
1149         Evaluation* baseObject = new Evaluation();
1150         baseObject->setQuantity(RESOURCE__ENERGYANDWORK);
1151         baseObject->setUnit(RESOURCE__KILOWATTHOUR);
1152         timeSeriesI->setBaseObject(baseObject);
1153
1154         // add start datetime for timeseries
1155         timeSeriesI->setTemporalContext(new TemporalContext(QDateTime::currentDateTime()));
1156
1157         // add timestep (1 second interval between data items)
1158         timeSeriesI->setTimeStep("PT1S");
1159
1160         // add three items with different values
1161         for ( int i = 0; i < 5; i++ ) {
1162                 timeSeriesI->addListItem(new Variant(i));
1163         }
1164
1165         QString stringData = Tools::toString(timeSeriesI, SERIALIZATION__TURTLE);
1166         printf("%s\n", stringData.toUtf8().data());
1167         timeSeriesI->destroyCascade();
1168         timeSeries->destroyCascade();
1169         return true;
1170 }
1171
1172
1173 bool baseObjectTimeSeriesTest()
1174 {
1175         bool parsedOk = false;
1176         TimeSeries* ts = new TimeSeries();
1177         ValueObject* baseObject = new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos");
1178         ts->setBaseObject(baseObject);
1179
1180         for (int d = 0; d < 10; d++) {
1181                 ts->addListItem(new ValueObject(QDateTime::currentDateTime().addSecs(60*d), d));
1182         }
1183         QString serialized = Tools::toString(ts, SERIALIZATION__TURTLE);
1184         ts->destroyCascade();
1185         printf("%s\n", serialized.toUtf8().data());
1186         qDebug() << "------------------";
1187
1188         TimeSeries* tsParsed = (TimeSeries*)Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
1189         qDebug() << "The parsed base object" << tsParsed->getBaseObject();
1190         if (tsParsed->getBaseObject() != NULL) parsedOk = true;
1191         serialized = Tools::toString(tsParsed, SERIALIZATION__TURTLE);
1192         tsParsed->destroyCascade();
1193         printf("\nReserialized:\n%s\n", serialized.toUtf8().data());
1194
1195         return parsedOk;
1196 }
1197
1198 bool substitutiveTimeSeriesParseTest()
1199 {
1200         bool parsedOk = false;
1201         TimeSeries* ts = new TimeSeries();
1202         ts->setBaseList(new OrderedList());
1203         ValueObject* baseObject = new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos");
1204         ts->setBaseObject(baseObject);
1205         ts->setBaseObjectProperty(PROPERTY__WEIGHT);
1206
1207         for (int d = 0; d < 10; d++) {
1208                 ts->addListItem(new ValueObject(QDateTime::currentDateTime().addSecs(60*d), d));
1209         }
1210         QString serialized = Tools::toString(ts, SERIALIZATION__TURTLE);
1211         ts->destroyCascade();
1212         printf("%s\n", serialized.toUtf8().data());
1213         qDebug() << "------------------";
1214
1215         TimeSeries* tsParsed = (TimeSeries*)Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
1216         if (tsParsed->getBaseObject() != NULL) parsedOk = true;
1217         serialized = Tools::toString(tsParsed, SERIALIZATION__TURTLE);
1218         tsParsed->destroyCascade();
1219         printf("\nReserialized:\n%s\n", serialized.toUtf8().data());
1220
1221         return parsedOk;
1222 }
1223
1224 bool networkTimeSeriesTest()
1225 {
1226         QUrl serviceUrl = QUrl("http://127.0.0.1:8099/seas/v1.0/access/");
1227         QString myId = "http://seasdemos.asema.com/cplusplus/controlcommandsender/Cabcd";
1228
1229         QNetworkAccessManager *networkManager = new QNetworkAccessManager();
1230         QEventLoop postWaitLoop;
1231         
1232         Request* tsRequest = RequestFactory::create(myId);
1233
1234         Activity* a = new Activity();
1235         QDateTime seriesEnd = QDateTime::currentDateTime();
1236         QDateTime seriesStart = seriesEnd.addDays(-1);
1237
1238         // system of interest
1239         SystemOfInterest* systemOfInterest = new SystemOfInterest();
1240         systemOfInterest->setSameAs("http://seasexamples.asema.com/api/Ctimeseries");
1241         tsRequest->setSystemOfInterest(systemOfInterest);
1242
1243         TemporalContext* tc = new TemporalContext();
1244         tc->setStart(seriesStart);
1245         tc->setEnd(seriesEnd);
1246
1247         tsRequest->addActivity(a);
1248         Input* i = new Input();
1249         i->setTemporalContext(tc);
1250         a->setInput(i);
1251
1252         ValueObject* v1 = new ValueObject();
1253         v1->setQuantity(NS__SMARTAPI + "Temperature");
1254         v1->setUnit(NS__SMARTAPI + "DegreeCelsius");
1255         tsRequest->add(NS__SMARTAPI + "Temperature", v1);
1256
1257         ValueObject* v2 = new ValueObject();
1258         v2->setQuantity(NS__SMARTAPI + "Cloudiness");
1259         v2->setUnit(NS__SMARTAPI + "Percent");
1260         tsRequest->add(NS__SMARTAPI + "Cloudiness", v2);
1261
1262         ValueObject* v3 = new ValueObject();
1263         v3->setQuantity(NS__SMARTAPI + "Precipitation");
1264         v3->setUnit(NS__SMARTAPI + "Millimeter");
1265         tsRequest->add(NS__SMARTAPI + "Precipitation", v3);
1266
1267         QString payload = Tools::toString(tsRequest, SERIALIZATION__TURTLE);
1268         tsRequest->destroyCascade();
1269         
1270         QNetworkRequest request(serviceUrl);
1271         request.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE__TURTLE);
1272         request.setRawHeader(QByteArray("X-SmartAPI-CallId"), QByteArray("1"));
1273         request.setRawHeader(QByteArray("X-SmartAPI-Method"), QByteArray("fetchData"));
1274         request.setRawHeader(QByteArray("Accept"), QByteArray(CONTENT_TYPE__TURTLE));
1275         
1276         QNetworkReply* reply = networkManager->post(request, payload.toUtf8());
1277         QObject::connect( reply, SIGNAL(finished()), &postWaitLoop, SLOT(quit()));
1278         postWaitLoop.exec( QEventLoop::ExcludeUserInputEvents );
1279         
1280         QByteArray result = reply->readAll();
1281         reply->deleteLater();
1282         networkManager->deleteLater();
1283
1284         qDebug() << "Result: " << result;
1285         
1286         Model* m = Tools::fromString(QString(result), SERIALIZATION__TURTLE);
1287         Resource* res = Tools::getResourceByType(RESOURCE__RESPONSE, m);
1288         Evaluation* tsResponse = Obj::parse<Evaluation>(res);
1289         delete res;
1290         delete m;
1291
1292         if (tsResponse->hasTemporalContext()) {
1293                 qDebug() << "Received timeseries";
1294                 if (tsResponse->getTemporalContext()->hasStart() && tsResponse->getTemporalContext()->hasEnd()) {
1295                         qDebug() << "starts " << tsResponse->getTemporalContext()->getStart();
1296                         qDebug() << "ends " << tsResponse->getTemporalContext()->getEnd();
1297                 }
1298         }
1299         
1300         if (tsResponse->hasTimeSerie()) {
1301                 QList<TimeSeries*> l = tsResponse->getTimeSeries().toQList();
1302                 for (int i = 0; i < l.length(); i++) {
1303                         TimeSeries* ts = l.at(i);
1304                         if (ts->hasList()) {
1305                                 QList<GraphItem*> tsl = ts->getList().toQList();
1306                                 for (int j = 0; j < tsl.length(); j++) {
1307                                         Evaluation* e = (Evaluation*)tsl.at(j);
1308                                         qDebug() << "Value:" << e->getInstant().toString() << e->getValue()->getValue().toDouble();
1309                                 }
1310                         }
1311                 }
1312                 
1313         }
1314         
1315         tsResponse->destroyCascade();
1316         return true;
1317 }
1318
1319 bool notificationTest()
1320 {
1321         QString myId = "http://seasdemos.asema.com/csharp/controlcommandsender/Cabcd";
1322
1323         Notification* notification = NotificationFactory::create(myId);
1324         Activity* activity = new Activity();
1325         Output* output = new Output();
1326         SystemOfInterest* soi = new SystemOfInterest();
1327         SystemOfInterest* capacitySoi = new SystemOfInterest();
1328         Address* address = new Address();
1329         Velocity* speed = new Velocity();
1330         Direction* direction = new Direction();
1331         Capacity* capacity = new Capacity();
1332         PhysicalEntity* vehicle = new PhysicalEntity();
1333
1334         soi->addType(RESOURCE__CAR);
1335         soi->setSameAs(myId);
1336         soi->setName("Simulated vehicle 1");
1337
1338         capacitySoi->addType(RESOURCE__BATTERY);
1339         vehicle->addType(RESOURCE__CAR);
1340         output->addCategory(RESOURCE__OBSERVATION);
1341
1342         activity->addOutput(output);
1343         notification->addActivity(activity);
1344         output->setSystemOfInterest(soi);
1345         soi->setRealizedBy(vehicle);
1346         vehicle->setVelocity(speed);
1347         vehicle->setAddress(address);
1348         vehicle->setDirection(direction);
1349         vehicle->addCapacity(capacity);
1350
1351         capacity->setSystemOfInterest(capacitySoi);
1352         capacity->setQuantity(RESOURCE__POWER);
1353         capacity->setUnit(RESOURCE__KILOWATT);
1354         capacity->setMaximum(new Variant(2000));
1355         capacity->setValue(new Variant(1000));
1356
1357         vehicle->setCoordinates(new Coordinates(60.4, 30.2));
1358         direction->setBearing(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(30)));
1359         speed->setGroundSpeed(new ValueObject(NS__UNIT + "MeterPerSecond", new Variant(10)));
1360
1361         QString payload = Tools::toString(notification, SERIALIZATION__TURTLE);
1362
1363         qDebug() << "Serialized:";
1364         printf("%s\n", payload.toLatin1().data());
1365         notification->destroyCascade();
1366
1367         Obj* parsedObj = Tools::fromStringAsObj(payload);
1368         if (Notification* parsedNotification = dynamic_cast<Notification*>(parsedObj)) {
1369                 QString reserialized = Tools::toString(parsedNotification, SERIALIZATION__TURTLE);
1370                 qDebug() << "Re-Serialized:";
1371                 printf("%s\n", reserialized.toLatin1().data());
1372         }
1373         parsedObj->destroyCascade();
1374
1375         return true;
1376 }
1377
1378 bool offeringTest()
1379 {
1380         QString myId = "http://seasdemos.asema.com/csharp/controlcommandsender/Cabcd";
1381         QString offerName = "Test offer";
1382         QString offerDescription = "Some offer description";
1383
1384         Activity* activity = new Activity();
1385         Offering* offering = new Offering(myId + "/" + SmartAPICrypto::generate16ByteCryptoRandomString(), offerName, offerDescription);
1386         offering->setBusinessFunction(RESOURCE__SELL);
1387
1388         UnitPriceSpecification* priceSpecification1 = new UnitPriceSpecification();
1389         priceSpecification1->setCurrency("EUR");
1390         priceSpecification1->setCurrencyValue(10.0);
1391         priceSpecification1->setValidThrough(QDateTime::currentDateTime());
1392         UnitPriceSpecification* priceSpecification2 = new UnitPriceSpecification();
1393         priceSpecification2->setCurrency("EUR");
1394         priceSpecification2->setCurrencyValue(12.0);
1395         priceSpecification2->setValidThrough(QDateTime::currentDateTime());
1396
1397         offering->addPriceSpecification(priceSpecification1);
1398         offering->addPriceSpecification(priceSpecification2);
1399
1400         SomeItems* items = new SomeItems(RESOURCE__REQUEST, "Service request", "Any kind of service request.", myId);
1401         offering->addIncludes(items);
1402         activity->addOffering(offering);
1403         QString payload = Tools::toString(activity, SERIALIZATION__TURTLE);
1404
1405         qDebug() << "Serialized:";
1406         printf("%s\n", payload.toLatin1().data());
1407         activity->destroyCascade();
1408
1409         Obj* parsedObj = Tools::fromStringAsObj(payload);
1410         if (Activity* parsedActivity = dynamic_cast<Activity*>(parsedObj)) {
1411                 QString reserialized = Tools::toString(parsedActivity, SERIALIZATION__TURTLE);
1412                 qDebug() << "Re-Serialized:";
1413                 printf("%s\n", reserialized.toLatin1().data());
1414         }
1415         parsedObj->destroyCascade();
1416         return true;
1417 }
1418
1419 bool listOfMapsTest()
1420 {
1421         Activity* a = new Activity();
1422         Input* i = new Input();
1423         Output* o = new Output();
1424         a->addInput(i);
1425         a->addOutput(o);
1426
1427         // Input
1428         QList<Map*> controllable_appliances;
1429         QList<Map*> controllable_works;
1430         
1431         Map* works1 = new Map();
1432         works1->insert("EarlyStartPeriod", 2147483647);
1433         works1->insert("LateStopPeriod", 2147483647);
1434         works1->insert("WorkDuration", 2147483647);
1435
1436         Map* appliance1 = new Map();
1437         appliance1->insert("Active", 4);
1438         appliance1->insert("ConsumptionRate", 1.267);
1439         appliance1->insert("Name", "String content");
1440         appliance1->add("ControllableWorks", works1); //controllable_works);
1441         
1442         //controllable_works.append(works1);
1443         controllable_appliances.append(appliance1);
1444         i->add("ControllableAppliances", controllable_appliances);
1445
1446         // Output
1447         QList<Map*> controllable_appliance_result;
1448         QList<Map*> controllable_appliance_work_result;
1449
1450         Map* appliance_result_1 = new Map();
1451         Map* work_result_1 = new Map();
1452         Map* usage_information = new Map();
1453         
1454         appliance_result_1->insert("Name", "Appliance result string");
1455         usage_information->insert("StartPeriod", 2147483647);
1456         usage_information->insert("StopPeriod", 2147483647);
1457         usage_information->insert("WorkDuration", 2147483647);
1458         work_result_1->add("UsageInformation", usage_information);
1459         controllable_appliance_work_result.append(work_result_1);
1460         appliance_result_1->insert("ControllableWorkResult", controllable_appliance_work_result);
1461         
1462         //QList<Map*> period_consumptions;
1463         Map* period_1 = new Map();
1464         period_1->insert("Period", 2147483647);
1465         period_1->insert("Value", 1.26743);
1466         //period_consumptions.append(period_1);
1467         work_result_1->add("PeriodConsumption", period_1); //period_consumptions);
1468         
1469         controllable_appliance_result.append(appliance_result_1);
1470         o->add("ControllableApplianceResult", controllable_appliance_result);
1471         qDebug() << "Start serializing...";
1472
1473         QString serialized = Tools::toString(a, SERIALIZATION__TURTLE);
1474         qDebug() << "Serialized:\n";
1475         printf("\n%s\n", serialized.toUtf8().constData());
1476         a->destroyCascade();
1477         
1478         qDebug() << "Start parsing...";
1479         Obj* a_parsed = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
1480
1481         if (a_parsed != NULL) {
1482                 QString reserialized = Tools::toString(a_parsed, SERIALIZATION__TURTLE);
1483
1484                 qDebug() << "----";
1485                 qDebug() << "Re-serialized:";
1486                 printf("\n%s\n", reserialized.toUtf8().constData());
1487                 a_parsed->destroyCascade();
1488                 return true;
1489         } else {
1490                 qDebug() << "Parsing failed.";
1491                 return false;
1492         }
1493 }
1494
1495 //bool chargePlanRegistrationTest()
1496 //{
1497 //      QString serverIdentity = "http://seasexamples.asema.com/api/Ctestserver";
1498 //      QString serverName = "A sample charging plan calculation service";
1499
1500 //      Service* service = new Service(serverIdentity);
1501
1502 //      // Service metadata
1503 //      Organization* owner = new Organization();
1504 //      Address* acmeAddress = new Address();
1505 //      InterfaceAddress* iface = new InterfaceAddress();
1506
1507 //      iface->setHost("www.acme.com");
1508 //      iface->setScheme("https");
1509 //      iface->setPath("/seas/v1.0e1.0/access");
1510 //      acmeAddress->setStreetAddress("Giant Rubber Band Street");
1511 //      acmeAddress->setZipCode("12345");
1512 //      acmeAddress->setCity("Fairfield, New Jersey");
1513 //      owner->setName("Acme Industries");
1514 //      owner->setAddress(acmeAddress);
1515
1516 //      service->addInterface(iface);
1517 //      service->addOwner(owner);
1518 //      service->setName(serverName);
1519 //      service->setDescription("A charging plan service that supplies the available energy for charging in timeslots at a charging point.");
1520 //      service->addWebsite("http://www.acme.com/acmeoptimizers/roadrunner/beep/beep");
1521
1522
1523 //      // API payload data
1524 //      Activity* a = new Activity();
1525 //      Input* i = new Input();
1526 //      Output* o = new Output();
1527 //      a->addOutput(o);
1528 //      a->addInput(i);
1529 //      service->addCapability(a);
1530
1531 //      // Input
1532 //      Map* charge_need = new Map();
1533 //      charge_need->insert("Energy", Factory::createValueObject(NS__UNIT + "KilowattHour", "Total amount of energy requested to complete the charge."));
1534 //      charge_need->insert("PowerMax", Factory::createValueObject(NS__UNIT + "Watt", "Maximum allowed instant power for charging the vehicle."));
1535 //      charge_need->insert("PowerMin", Factory::createValueObject(NS__UNIT + "Watt", "Minumum allowed instant power for charging the vehicle."));
1536 //      charge_need->insert("Priority", new Obj(DATATYPE__INTEGER));
1537 //      charge_need->insert("Type", new Enumeration("Immediate", "Delayed"));
1538 //      TemporalContext* tci = new TemporalContext();
1539 //      tci->setDescription("The desired schedule at which the charging should take place (start (optional) and end)");
1540 //      charge_need->insert("Schedule", tci);
1541 //      i->add("ChargingNeed", charge_need);
1542
1543 //      // Output
1544 //      Map* charge_plan = new Map();
1545 //      QList<Map*> orders;
1546 //      Map* order = new Map();
1547 //      TemporalContext* tco = new TemporalContext();
1548 //      tco->setDescription("The start and end times of this charging slot.");
1549 //      order->insert("Schedule", tco);
1550 //      order->insert("Power", Factory::createValueObject(NS__UNIT + "Watt", "The instant power supplied in this slot."));
1551 //      orders.append(order);
1552 //      charge_plan->insert("Orders", orders);
1553 //      o->add("ChargingPlan", charge_plan);
1554
1555 //      RegistrationAgent* agent = new RegistrationAgent(serverIdentity);
1556 //      QString payload = agent->generateRegistrationMessage(service);
1557 //      printf("%s\n", payload.toUtf8().constData());
1558 //      service->destroyCascade();
1559 //    delete agent;
1560
1561 //    return true;
1562 //}
1563
1564 EVP_PKEY* getPemPublicKey(QString fileName)
1565 {
1566         return SmartAPICrypto::loadPemPublicKey(fileName);
1567 }
1568
1569 EVP_PKEY* getPemPrivateKey(QString fileName)
1570 {
1571         return SmartAPICrypto::loadPemPrivateKey(fileName);
1572 }
1573
1574 Service* createSampleRegistrationEntity(QString serverIdentity)
1575 {
1576         QString serverName = "A C++ sample route energy calculation service";
1577
1578         Service* service = new Service(serverIdentity);
1579
1580         // Service metadata
1581         Organization* owner = new Organization();
1582         Address* acmeAddress = new Address();
1583         InterfaceAddress* iface = new InterfaceAddress();
1584
1585         iface->setHost("www.acme.com");
1586         iface->setScheme("https");
1587         iface->setPath("/seas/v1.0e1.0/access");
1588         acmeAddress->setStreetAddress("Giant Rubber Band Street");
1589         acmeAddress->setZipCode("12345");
1590         acmeAddress->setCity("Fairfield, Cee");
1591         owner->setName("Acme Industries");
1592         owner->setAddress(acmeAddress);
1593
1594         service->addInterface(iface);
1595         service->addOwner(owner);
1596         
1597         
1598         service->setName(serverName);
1599         service->setDescription("A route calculation service that in addition to length and driving time calculates the amount of energy consumed in the battery. Takes as parameters various efficiency factors such as weight and drag.");
1600         service->addWebsite("http://www.acme.com/acmeoptimizers/roadrunner/beep/beep");
1601
1602         // API payload data
1603         Activity* a = new Activity();
1604         Input* i = new Input();
1605         Output* o = new Output();
1606         a->addOutput(o);
1607         a->addInput(i);
1608         service->addCapability(a);
1609
1610         PhysicalEntity* car = new PhysicalEntity();
1611         car->setWeight(Factory().createValueObject(NS__UNIT + "Kilogram", "Vehicle's weight without any consumables or passengers."));
1612         car->add("frontalAerodynamicCoefficient", Factory::createValueObject(NS__UNIT + "SquareMeter", "Product of vehicle's frontal area and aerodynamic coefficient"));
1613         car->add("tireRollingResistanceCoefficient", Factory::createValueObject(new Obj(DATATYPE__INTEGER), "Vehicle's tire rolling resistance coefficient, in interval ]0, 1["));
1614         car->add("gearEfficiencyCoefficient", Factory::createValueObject("Vehicle's efficiency coefficient between engine and gear, in interval ]0, 1["));
1615         car->add("batteryCapacity", Factory::createValueObject(NS__UNIT + "KilowattHour", "Vehicle's capacity of the battery (enter only if electric vehicle or hybrid rechargeable, 0 otherwise"));
1616         car->add("extraLoadWeight", Factory::createValueObject(NS__UNIT + "Kilogram", "Vehicle's extra load (consumables and passengers weight)"));
1617         car->add("auxiliaryEquipmentConsumption", Factory::createValueObject(NS__UNIT + "Watt", "Vehicle's instantaneous auxiliary equipments consumption"));
1618         car->add("maximumAcceleration", Factory::createValueObject(NS__UNIT + "MeterPerSecondSquared", "Maximum acceleration (> 0.1), based on vehicle's acceleration capacity and expected driving behavior"));
1619         car->add("maximumDeceleration", Factory::createValueObject(NS__UNIT + "MeterPerSecondSquared", "Maximum deceleration (< -0.1), based on vehicle's braking capacity and expected driving behavior"));
1620         i->add("vehicleData", car);
1621
1622         TemporalContext* tc = new TemporalContext();
1623         Velocity* averageVelocity = new Velocity();
1624         Route* route = new Route();
1625
1626         tc->setDescription("The timespan estimated for traveling the route.");
1627         averageVelocity->setDescription("Estimated average speed for the travel.");
1628
1629         averageVelocity->setGroundSpeed(Factory::createValueObject(NS__UNIT + "KilometerPerHour", "Velocity component in relation to road surface."));
1630         
1631         route->setLength(Factory::createValueObject(NS__UNIT + "Kilometer", "Total length of the calculated route."));
1632         route->setEnergyConsumption(Factory::createValueObject(NS__UNIT + "KilowattHour", "Total energy consumed in driving the route."));
1633         route->setAverageVelocity(averageVelocity);
1634         route->setDuration(tc);
1635
1636         o->add("routeData", route);
1637         
1638         return service;
1639 }
1640
1641 //bool encryptedRegistrationTest()
1642 //{
1643 //      QString serverIdentity = "http://seasexamples.asema.com/api/Ctestserver";
1644 //      QString serverName = "A sample charging plan calculation service";
1645
1646 //      EVP_PKEY* pubKey = getPemPublicKey("../../Java/SmartAPI/src/smartapi/tests/testkey_public.pem");
1647 //      EVP_PKEY* privKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
1648
1649 //      Service* service = createSampleRegistrationEntity(serverIdentity);
1650
1651 //      RegistrationAgent agent(serverIdentity);
1652
1653 //      QByteArray symKey;
1654 //      QString payload = agent.generateEncryptedRegistrationMessage(pubKey, service, &symKey);
1655 //      printf("%s\n", payload.toUtf8().constData());
1656         
1657 //      //printf("%s\n", payload.toUtf8().data());
1658 //      QString decrypted = SmartAPICrypto::asymmetricDecrypt(privKey, payload, &symKey);
1659 //      printf("Decrypted len: %d\n", decrypted.length());
1660 //      printf("%s\n", decrypted.toUtf8().data());
1661         
1662 //      qDebug() << "------";
1663 //      QString ct = SmartAPICrypto::symmetricEncrypt((unsigned char*)symKey.constData(), decrypted);
1664 //      printf("%s\n", ct.toUtf8().data());
1665 //      QString pt = SmartAPICrypto::symmetricDecrypt((unsigned char*)symKey.constData(), ct);
1666 //      printf("%s\n", pt.toUtf8().data());
1667         
1668 //      service->destroyCascade();
1669 //      EVP_PKEY_free(pubKey);
1670 //      EVP_PKEY_free(privKey);
1671
1672 //      return true;
1673 //}
1674
1675 bool gatewayRegistrationTest()
1676 {
1677         QString myIdentity = "http://www.itron.com";
1678         QString gatewayIdentity = "http://itron.ilm.net/core/Gateway153";
1679         QString acMeterIdentity = "http://itron.ilm.net/core/ACmeter2493";
1680         QString dcMeterIdentity = "http://itron.ilm.net/core/DCmeter2494";
1681         
1682         Device* gateway = new Device(gatewayIdentity);
1683         Device* acMeter = new Device(acMeterIdentity);
1684         Device* dcMeter = new Device(dcMeterIdentity);
1685         
1686         Organization* gatewayOwner = new Organization();
1687         Organization* acOwner = new Organization();
1688         Organization* dcOwner = new Organization();
1689         
1690         gateway->setName("Itron gateway");
1691         gateway->addManagedEntity(acMeter);
1692         gateway->addManagedEntity(dcMeter);
1693
1694         acMeter->setName("AC Electricity Smart Meter");
1695         dcMeter->setName("DC Electricity Smart Meter");
1696         
1697         gatewayOwner->setName("Itron");
1698         acOwner->setName("Itron");
1699         dcOwner->setName("Itron");
1700         
1701         Address* gatewayAddress = new Address();
1702         Address* acAddress = new Address();
1703         Address* dcAddress = new Address();
1704         
1705         gatewayAddress->setCity("Issy Les Moulineaux");
1706         acAddress->setCity("Issy Les Moulineaux");
1707         dcAddress->setCity("Issy Les Moulineaux");
1708         gatewayAddress->setCountry("France");
1709         acAddress->setCountry("France");
1710         dcAddress->setCountry("France");
1711         
1712         gateway->setAddress(gatewayAddress);
1713         acMeter->setAddress(acAddress);
1714         dcMeter->setAddress(dcAddress);
1715         gateway->addOwner(gatewayOwner);
1716         acMeter->addOwner(acOwner);
1717         dcMeter->addOwner(dcOwner);
1718         
1719         InterfaceAddress* gatewayIface = new InterfaceAddress();
1720         InterfaceAddress* acIface = new InterfaceAddress();
1721         InterfaceAddress* dcIface = new InterfaceAddress();
1722         
1723         gatewayIface->setHost("itron.ilm.net");
1724         acIface->setHost("itron.ilm.net");
1725         dcIface->setHost("itron.ilm.net");
1726         
1727         gatewayIface->setScheme("core");
1728         acIface->setScheme("core");
1729         dcIface->setScheme("core");
1730         
1731         gatewayIface->setPort(2000);
1732         acIface->setPort(2000);
1733         dcIface->setPort(2000);
1734         
1735         gatewayIface->setPath("/core/Gateway153");
1736         acIface->setPath("/core/ACmeter2493");
1737         dcIface->setPath("/core/DCmeter2494");
1738         
1739         gateway->addInterface(gatewayIface);
1740         acMeter->addInterface(acIface);
1741         dcMeter->addInterface(dcIface);
1742
1743         
1744         // add the api to the gateway
1745         Activity* activity = new Activity();
1746
1747         // input for selecting which output values (quantities and unit) are returned
1748         Input* i = new Input();
1749         Obj* serial = new Obj(DATATYPE__INTEGER);
1750         serial->setDescription("The meter serial number, as shown by the label on the meter");
1751         i->add("meterSerialNumber", serial);
1752         activity->addInput(i);
1753         
1754         Output* o = new Output();
1755         o->add(NS__SMARTAPI + "PowerConsumption", Factory::createValueObject(NS__UNIT + "Watt", "Power consumption."));
1756         o->add(NS__SMARTAPI + "AccumulatedConsumption", Factory::createValueObject(NS__UNIT + "WattHour", "Accumulated energy consumption."));
1757         activity->addOutput(o);
1758         gateway->addCapability(activity);
1759
1760         QString payload = Tools::toString(gateway, SERIALIZATION__TURTLE);
1761
1762         qDebug() << "Serialized:";
1763         printf("%s\n", payload.toLatin1().data());
1764         gateway->destroyCascade();
1765         
1766         Obj* a_parsed = Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
1767
1768         if (a_parsed != NULL) {
1769                 QString reserialized = Tools::toString(a_parsed, SERIALIZATION__TURTLE);
1770
1771                 qDebug() << "----";
1772                 qDebug() << "Re-serialized:";
1773                 printf("\n%s\n", reserialized.toUtf8().constData());
1774                 a_parsed->destroyCascade();
1775         } else {
1776                 qDebug() << "Parsing failed.";
1777                 return false;
1778         }
1779         
1780         // registrate
1781         //RegistrationAgent* agent = new RegistrationAgent(myIdentity);
1782         // Note: this will bind the entities to the agent which in turn will delete them
1783         //agent->addEntity(gateway);
1784         //agent->addEntity(acMeter);
1785         //agent->addEntity(dcMeter);
1786         
1787         //agent->makeRegistration();
1788         //QString payload = agent->generateRegistrationMessage();
1789         //printf("%s\n", payload.toUtf8().constData());
1790
1791         //delete agent;
1792         return true;
1793 }
1794
1795 bool faultyIdTest()
1796 {
1797         Activity* a1 = new Activity("http://act.com");
1798         a1->addInput(new Input());
1799
1800         // NOTE: all property lists of a2 are now considered copies of a1
1801         // Any objects put into a2 lists will not be deleted as it is assumed
1802         // that a1 will delete them.
1803         Activity* a2 = new Activity(a1);
1804
1805         Entity* e1 = new Entity("http://e1.com");
1806         e1->addCapability(a1);
1807         Entity* e2 = new Entity("http://e2.com");
1808         e2->addCapability(a1);
1809         Entity* e3 = new Entity("http://e3.com");
1810         e3->addCapability(a1);
1811         e3->addCapability(a2);
1812         
1813         Request* r = new Request();
1814
1815         // Adding entities into a2 instead of a1 would now cause a memory leak
1816         a1->addEntity(e1);
1817         a1->addEntity(e2);
1818         a1->addEntity(e3);
1819         r->addActivity(a1);
1820         r->addActivity(a2);
1821         QString payload = Tools::toString(r, SERIALIZATION__TURTLE);
1822
1823         qDebug() << "Serialized:";
1824         printf("%s\n", payload.toLatin1().data());
1825         r->destroyCascade();
1826
1827         return true;
1828 }
1829
1830 bool routeRequestTest()
1831 {
1832         QString myId = "http://seasdemos.asema.com/cplusplus/controlcommandsender/Cabcd";
1833
1834         Request* request = RequestFactory::create(myId);
1835         request->setMethod(NS__SMARTAPI + "Read");
1836
1837         Activity* activity = new Activity();
1838         Input* input = new Input();
1839
1840         SystemOfInterest* sys_of_interest = new SystemOfInterest();
1841         sys_of_interest->setType(NS__SMARTAPI + "ChargingStation");
1842         input->setSystemOfInterest(sys_of_interest);
1843
1844         Coordinates* coordinates = new Coordinates(41.3746157, 2.1428249);
1845
1846         input->add("search_coordinates", new Variant(coordinates));
1847         input->add("max_distance", new Variant(100));
1848
1849         activity->addInput(input);
1850         request->addActivity(activity);
1851
1852         QString payload = Tools::toString(request, SERIALIZATION__TURTLE);
1853         request->destroyCascade();
1854         
1855         
1856         QUrl serviceUrl = QUrl("http://127.0.0.1:8099/RoutingService/seas/v1.0/fetchData/");
1857
1858         QNetworkAccessManager *networkManager = new QNetworkAccessManager();
1859         QEventLoop postWaitLoop;
1860         
1861         QNetworkRequest nrequest(serviceUrl);
1862         nrequest.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE__TURTLE);
1863         nrequest.setRawHeader(QByteArray("X-SmartAPI-CallId"), QByteArray("1"));
1864         nrequest.setRawHeader(QByteArray("X-SmartAPI-Method"), QByteArray("fetchData"));
1865         nrequest.setRawHeader(QByteArray("Accept"), QByteArray(CONTENT_TYPE__TURTLE));
1866         
1867         QNetworkReply* reply = networkManager->post(nrequest, payload.toUtf8());
1868         QObject::connect( reply, SIGNAL(finished()), &postWaitLoop, SLOT(quit()));
1869         postWaitLoop.exec( QEventLoop::ExcludeUserInputEvents );
1870         
1871         QByteArray result = reply->readAll();
1872         reply->deleteLater();
1873         networkManager->deleteLater();
1874
1875         //printf("%s\n", result.data());
1876         
1877         QVariantMap rm;
1878         QVariantList resultList;
1879         Obj* o = Tools::fromStringAsObj(QString(result));
1880         if (Response* r = dynamic_cast<Response*>(o)) {
1881                 
1882                         if (r->hasActivity()) {
1883                                 Activity* a = r->getActivities().at(0);
1884                                 if (a->hasOutput()) {
1885                                         Output* o = a->getOutputs().at(0);
1886                                         QList<GraphItem*> results = o->getAll("result")->toQList();
1887                                         for (int i = 0; i < results.length(); i++) {
1888                                                 QVariantMap result;
1889                                                 float price = 0;
1890                                                 QString station_id = "";
1891                                                 QString requester_id = "";
1892                                                 float distance = 0;
1893                                                 QString time_of_arrival = "";
1894                                                 float latitude = 0;
1895                                                 float longitude = 0;
1896                                                 float energy_use = 0;
1897                                                 QVariantList route;
1898                                                 
1899                                                 Map* m = (Map*)((Variant*)results.at(i))->asObj();
1900                                                 if (m) {
1901                                                         Variant* vo_i = m->get("price");
1902                                                         Variant* si_i = m->get("station_id");
1903                                                         Variant* ri_i = m->get("requester_id");
1904                                                         Variant* di_i = m->get("distance");
1905                                                         Variant* co_i = m->get("coordinates");
1906                                                         Variant* ro_i = m->get("route");
1907                                                         Variant* ta_i = m->get("time_of_arrival");
1908
1909                                                         if (vo_i != NULL && vo_i->asObj() != NULL) price = ((ValueObject*)vo_i->asObj())->getValue()->asFloat();
1910                                                         if (si_i != NULL && si_i->asObj() != NULL) station_id = ((SystemOfInterest*)si_i->asObj())->getSameAs()->getIdentifierUri();
1911                                                         if (ri_i != NULL) requester_id = ri_i->asString();
1912                                                         if (di_i != NULL && di_i->asObj() != NULL) distance = ((ValueObject*)di_i->asObj())->getValue()->asFloat();
1913                                                         if (ta_i != NULL) time_of_arrival = ta_i->asString();
1914                                                         if (co_i != NULL) {
1915                                                                 Coordinates* c = (Coordinates*)co_i->asObj();
1916                                                                 if (c != NULL) {
1917                                                                         latitude = c->getLatitude();
1918                                                                         longitude = c->getLongitude();
1919                                                                 }
1920                                                         }
1921                                                         if (ro_i != NULL) {
1922                                                                 Route* r = (Route*)ro_i->asObj();
1923                                                                 if (r != NULL) {
1924                                                                         PropertyList<Coordinates*> cl = r->getRoutePoints();
1925                                                                         for (int j = 0; j < cl.length(); j++) {
1926                                                                                 Coordinates* cc = cl.at(j);
1927                                                                                 QVariantMap cm;
1928                                                                                 cm.insert("latitude", cc->getLatitude());
1929                                                                                 cm.insert("longitude", cc->getLongitude());
1930                                                                                 route << cm;
1931                                                                         }
1932                                                                 }
1933                                                         }
1934                                                 } else {
1935                                                         qDebug() << "The result map from Routing Service is NULL";
1936                                                         return false;
1937
1938                                                 }
1939                                                 result.insert("price", price);
1940                                                 result.insert("station_id", station_id);
1941                                                 result.insert("requester_id", requester_id);
1942                                                 result.insert("distance", distance);
1943                                                 result.insert("time_of_arrival", time_of_arrival);
1944                                                 result.insert("latitude", latitude);
1945                                                 result.insert("longitude", longitude);
1946                                                 result.insert("energy_use", energy_use);
1947                                                 result.insert("route", route);
1948                                                 resultList.append(result);
1949                                         }
1950                                 }
1951                 }
1952         } 
1953         o->destroyCascade();
1954         //qDebug() << resultList;
1955         rm.insert("results", resultList);
1956
1957         return true;
1958 }
1959
1960 //bool chargePlanFetchTest()
1961 //{
1962 //      QString myId = "http://seasdemos.asema.com/cplusplus/controlcommandsender/Cabcd";
1963
1964 //      Request* request = RequestFactory::create(myId);
1965 //      request->setMethod(NS__SMARTAPI + "Read");
1966         
1967 //      Activity* activity = new Activity();
1968 //      request->addActivity(activity);
1969
1970 //      Input* powerMaxSiteInput = new Input();
1971 //      powerMaxSiteInput->setName("PMaxSite");
1972         
1973 //      Input* needsInput = new Input();
1974 //      needsInput->setName("Needs");
1975
1976 //      activity->addInput(powerMaxSiteInput);
1977 //      activity->addInput(needsInput);
1978
1979                 
1980 //      // Maximul instant Power limit on the site
1981 //      ValueObject* powerMaxSite = new ValueObject();
1982 //      powerMaxSite->setQuantity(RESOURCE__POWER);
1983 //      powerMaxSite->setName("PMaxSite");
1984 //      powerMaxSite->setUnit(RESOURCE__KILOWATT);
1985 //      powerMaxSite->setValue(new Variant(40));
1986 //      powerMaxSiteInput->add("PMaxSite", powerMaxSite);
1987
1988 //      // chargeNeeds list
1989
1990 //      QList<Map*> needs;
1991         
1992 //      Map* need = new Map();
1993
1994 //      // Charge ID
1995 //      need->insert("ChargeID", new Variant(145));
1996
1997 //      ValueObject* energy = new ValueObject();
1998 //      energy->setQuantity(RESOURCE__ELECTRICENERGY);
1999 //      energy->setUnit(RESOURCE__KILOWATTHOUR);
2000 //      energy->setValue(new Variant(600));
2001 //      need->insert("Energy", energy);
2002
2003 //      ValueObject* powerMin = new ValueObject();
2004 //      powerMin->setQuantity(RESOURCE__POWER);
2005 //      powerMin->setUnit(RESOURCE__KILOWATT);
2006 //      powerMin->setValue(new Variant(30));
2007 //      need->insert("PowerMin", powerMin);
2008
2009 //      ValueObject* powerMax = new ValueObject();
2010 //      powerMax->setQuantity(RESOURCE__POWER);
2011 //      powerMax->setUnit(RESOURCE__KILOWATT);
2012 //      powerMax->setValue(new Variant(1000));
2013 //      need->insert("PowerMax", powerMax);
2014
2015 //      // Schedule
2016 //      QDateTime start = QDateTime::currentDateTime();
2017 //      QDateTime end = start.addSecs(3600);
2018         
2019 //      TemporalContext* tco = new TemporalContext();
2020 //      tco->setStart(start);
2021 //      tco->setEnd(end);
2022 //      need->insert("Schedule", tco);
2023
2024 //      need->insert("Priority", new Variant(1));
2025 //      need->insert("Type", new Variant("Delayed"));
2026
2027 //      needs.append(need);
2028
2029 //      needsInput->add("Needs", needs);
2030
2031 //      QString payload = Tools::toString(request, SERIALIZATION__TURTLE);
2032 //      request->destroyCascade();
2033         
2034 //      QUrl serviceUrl = QUrl("http://seas.asema.com:2683/seas/v1.0e1.0/access/");
2035
2036 //      QNetworkAccessManager *networkManager = new QNetworkAccessManager();
2037 //      QEventLoop postWaitLoop;
2038         
2039 //      QNetworkRequest nrequest(serviceUrl);
2040 //      nrequest.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE__TURTLE);
2041 //      nrequest.setRawHeader(QByteArray("X-SmartAPI-CallId"), QByteArray("1"));
2042 //      nrequest.setRawHeader(QByteArray("X-SmartAPI-Method"), QByteArray("fetchData"));
2043 //      nrequest.setRawHeader(QByteArray("Accept"), QByteArray(CONTENT_TYPE__TURTLE));
2044         
2045 //      QNetworkReply* reply = networkManager->post(nrequest, payload.toUtf8());
2046 //      QObject::connect( reply, SIGNAL(finished()), &postWaitLoop, SLOT(quit()));
2047 //      postWaitLoop.exec( QEventLoop::ExcludeUserInputEvents );
2048         
2049 //      QByteArray result = reply->readAll();
2050 //      reply->deleteLater();
2051 //      networkManager->deleteLater();
2052
2053         
2054 //      printf("---- CHARGE PLAN ----\n%s\n-------------\n", result.data());
2055         
2056 //      QVariantMap rm;
2057 //      QVariantList resultList;
2058 //      Obj* o = Tools::fromStringAsObj(QString(result));
2059 //      if (Response* r = dynamic_cast<Response*>(o)) {
2060 //              if (r->hasActivity()) {
2061 //                      Activity* a = r->getActivities().at(0);
2062 //                      if (a->hasOutput()) {
2063 //                              Output* ou = a->getOutputs().at(0);
2064 //                              QList<GraphItem*> plans = ou->getAll("ChargingPlan")->toQList();
2065 //                              for (int pi = 0; pi < plans.length(); pi++) {
2066 //                                      Variant* plan = (Variant*)plans.at(pi);
2067 //                                      Map* planMap = (Map*)plan->asObj();
2068 //                                      Variant* orders =  planMap->get("Orders");
2069 //                                      QList<Variant*> orderList = orders->asList();
2070 //                                      for (int oi = 0; oi < orderList.length(); oi++) {
2071 //                                              QVariantMap plan;
2072 //                                              Variant* order = orderList.at(oi);
2073 //                                              Map* orderMap = (Map*)order->asObj();
2074 //                                              ValueObject* power = (ValueObject*)orderMap->get("Power")->asObj();
2075 //                                              TemporalContext* tco = (TemporalContext*)orderMap->get(NS__SMARTAPI + "temporalContext")->asObj();
2076                                         
2077 //                                              plan.insert("start", tco->getStart());
2078 //                                              plan.insert("end", tco->getEnd());
2079 //                                              plan.insert("power", power->getValue()->getValue());
2080 //                                              plan.insert("power_unit", power->getUnit());
2081 //                                              resultList << plan;
2082 //                                      }
2083 //                              }
2084 //                      }
2085 //              }
2086 //      } else {
2087 //              return false;
2088 //      }
2089 //      o->destroyCascade();
2090 //      qDebug() << resultList;
2091         
2092 //      return true;
2093 //}
2094
2095 bool availabilityTest()
2096 {
2097         // Temporal availability
2098         Availability* a1 = new Availability();
2099         TemporalContext* tcx = new TemporalContext();
2100         tcx->setStart(QDateTime::currentDateTime());
2101         tcx->setEnd(QDateTime::currentDateTime());
2102         tcx->setDuring(RESOURCE__WEEKDAY);
2103         a1->setTemporalContext(tcx);
2104         printf("%s\n", Tools::toString(a1, SERIALIZATION__TURTLE).toUtf8().constData());
2105         
2106         // Temporal availability
2107         Availability* a2 = new Availability();
2108         TemporalContext* tcx2 = new TemporalContext();
2109         tcx2->setStart(QDateTime::currentDateTime());
2110         tcx2->setEnd(QDateTime::currentDateTime());
2111         a2->setTemporalContext(tcx2);
2112         //printf("%s\n", Tools::toString(a2, SERIALIZATION__TURTLE).toUtf8().constData());
2113         
2114         // Property based availability (distance)
2115         Availability* a3 = new Availability();
2116         Ring* ring = new Ring();
2117         ring->setCoordinates(60.1, 24.1);
2118         ring->setMaxRadiusInKilometers(10);
2119         a3->setRing(ring);
2120         printf("%s\n", Tools::toString(a3, SERIALIZATION__TURTLE).toUtf8().constData());
2121         
2122         // Property based availability (address)
2123         Availability* a4 = new Availability();
2124         Address* addr = new Address();
2125         addr->setCountry("Finland");
2126         addr->setCity("Espoo");
2127         a4->setAddress(addr);
2128         printf("%s\n", Tools::toString(a4, SERIALIZATION__TURTLE).toUtf8().constData());
2129         
2130         // Property based availability (system state)
2131         Availability* a5 = new Availability();
2132         a5->setProperty(PROPERTY__SYSTEMSTATE);
2133         // FIXME: a5->addValue("away");
2134         // FIXME: a5->addValue("away long");
2135         printf("%s\n", Tools::toString(a5, SERIALIZATION__TURTLE).toUtf8().constData());
2136         
2137         // Property based availability (capacity)
2138         Availability* a6 = new Availability();
2139         a6->setProperty(PROPERTY__CAPACITY);
2140         a6->setIsControlledBy("http://acme.com/backend/CentityId");
2141         // system of interest / capacity id can be left out if there is only one capacity
2142         a6->setSystemOfInterestWithSameAs("http://acme.com/backend/CcapacityId");
2143         a6->setUnit(RESOURCE__PERCENT);
2144         a6->setMinimum(new Variant(40));
2145         printf("%s\n", Tools::toString(a6, SERIALIZATION__TURTLE).toUtf8().constData());
2146         
2147         // Property based availability (user)
2148         Availability* a7 = new Availability();
2149         a7->addPersonByUsername("seas");
2150         a7->addPersonByUsername("admin");
2151         printf("%s\n", Tools::toString(a7, SERIALIZATION__TURTLE).toUtf8().constData());
2152         
2153         // Property based availability (priority)
2154         Availability* a8 = new Availability();
2155         a8->setPriorityInPercents(70);
2156         printf("%s\n", Tools::toString(a8, SERIALIZATION__TURTLE).toUtf8().constData());
2157
2158         a1->destroyCascade();
2159         a2->destroyCascade();
2160         a3->destroyCascade();
2161         a4->destroyCascade();
2162         a5->destroyCascade();
2163         a6->destroyCascade();
2164         a7->destroyCascade();
2165         a8->destroyCascade();
2166
2167         return true;
2168 }
2169
2170 bool hugeDataTest()
2171 {
2172         qDebug() << "Not implemented yet";
2173         return false;
2174 }
2175
2176 bool keyServerTest()
2177 {
2178         QString content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
2179         QString keyId = "http://www.acme.com/services/abcd/";
2180         QString publicKeyServer = "http://127.0.0.1:11371";
2181         EVP_PKEY* downloadedKey = SmartAPICrypto::downloadPublicKey(keyId, publicKeyServer);
2182         EVP_PKEY* pubKey = getPemPublicKey("../../Java/SmartAPI/src/smartapi/tests/testkey_public.pem");
2183         EVP_PKEY* privKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2184
2185         QString signature = SmartAPICrypto::sign(privKey, content);
2186         qDebug() << "new signature" << signature;
2187         bool verified = SmartAPICrypto::verifySignature(signature, pubKey, content);
2188
2189         qDebug() << "Signature verification, key on disk " << (verified ? "successful" : "failed");
2190         if (!verified) {
2191                 return false;
2192         }
2193
2194         verified = SmartAPICrypto::verifySignature(signature, downloadedKey, content);
2195         qDebug() << "Signature verification, downloaded key " << (verified ? "successful" : "failed");
2196         
2197         EVP_PKEY_free(downloadedKey);
2198         EVP_PKEY_free(pubKey);
2199         EVP_PKEY_free(privKey);
2200         return verified;
2201 }
2202
2203 bool basicChecksumTest()
2204 {
2205         PhysicalEntity* bus1 = new PhysicalEntity("http://www.volvo.com/bus");
2206         bus1->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 5500));
2207         bus1->add(NS__SMARTAPI + "weight", new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 1000));
2208         bus1->add(NS__SMARTAPI + "maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 11));
2209
2210         PhysicalEntity* bus2 = new PhysicalEntity("http://www.volvo.com/bus");
2211         bus2->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 5500));
2212         bus2->add(NS__SMARTAPI + "maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 11));
2213         bus2->add(NS__SMARTAPI + "weight", new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 1000));
2214
2215         QString b1Check = bus1->generateChecksum();
2216         QString b2Check = bus2->generateChecksum();
2217         bus1->destroyCascade();
2218         bus2->destroyCascade();
2219         qDebug() << "Basic checksum test checksums:";
2220         qDebug() << "Item 1:" << b1Check;
2221         qDebug() << "Item 2:" << b2Check;
2222         return b1Check == b2Check;
2223 }
2224
2225 bool parsedChecksumTest()
2226 {
2227         PhysicalEntity* bus = new PhysicalEntity("http://www.volvo.com/bus");
2228
2229         bus->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 5500));
2230         bus->add(NS__SMARTAPI + "weight", new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 1000));
2231
2232         bus->add(NS__SMARTAPI + "maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 11));
2233
2234         QString serialized = Tools::toString(bus, SERIALIZATION__TURTLE);
2235         QString checksum = bus->generateChecksum();
2236
2237         printf("Object:\n%s\n", serialized.toUtf8().data());
2238         printf("Checksum: %s\n", checksum.toUtf8().data());
2239
2240         Obj* parsedObj = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
2241         QString newChecksum = parsedObj->generateChecksum();
2242         printf("Checksum from parsed: %s\n", newChecksum.toUtf8().data());
2243         bus->destroyCascade();
2244         parsedObj->destroyCascade();
2245         return newChecksum == checksum;
2246 }
2247
2248 bool crossChecksumTest()
2249 {
2250         Velocity* v1 = new Velocity();
2251         v1->setLinearVelocityX(new ValueObject(RESOURCE__LINEARVELOCITY, RESOURCE__KILOMETERPERHOUR, new Variant(30)));
2252         v1->setLinearVelocityY(new ValueObject(RESOURCE__LINEARVELOCITY, RESOURCE__KILOMETERPERHOUR, new Variant(100)));
2253
2254         QString v1checksum = v1->generateChecksum();
2255
2256                 // velocity with flipped values
2257         Velocity* v2 = new Velocity();
2258         v2->setLinearVelocityX(new ValueObject(RESOURCE__LINEARVELOCITY, RESOURCE__KILOMETERPERHOUR, new Variant(100)));
2259         v2->setLinearVelocityY(new ValueObject(RESOURCE__LINEARVELOCITY, RESOURCE__KILOMETERPERHOUR, new Variant(30)));
2260
2261         QString v2checksum = v2->generateChecksum();
2262
2263         qDebug() << "Test 1, Checksum v1: " << v1checksum;
2264         qDebug() << "Test 1, Checksum v2: " << v2checksum;
2265         v1->destroyCascade();
2266         v2->destroyCascade();
2267
2268         Device* d1 = new Device();
2269         d1->addValueObject(new ValueObject(NS__SMARTAPI + "InsideTemperature", RESOURCE__DEGREECELSIUS, new Variant(30)));
2270         d1->addValueObject(new ValueObject(NS__SMARTAPI + "OutsideTemperature", RESOURCE__DEGREECELSIUS, new Variant(100)));
2271
2272         QString d1checksum = d1->generateChecksum();
2273
2274         // device with flipped values
2275         Device* d2 = new Device();
2276         d2->addValueObject(new ValueObject(NS__SMARTAPI + "InsideTemperature", RESOURCE__DEGREECELSIUS, new Variant(100)));
2277         d2->addValueObject(new ValueObject(NS__SMARTAPI + "OutsideTemperature", RESOURCE__DEGREECELSIUS, new Variant(30)));
2278
2279         QString d2checksum = d2->generateChecksum();
2280         qDebug() << "Test 2, Checksum v1: " << d1checksum;
2281         qDebug() << "Test 2, Checksum v2: " << d2checksum;
2282         d1->destroyCascade();
2283         d2->destroyCascade();
2284
2285         return v1checksum != v2checksum && d1checksum != d2checksum;
2286 }
2287
2288 bool simpleHashTest()
2289 {
2290         QString r = "Simple hash input";
2291         QString responseHash = SmartAPICrypto::createEncodedMessageDigest(r);
2292         qDebug() << "Hash for the text: " << responseHash;
2293         return true;
2294 }
2295
2296 bool symmetricEncryptionTest()
2297 {
2298         QByteArray key = SmartAPICrypto::generateSymmetricKey();
2299         QString content = "Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
2300
2301         QString encrypted = SmartAPICrypto::symmetricEncrypt((unsigned char*)key.data(), content);
2302         QString decrypted = SmartAPICrypto::symmetricDecrypt((unsigned char*)key.data(), encrypted);
2303         qDebug() << "Symmetric - decrypted" << decrypted;
2304         return decrypted == content;
2305 }
2306
2307 bool asymmetricEncryptionTest()
2308 {
2309         QString content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
2310
2311         EVP_PKEY* privKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2312         EVP_PKEY* pubKey = getPemPublicKey("../../Java/SmartAPI/src/smartapi/tests/testkey_public.pem");
2313         QByteArray symKeyHolder;
2314
2315         QString encrypted = SmartAPICrypto::asymmetricEncrypt(pubKey, content, &symKeyHolder);
2316         QString decrypted = SmartAPICrypto::asymmetricDecrypt(privKey, encrypted, &symKeyHolder);
2317         qDebug() << "Asymmetric - decrypted" << decrypted;
2318         EVP_PKEY_free(privKey);
2319         EVP_PKEY_free(pubKey);
2320         return decrypted == content;
2321 }
2322
2323 bool simpleSignatureTest()
2324 {
2325         QString content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
2326         EVP_PKEY* privKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2327         qDebug() << "privKey =" << privKey;
2328
2329         QString signature = SmartAPICrypto::sign(privKey, content);
2330         qDebug() << "New signature" << signature;
2331         EVP_PKEY_free(privKey);
2332         return true;
2333 }
2334
2335 bool hashVerificationTest()
2336 {
2337         QString r = "Some digest input";
2338         QString digest = SmartAPICrypto::createEncodedMessageDigest(r);
2339         qDebug() << "Generated digest:" << digest;
2340         bool match = SmartAPICrypto::verifyEncodedMessageDigest(digest, r);
2341         qDebug() << "Digest match: " << match;
2342         return match;
2343 }
2344
2345 bool keyGenerationTest()
2346 {
2347         QString myId = "http://www.acme.com/services/abcd/1";
2348         QString publicKeyServer = "http://127.0.0.1:11371";
2349         SmartAPICrypto::createAndSaveKeyPair(myId, "/tmp/testkey_private.pem", publicKeyServer, "test", "test");
2350         return true;
2351 }
2352
2353 bool keyRevokationTest()
2354 {
2355         QString myId = "http://www.acme.com/services/abcd/1";
2356         QString publicKeyServer = "http://127.0.0.1:11371";
2357         return SmartAPICrypto::revokePublicKey(myId, publicKeyServer, "test", "test");
2358 }
2359
2360 bool keyUploadTest()
2361 {
2362         QString myId = "http://www.acme.com/services/abcd/2";
2363         QString publicKeyServer = "http://127.0.0.1:11371";
2364         QString pub, priv;
2365         Tools::createCryptoKeys(&priv, &pub);
2366         qDebug() << priv;
2367         qDebug() << pub;
2368         Tools::uploadPublicKey(pub, myId, publicKeyServer, "test", "test");
2369         Tools::revokePublicKey(myId, publicKeyServer, "test", "test");
2370         qDebug() << "Key uploaded and revoked";
2371         return true;
2372 }
2373
2374 bool keyEncryptionTest()
2375 {
2376         EVP_PKEY* pubKey = getPemPublicKey("../../Common/Java/SmartAPI/src/smartapi/tests/testkey_public.pem");
2377         EVP_PKEY* privKey = getPemPrivateKey("../../Common/Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2378
2379         QByteArray key = SmartAPICrypto::generateSymmetricKey();
2380         QString encodedKey = SmartAPICrypto::encryptAndEncodeKey(pubKey, key);
2381         QByteArray decodedKey = SmartAPICrypto::decryptAndDecodeKey(privKey, encodedKey);
2382         qDebug() << "original key:" << key.toBase64();
2383         qDebug() << "encrypted key:" << encodedKey;
2384         qDebug() << "decrypted key:" << decodedKey.toBase64();
2385         
2386         EVP_PKEY_free(privKey);
2387         EVP_PKEY_free(pubKey);
2388         return true;
2389 }
2390
2391 bool crossSystemDecryptionTest()
2392 {
2393         QString encrypted = "GUsjdd81ugIzil2isjteOQ==tPkIcebSOYdsS+o6fecuk4MSsA6P++HBv9/7MDuruGvCQvBAAAuMZb5mqyqg/oIjGwAavhi7RHFMG8OtDabbRywW8cWEmt6KKj96fAnozvzuvSbduguOtIiuzgwPVmxURPzHhoKM08bvoQDzhXsfA5YY5eBNDq3SdUHSQIl7rWeyKATjUXOZhlWNwjwkcztF4UCj+g2YcoFRtlaxKFxON2LsGNcNrQght/SBWfX00qys9uXuii9GgMnXjMuP/BlRMC3AZms3BBVAgJD9MvdkBAdU9jN6hpdC0WkXc1IPIumdk5W8jg7mIg9HCzs/g4phGQG5CbHDuSLcns95O5emrNls9K9n0olI7SWfeFwNRimuOUqOk5fO26I7/ELu1jnvVppFzt4MBr13E67CR7PvnQ==";
2394         QString key = "adUiExOZ/L05Hds1r4W2vg==";
2395         QByteArray decodedKey = SmartAPICrypto::decodeBase64EncodedKey(key);
2396
2397         QString decrypted = SmartAPICrypto::symmetricDecrypt((unsigned char*)decodedKey.data(), encrypted);
2398         printf("%s\n", decrypted.toUtf8().data());
2399         return decrypted.startsWith("The") && decrypted.endsWith(". ");
2400 }
2401
2402 bool solarPanelClientTest()
2403 {
2404         QNetworkAccessManager *networkManager = new QNetworkAccessManager();
2405         OAuthAgent* oauthAgent = new OAuthAgent(networkManager);
2406         EVP_PKEY* myPrivateKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2407         if (!myPrivateKey) {
2408                 qDebug() << "Cannot load private key. Check the path.";
2409                 return false;
2410         }
2411
2412         QString myIdentity = "http:///www.client.com/seas/Cclient";
2413         QString clientSecret = "asdf";
2414         //QString panelGatewayAddress = "http://development.asema.com:2888/solarpanelgateway/";
2415         //QString panelGatewayAddress = "http://127.0.0.1:2888/solarpanelgateway/";
2416         //QString securityBrokerAddress = "http://development.asema.com:11372/oauth2/";
2417         //QString securityBrokerAddress = "http://127.0.0.1:2872/oauth2/";
2418         QString panelGatewayAddress = "http://127.0.0.1:8080/solarpanelgateway/";
2419         QString securityBrokerAddress = "http://127.0.0.1:11372/oauth2/";
2420
2421         QString dataEndpoint = panelGatewayAddress + "seas/v1.0e1.0/access/";
2422         QString authorizeEndpoint = panelGatewayAddress + "authorize";
2423         QString tokenEndpoint = securityBrokerAddress + "token";
2424         QString clientId = "SolarPanelTestApp";
2425         QString authorizationCode;
2426         QString authToken;
2427         QStringList panelIds;
2428         panelIds << "http://seas.asema.com/dataservice/solar/Paris/panels/1";
2429         panelIds << "http://seas.asema.com/dataservice/solar/Paris/panels/2";
2430
2431         // the following is basically the Java implementation of SolarPanelClient.requestDataFromGateway() translated to C++
2432         QMap<QString, QList<QMap<QDateTime, double> > > results;
2433         QListIterator<QString> pi(panelIds);
2434         while (pi.hasNext()) {
2435                 QString panelId = pi.next();
2436                 Activity* requestActivity = NULL;
2437                 // create request activity
2438                 Activity* requestActivityTemplate = new Activity();
2439                 Input* i = new Input();
2440                 requestActivityTemplate->addInput(i);
2441                 i->setCategory(RESOURCE__SOLARENERGYPRODUCTION);
2442                 i->setSystemOfInterestWithSameAs(panelId);
2443                 ValueObject* vo = new ValueObject();
2444                 vo->setQuantity(RESOURCE__ENERGYANDWORK);
2445                 vo->setUnit(RESOURCE__MEGAWATTHOUR);
2446                 i->addOutputValue(vo);
2447
2448                 // create start and end timestamps
2449                 // start = 1 day ago
2450                 // end = now
2451                 QDateTime now = QDateTime::currentDateTime();
2452                 QDateTime start = now.addDays(-1);
2453                 i->setTemporalContext(start, now);
2454
2455                 bool activityPaid = false;
2456                 while (true) {
2457                         // request data
2458                         Request* r = RequestFactory::create(myIdentity);
2459                         r->setMethod(QUrl(RESOURCE__READ)); // FIXME is this right?
2460
2461                         if (requestActivity != NULL)
2462                                 r->addActivity(new Activity(requestActivity));
2463                         else
2464                                 r->addActivity(new Activity(requestActivityTemplate));
2465
2466                         HttpMessage* httpMessage = Tools::serializeRequest(r);
2467                         r->destroyCascade();
2468
2469                         QNetworkReply* reply = httpMessage->post(networkManager, dataEndpoint, "Request", clientId.toLocal8Bit(), QMap<QString, QString>(), CONTENT_TYPE__TURTLE, CONTENT_TYPE__TURTLE, authToken);
2470                         QEventLoop loop;
2471                         QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
2472                         loop.exec();
2473
2474                         QByteArray responseString = reply->readAll();
2475                         int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
2476                         if (httpStatus != 200) {
2477                                 // not authenticated
2478                                 qDebug() << "not authenticated. authToken is" << authToken;
2479                                 if (authToken.isEmpty()) {
2480                                         authorizationCode = oauthAgent->oauth2AuthorizeApplication(authorizeEndpoint, clientId, "api");
2481                                         authToken = oauthAgent->oauth2AuthenticateUser(tokenEndpoint, authorizationCode, clientId, clientSecret, "");
2482                                         qDebug() << "Got authorization to access the server with token " << authToken;
2483                                         continue;
2484                                 } else {
2485                                         qDebug() << "Already authenticated but server still requests authentication. Aborting.";
2486                                         return false;
2487                                 }
2488                         }
2489                         QByteArray contentType = reply->header(QNetworkRequest::ContentTypeHeader).toByteArray();
2490                         reply->deleteLater();
2491
2492                         //qDebug() << "Response from panel gateway:----- ";
2493                         //printf("%s\n", responseString.constData());
2494                         //qDebug() << "------ContentType------";
2495                         //qDebug() << contentType;
2496
2497                         Response* response = Tools::parseResponse(responseString, contentType);
2498
2499                         if (response == NULL) {
2500                                 qDebug() << "Could not parse the data.";
2501                                 //continue;
2502                                 return false;
2503                         }
2504
2505                         if (response->hasActivity()) {
2506                                 Activity* respActivity = response->getActivities().first();
2507                                 if (respActivity->hasOutput()) {
2508                                         // Output received OK
2509                                         qDebug() << "Got data for panel OK!";
2510                                 } else if (respActivity->hasOffering()) {
2511                                         // Output not received, a payment is requested
2512                                         if (!activityPaid) {
2513                                                 requestActivity = new Activity(respActivity);
2514
2515                                                 Offering* offering = requestActivity->getOfferings().first();
2516                                                 QListIterator<PriceSpecification*> psi(offering->getPriceSpecification().toQList());
2517                                                 while (psi.hasNext()) {
2518                                                         PriceSpecification* ps = psi.next();
2519                                                         qDebug() << "Received an offer to pay for the data request, price is" << ps->getCurrencyValue() << ps->getCurrency();
2520                                                         qDebug() << "Accepting it.";
2521                                                 }
2522
2523                                                 /*
2524                         printf("~~~ RESP ACTIVITY ~~~\n\n%s\n\n", Tools::toString(respActivity, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2525                         printf("~~~ REQUEST ACTIVITY ~~~\n\n%s\n\n", Tools::toString(requestActivity, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2526                         return;
2527                         */
2528
2529                                                 offering->sign(myPrivateKey);
2530                                                 activityPaid = true;
2531                                                 continue;
2532                                         } else {
2533                                                 qDebug() << "Already signed the offering but server still requests payment. Aborting.";
2534                                                 return false;
2535                                         }
2536                                 }
2537                         } else {
2538                                 qDebug() << "response has no activity!";
2539                                 return false;
2540                         }
2541
2542                         if (response == NULL) {
2543                                 qDebug() << "Response is null. Exiting.";
2544                                 return false;
2545                         }
2546
2547                         qDebug() << "--- Got response from panel gateway";
2548                         qDebug() << Tools::toString(response, SERIALIZATION__TURTLE);
2549
2550                         Activity* responseActivity = response->getActivities().first();
2551                         if (responseActivity->hasOutput()) {
2552                                 QListIterator<Output*> oi(responseActivity->getOutputs().toQList());
2553                                 while (oi.hasNext()) {
2554                                         Output* out = oi.next();
2555                                         if (out->isEncrypted()) {
2556                                                 qDebug() << "encrypted content:";
2557                                                 qDebug() << out->getStringRepresentation();
2558
2559                                                 bool result = true;
2560                                                 if (out->getEncryptionKeyType() == RESOURCE__PUBLICKEY) {
2561                                                         result = out->decrypt(myPrivateKey);
2562                                                 } else if (out->getEncryptionKeyType() == RESOURCE__NOTARIZEDSESSIONKEY) {
2563                                                         QString signature = SmartAPICrypto::sign(myPrivateKey, out->getHashCode());
2564                                                         qDebug() << "This is a notarized message, key at" << out->getNotary();
2565                                                         TransactionAgent agent;
2566                                                         QString keyString = agent.fetchKeyFromNotary(myIdentity,
2567                                                                         out->getIdentifierUri(),
2568                                                                         out->getHashCode(),
2569                                                                         signature,
2570                                                                         out->getNotary(),
2571                                                                         myPrivateKey);
2572                                                         qDebug() << "The keystring is" << keyString;
2573                                                         QByteArray secretKey = SmartAPICrypto::decryptAndDecodeKey(myPrivateKey, keyString);
2574                                                         result = out->decrypt(secretKey);
2575                                                         qDebug() << "decrypted output------------------";
2576                                                         qDebug() << Tools::toString(out, SERIALIZATION__TURTLE);
2577                                                 }
2578
2579                                                 if (!result) {
2580                                                         qDebug() << "decryption failed!";
2581                                                         return false;
2582                                                 } else {
2583                                                         qDebug() << "decrypted successfully!!!";
2584                                                 }
2585                                         }
2586
2587                                         QList<QMap<QDateTime, double> > timeSeriesList;
2588
2589                                         // Fill timeseries from the output here
2590                                         if (out->hasTimeSerie()) {
2591                                                 qDebug() << "Filling the timeseries data";
2592                                                 TimeSeries* ts = out->getTimeSeries().first();
2593                                                 QListIterator<GraphItem*> tsi(ts->getList().toQList());
2594                                                 while (tsi.hasNext()) {
2595                                                         Evaluation* tse = dynamic_cast<Evaluation*>(tsi.next());
2596                                                         qDebug() << "Data for" << tse->getInstant();
2597                                                 }
2598                                         }
2599
2600                                         results.insert(panelId, timeSeriesList);
2601                                 }
2602
2603                                 // request completed, so exit the forever loop
2604                                 break;
2605                         }
2606                         delete response;
2607                 }
2608                 delete requestActivityTemplate;
2609         }
2610
2611         qDebug() << "test finished!";
2612         return true;
2613 }
2614
2615 bool currencyConversionTest()
2616 {
2617         QNetworkAccessManager* networkManager = new QNetworkAccessManager();
2618         UnitConverter u(networkManager);
2619
2620         QEventLoop waitLoop;
2621         QObject::connect(&u, SIGNAL(ready()), &waitLoop, SLOT(quit()));
2622         u.load();
2623         waitLoop.exec( QEventLoop::ExcludeUserInputEvents );
2624
2625
2626         ValueObject* testA = new ValueObject(RESOURCE__POWER, NS__UNIT + "Watt", 2.2);
2627         ValueObject* testB = new ValueObject(RESOURCE__CURRENCY, RESOURCE__EURO, 2.2);
2628         testB->setSecondaryQuantity(RESOURCE__ENERGYANDWORK);
2629         testB->setSecondaryUnit(RESOURCE__KILOWATTHOUR);
2630
2631         ValueObject* testC = new ValueObject(RESOURCE__CURRENCY, RESOURCE__EURO, 10);
2632         ValueObject* testD = new ValueObject(RESOURCE__TEMPERATURE, NS__UNIT + "Kelvin", 283.15);
2633         ValueObject* testE = new ValueObject(RESOURCE__TEMPERATURE, NS__UNIT + "DegreeCelsius", 10);
2634
2635         testA->turtlePrint();
2636         u.convert(testA, NS__UNIT + "Kilowatt");
2637         testA->turtlePrint();
2638
2639         testB->turtlePrint();
2640         u.convert(testB, RESOURCE__POUNDSTERLING, RESOURCE__MEGAWATTHOUR);
2641         testB->turtlePrint();
2642
2643         testC->turtlePrint();
2644         u.convert(testC, RESOURCE__POUNDSTERLING);
2645         testC->turtlePrint();
2646
2647         testD->turtlePrint();
2648         u.convert(testD, NS__UNIT + "DegreeFahrenheit");
2649         testD->turtlePrint();
2650
2651         testE->turtlePrint();
2652         u.convert(testE, NS__UNIT + "DegreeFahrenheit");
2653         testE->turtlePrint();
2654
2655         testA->destroyCascade();
2656         testB->destroyCascade();
2657         testC->destroyCascade();
2658         testD->destroyCascade();
2659         testE->destroyCascade();
2660
2661         return true;
2662 }
2663
2664
2665 bool registrationTest()
2666 {
2667         RegisterDeregisterTest* test = new RegisterDeregisterTest();
2668         test->doTest();
2669 }
2670
2671 bool registrationSearchTest()
2672 {
2673         RegisterSearchTest* test = new RegisterSearchTest();
2674         test->doTest();
2675 }
2676
2677 bool multiParseTest()
2678 {
2679         Request* request = RequestFactory::create("http://test.iot.com/test");
2680         request->setMethod(NS__SMARTAPI + "Read");
2681
2682         Activity* activity = new Activity();
2683         Input* input = new Input();
2684
2685         SystemOfInterest* sys_of_interest = new SystemOfInterest();
2686         sys_of_interest->setType(NS__SMARTAPI + "Test");
2687         input->setSystemOfInterest(sys_of_interest);
2688
2689         Coordinates* coordinates = new Coordinates(40.000, 2.000);
2690         input->add("search_coordinates", new Variant(coordinates));
2691
2692         activity->addInput(input);
2693         request->addActivity(activity);
2694
2695         QString payload = Tools::toString(request, SERIALIZATION__TURTLE);
2696         Request* req1 = (Request*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
2697         Request* req2 = (Request*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
2698         Request* req3 = (Request*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
2699         Request* req4 = (Request*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
2700
2701         req1->destroyCascade();
2702         request->destroyCascade();
2703         req4->destroyCascade();
2704         req2->destroyCascade();
2705         req3->destroyCascade();
2706
2707         return true;
2708 }
2709
2710
2711 //bool sharingTest()
2712 //{
2713 //    // generate key pairs
2714 //    EVP_PKEY* iotc1PrivateKey;
2715 //    EVP_PKEY* iotc1PublicKey;
2716 //    EVP_PKEY* iotc2PrivateKey;
2717 //    EVP_PKEY* iotc2PublicKey;
2718 //    SmartAPICrypto::generateKeyPair(&iotc1PrivateKey, &iotc1PublicKey);
2719 //    SmartAPICrypto::generateKeyPair(&iotc2PrivateKey, &iotc2PublicKey);
2720
2721 //    QString iotc1Identity = "http://acme.com/iotc-1/C756fdg76dgfh4376dshg";
2722
2723 //    // (1) IoTC 1 registers with RegistrationAgent
2724 //    QString powerIdentifier = "/Cpower";
2725 //    QString volumeIdentifier = "/Cvolume";
2726 //    QString controlOfferingIdentifier ="/Ccontroloffering";
2727 //    QString dataOfferingIdentifier = "/dataCoffering";
2728
2729 //    // create boiler
2730 //    Device* boiler = new Device(iotc1Identity);
2731 //    boiler->addType(RESOURCE__WATERBOILER);
2732
2733 //    // info about energy consumption (power capacity)
2734 //    Capacity* power = new Capacity(iotc1Identity + powerIdentifier);
2735 //    power->setSystemOfInterestWithType(RESOURCE__RESISTOR);
2736 //    power->setQuantity(RESOURCE__POWER);
2737 //    power->setUnit(RESOURCE__KILOWATT);
2738 //    power->setMaximum(new Variant(6));
2739 //    power->setStep(new Variant(3));
2740 //    power->setValue(new Variant(6));
2741 //    boiler->addCapacity(power);
2742
2743 //    // info about water volume (volume capacity)
2744 //    Capacity* volume = new Capacity(iotc1Identity + volumeIdentifier);
2745 //    volume->setSystemOfInterestWithType(RESOURCE__WATERTANK);
2746 //    volume->setQuantity(RESOURCE__VOLUME);
2747 //    volume->setUnit(RESOURCE__LITER);
2748 //    volume->setMaximum(new Variant(500));
2749 //    volume->setValue(new Variant(500));
2750 //    boiler->addCapacity(volume);
2751
2752 //    // price for controlling on/off of this device
2753 //    Offering* controlOffering = new Offering(iotc1Identity + controlOfferingIdentifier);
2754 //    boiler->addOffering(controlOffering);
2755 //    PriceSpecification* controlPriceSpecification = new UnitPriceSpecification();
2756 //    controlPriceSpecification->setGrName("Price to control this boiler");
2757 //    controlPriceSpecification->setGrDescription("The amount in Euro to be paid for being able to control the two 3 kW resistors of this boiler for one hour.");
2758 //    controlPriceSpecification->setCurrency("EUR");
2759 //    controlPriceSpecification->setCurrencyValue(1.5);
2760 //    controlOffering->addPriceSpecification(controlPriceSpecification);
2761 //    // offer item is a one hour subscription for controlling
2762 //    SomeItems* controlItems = new SomeItems(RESOURCE__SERVICESUBSCRIPTION, "Service subscription", "Right to control this device for one hour.", NULL);
2763 //    controlItems->setDuration(0, 0, 0, 1, 0, 0);
2764 //    controlItems->setMethod(RESOURCE__WRITE);
2765 //    controlOffering->addIncludes(controlItems);
2766
2767 //    // price for subscribing to receive data values of this device
2768 //    Offering* readOffering = new Offering(iotc1Identity + dataOfferingIdentifier);
2769 //    boiler->addOffering(readOffering);
2770 //    PriceSpecification* readPriceSpecification = new UnitPriceSpecification();
2771 //    readPriceSpecification->setGrName("Price to subscribe to receive real-time values");
2772 //    readPriceSpecification->setGrDescription("The amount in Euro to be paid for being able to receive real-time values for power and volume of this boiler for one day.");
2773 //    readPriceSpecification->setCurrency("EUR");
2774 //    readPriceSpecification->setCurrencyValue(0.05);
2775 //    readOffering->addPriceSpecification(readPriceSpecification);
2776 //    // offer item is a one day subscription for reading
2777 //    SomeItems* readItems = new SomeItems(RESOURCE__SERVICESUBSCRIPTION, "Service subscription", "Right to receive data values of this device for one day", NULL);
2778 //    readItems->setDuration(0, 0, 1, 0, 0, 0);
2779 //    readItems->setMethod(RESOURCE__SUBSCRIBE);
2780 //    readOffering->addIncludes(readItems);
2781
2782 //    // activity for subscribing to follow values of this entity
2783 //    Activity* subsActivity = new Activity();
2784 //    subsActivity->setMethod(RESOURCE__SUBSCRIBE);
2785 //    boiler->addCapability(subsActivity);
2786
2787 //    // input for defining requested capacities
2788 //    Input* subsInput = new Input();
2789 //    subsActivity->addInput(subsInput);
2790 //    subsInput->addRequiredPropertyDescription(1, RESOURCE__SYSTEMOFINTEREST, PROPERTY__SYSTEMOFINTEREST);
2791 //    SystemOfInterest* subsSoi = new SystemOfInterest();
2792 //    subsInput->setSystemOfInterest(subsSoi);
2793 //    QStringList subsSoiDataRanges;
2794 //    subsSoiDataRanges << iotc1Identity + powerIdentifier << iotc1Identity + volumeIdentifier;
2795 //    subsSoi->addRequiredPropertyDescription(1, 2, subsSoiDataRanges, PROPERTY__SAMEAS);
2796 //    subsInput->addOptionalPropertyDescription(1, RESOURCE__RDFS_RESOURCE, PROPERTY__PUBLICKEYSERVER);
2797 //    InterfaceAddress* subsInInterface = new InterfaceAddress();
2798 //    subsInput->addInterface(subsInInterface);
2799 //    subsInput->addRequiredPropertyDescription(1, RESOURCE__INTERFACEADDRESS, PROPERTY__INTERFACE);
2800
2801 //    // output to define output and its mqtt interface
2802 //    Output* subsOutput = new Output(Output::TYPE_REFERENCE);
2803 //    subsActivity->addOutput(subsOutput);
2804 //    subsOutput->addRequiredPropertyDescription(1, RESOURCE__INTERFACEADDRESS, PROPERTY__INTERFACE);
2805 //    InterfaceAddress* subsOutInterface = new InterfaceAddress();
2806 //    subsOutInterface->addContentType(CONTENT_TYPE__TURTLE);
2807 //    subsOutInterface->addRequiredPropertyDescription(1, DATATYPE__STRING, PROPERTY__HOST);
2808 //    subsOutInterface->addRequiredPropertyDescription(1, DATATYPE__INT, PROPERTY__PORT);
2809 //    subsOutInterface->addRequiredPropertyDescription(1, DATATYPE__STRING, PROPERTY__SCHEME);
2810 //    subsOutInterface->addRequiredPropertyDescription(1, DATATYPE__STRING, PROPERTY__TOPIC);
2811 //    subsOutput->addInterface(subsOutInterface);
2812 //    subsOutput->addRequiredPropertyDescription(1, RESOURCE__ENTITY, PROPERTY__ENTITY);
2813 //    Entity* subsOutEntity = new Entity();
2814 //    subsOutEntity->addRequiredPropertyDescription(1, 2, RESOURCE__CAPACITY, PROPERTY__CAPACITY);
2815
2816 //    // interface for making subscription
2817 //    InterfaceAddress* iData = new InterfaceAddress();
2818 //    subsActivity->addInterface(iData);
2819 //    iData->addContentType(CONTENT_TYPE__TURTLE);
2820 //    iData->setHost("acme.com");
2821 //    iData->setPath("/data");
2822 //    iData->setPort(80);
2823 //    iData->setScheme("http");
2824
2825 //    // interface for mqtt notifications
2826 //    InterfaceAddress* iMqtt = new InterfaceAddress();
2827 //    subsActivity->addInterface(iMqtt);
2828 //    iMqtt->addContentType(CONTENT_TYPE__TURTLE);
2829 //    iMqtt->setHost("seas.asema.com");
2830 //    iMqtt->setPort(1883);
2831 //    iMqtt->setScheme("mqtt");
2832 //    QStringList iMqttTopic;
2833 //    iMqttTopic << iotc1Identity;
2834 //    iMqttTopic << RESOURCE__DEVICE;
2835 //    iMqtt->setTopic(iMqttTopic);
2836
2837 //    // interface for websocket notifications
2838 //    InterfaceAddress* iWS = new InterfaceAddress();
2839 //    subsActivity->addInterface(iWS);
2840 //    iWS->addContentType(CONTENT_TYPE__TURTLE);
2841 //    iWS->setHost("seas.asema.com");
2842 //    iWS->setPort(80);
2843 //    iWS->setScheme("ws");
2844
2845 //    // activity for controlling this device
2846 //    Activity* writeActivity = new Activity();
2847 //    writeActivity->setMethod(RESOURCE__WRITE);
2848 //    boiler->addCapability(writeActivity);
2849
2850 //    // input for defining target value(s)
2851 //    Input* writeInput = new Input();
2852 //    writeActivity->addInput(writeInput);
2853 //    writeInput->addRequiredPropertyDescription(1, RESOURCE__SYSTEMOFINTEREST, PROPERTY__SYSTEMOFINTEREST);
2854 //    SystemOfInterest* writeSoi = new SystemOfInterest();
2855 //    writeInput->setSystemOfInterest(writeSoi);
2856 //    QStringList writeSoiDataRanges;
2857 //    writeSoiDataRanges << iotc1Identity + powerIdentifier << iotc1Identity + volumeIdentifier;
2858 //    writeSoi->addRequiredPropertyDescription(1, writeSoiDataRanges, PROPERTY__SAMEAS);
2859 //    writeInput->addRequiredPropertyDescription(1, RESOURCE__LITERAL, PROPERTY__RDF_VALUE);
2860
2861 //    // output containing current values
2862 //    Output* writeOutput = new Output();
2863 //    writeActivity->addOutput(writeOutput);
2864 //    writeOutput->addRequiredPropertyDescription(1, RESOURCE__ENTITY, PROPERTY__ENTITY);
2865
2866 //    // interface for control commands (same as making subscriptions)
2867 //    writeActivity->addInterface(iData);
2868
2869 //    // availability of the boiler (7 days from now)
2870 //    Availability* availability1 = new Availability();
2871 //    QDateTime now = QDateTime::currentDateTime();
2872 //    availability1->setTemporalContext(now, now.addDays(7));
2873
2874 //    // debug print registration description
2875 //    qDebug() << "(1) Device registration:";
2876 //    printf("%s\n", Tools::toString(boiler, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2877
2878 //    // registrate boiler description
2879 //    RegistrationAgent* registrationAgent = new RegistrationAgent(iotc1Identity + "/registrator"); // FIXME this /registrator suffix is needed because of a serialization bug that Hannu is working on
2880 //    //registrationAgent->addEntity(boiler);
2881 //    QEventLoop loop;
2882 //    QObject::connect(registrationAgent, SIGNAL(registrationSucceeded(int)), &loop, SLOT(quit()));
2883 //    if (!registrationAgent->makeRegistration(boiler)) {
2884 //        qCritical() << "RegistrationAgent::makeRegistration failed!";
2885 //        return false;
2886 //    }
2887 //    qDebug() << "waiting for registrationSucceeded signal...";
2888 //    loop.exec();
2889 //    qDebug() << "Registration made.";
2890
2891 //    // (2) IoTC 1 shares availability with SharingAgent
2892 //    qDebug() << "(2) Share availability";
2893 //    Availability* availability2 = new Availability();
2894 //    now = QDateTime::currentDateTime();
2895 //    availability2->addAvailability(now, now.addDays(14));
2896
2897 //    qDebug() << "Shared availability:";
2898 //    printf("%s\n", Tools::toString(availability2, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2899
2900 //    // share with defined availability
2901 //    SharingAgent* sharingAgent = new SharingAgent(iotc1Identity + "/registrator");
2902 //    if (sharingAgent->share(iotc1Identity, availability2)) {
2903 //        qDebug() << "Availability successfully added.";
2904 //    } else {
2905 //        qCritical() << "Failed to add availability!";
2906 //        return false;
2907 //    }
2908
2909 //    // (3) IoTC2 searches for available devices with SharingAgent
2910 //    // search for available devices with power capacity
2911 //    qDebug() << "(3) Search for available devices with power capacity";
2912 //    Entity* entity = new Device();
2913 //    Capacity* capacity = new Capacity();
2914 //    capacity->setQuantity(RESOURCE__POWER);
2915 //    entity->addCapacity(capacity);
2916
2917 //    // ...that are available from now on for at least 1 day...
2918 //    Availability* av = new Availability();
2919 //    QDateTime currentDateTime = QDateTime::currentDateTime();
2920 //    av->setTemporalContext(currentDateTime, currentDateTime.addDays(1));
2921
2922 //    // ...with maximum price of 0.05 euros per day
2923 //    Offering* offer = new Offering();
2924 //    PriceSpecification* ps = new UnitPriceSpecification();
2925 //    ps->setCurrency("EUR");
2926 //    ps->setCurrencyValue(0.05);
2927 //    offer->addPriceSpecification(ps);
2928 //    SomeItems* si = new SomeItems(RESOURCE__SERVICESUBSCRIPTION, QString(), QString(), QString());
2929 //    si->setDuration(0, 0, 1, 0, 0, 0);
2930 //    offer->addIncludes(si);
2931
2932 //    // debug print offering and availability search parameter objects
2933 //    printf("Search availability parameter:\n%s\n", Tools::toString(av, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2934 //    printf("Search offer parameter:\n%s\n", Tools::toString(offer, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2935
2936 //    SharingAgent* searchAgent = new SharingAgent("http://acme.com/test/searcher");
2937 //    bool foundBoiler = false;
2938 //    QList<Offering*> offerings;
2939 //    offerings << offer;
2940 //    QList<Entity*> found = searchAgent->search(entity, av, offerings);
2941 //    qDebug() << "found length is" << found.length();
2942 //    Device* iotc1 = NULL;
2943 //    QListIterator<Entity*> foundIter(found);
2944 //    while (foundIter.hasNext()) {
2945 //        Entity* e = foundIter.next();
2946 //        qDebug() << "next entity:" << e->getIdentifierUri();
2947 //        if (iotc1Identity == e->getIdentifierUri()) {
2948 //            foundBoiler = true;
2949 //            iotc1 = dynamic_cast<Device*>(e);
2950 //        }
2951 //    }
2952
2953 //    if (!foundBoiler) {
2954 //        qCritical() << "Could not find boiler using sharing agent!";
2955 //        return false;
2956 //    }
2957
2958 //    qDebug() << "boiler found:" << iotc1;
2959 //    return true;
2960 //}
2961
2962 bool identifierManagementTest()
2963 {
2964         qDebug() << "Running identifierManagementTest...";
2965         QString domain = "asema.com";
2966         QString systemId = "iotc/123";
2967         QString objId = "/obj%567&/>qwerty/";
2968
2969         Entity* e = new Entity(Tools::createIdentifierUri(domain, systemId, objId));
2970         qDebug() << "identifier creation successful";
2971         printf("%s\n", Tools::toString(e, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2972         QString domain2 = e->getDomain();
2973         QString systemId2 = e->getSystemIdentifier();
2974         QString objId2 = e->getObjectIdentifier();
2975         QString secondObjectId = e->getObjectIdentifier(2);
2976         qDebug() << "domain:" << domain2;
2977         qDebug() << "systemId:" << systemId2;
2978         qDebug() << "objectId:" << objId2;
2979         qDebug() << "secondObjectId:" << secondObjectId;
2980         qDebug() << "identifier partition successful";
2981
2982         if (domain == domain2) {
2983                 qDebug() << "domain correct";
2984         } else {
2985                 qDebug() << "domain match FAILED!";
2986                 return false;
2987         }
2988
2989         if (systemId == systemId2) {
2990                 qDebug() << "systemId correct";
2991         } else {
2992                 qDebug() << "systemId match FAILED!";
2993                 return false;
2994         }
2995
2996         if (objId == objId2) {
2997                 qDebug() << "objId correct";
2998         } else {
2999                 qDebug() << "objId match FAILED!";
3000                 return false;
3001         }
3002
3003         if (secondObjectId.isEmpty()) {
3004                 qDebug() << "secondObjectId correct";
3005         } else {
3006                 qDebug() << "secondObjectId match FAILED!";
3007                 return false;
3008         }
3009
3010         e->destroyCascade();
3011         return true;
3012 }
3013
3014 bool priceSpecificationSerializeParseTest()
3015 {
3016         DistanceDependentPriceSpecification* ddps = new DistanceDependentPriceSpecification();
3017
3018         Coordinates* c = new Coordinates(20.1, 21.0);
3019         ddps->setCoordinates(c);
3020
3021         QString serialized = Tools::toString(ddps, SERIALIZATION__TURTLE);
3022         qDebug() << "Serialized:";
3023         printf("%s\n", serialized.toLatin1().data());
3024         ddps->destroyCascade();
3025
3026         qDebug() << "-------------------";
3027         DistanceDependentPriceSpecification* parsedEntity = (DistanceDependentPriceSpecification*)Tools::fromStringAsObj(serialized);
3028
3029         qDebug() << "\nRe-serializing...";
3030         QString reserializedPayload = Tools::toString(parsedEntity, SERIALIZATION__TURTLE);
3031         printf("%s\n", reserializedPayload.toLatin1().data());
3032
3033         parsedEntity->destroyCascade();
3034
3035         return true;
3036 }
3037
3038 bool priceSpecificationCopyTest()
3039 {
3040         Offering* o = new Offering("http://offering.com");
3041         PropertyDependentPriceSpecification* ps = new PropertyDependentPriceSpecification();
3042         ps->setUnit(RESOURCE__EURO);
3043         ps->setReferenceObject("http://someobject.com");
3044         ps->setProperty("http://proper.ty");
3045         Condition* c1 = new Condition();
3046         c1->addLesser(new Variant(10));
3047         c1->addAction(new Variant(5));
3048         ps->addCondition(c1);
3049         Condition* c2 = new Condition();
3050         c2->addGreaterOrEqual(new Variant(10));
3051         c2->addAction(new Variant(7));
3052         ps->addCondition(c2);
3053         o->addPriceSpecification(ps);
3054
3055         qDebug() << "original:";
3056         o->turtlePrint();
3057
3058         Offering* copy = new Offering(o);
3059         qDebug() << "copied:";
3060         copy->turtlePrint();
3061
3062 //    qDebug() << "orig unit" << o->getPriceSpecification().at(0)->getAll(PROPERTY__UNIT)->at(0);
3063 //    qDebug() << "copy unit" << copy->getPriceSpecification().at(0)->getAll(PROPERTY__UNIT)->at(0);
3064
3065 //    qDebug() << "orig unit" << ((Obj*)o->getAll(PROPERTY__HASPRICESPECIFICATION)->at(0))->getAll(PROPERTY__UNIT)->at(0);
3066 //    qDebug() << "copy unit" << ((Obj*)copy->getAll(PROPERTY__HASPRICESPECIFICATION)->at(0))->getAll(PROPERTY__UNIT)->at(0);
3067
3068         // test that local class pointers differ
3069         if (o->getPriceSpecification().at(0)->getAll(PROPERTY__UNIT)->at(0) == copy->getPriceSpecification().at(0)->getAll(PROPERTY__UNIT)->at(0)) {
3070                 qDebug() << "Orignal and copied unit (variants) has same pointer while copy should be copied!";
3071                 return false;
3072         }
3073
3074         // test that pointers in property map differ
3075         if (((Obj*)o->getAll(PROPERTY__HASPRICESPECIFICATION)->at(0))->getAll(PROPERTY__UNIT)->at(0) == ((Obj*)copy->getAll(PROPERTY__HASPRICESPECIFICATION)->at(0))->getAll(PROPERTY__UNIT)->at(0)) {
3076                 qDebug() << "Orignal and copied unit (variants) has same pointer while copy should be copied!";
3077                 return false;
3078         }
3079
3080         o->destroyCascade();
3081         qDebug() << "copied after destroying original:";
3082         copy->turtlePrint();
3083
3084         if (copy->hasPriceSpecification() && ((PropertyDependentPriceSpecification*)copy->getPriceSpecification().at(0))->getConditions().length() == 2) {
3085                 copy->destroyCascade();
3086                 return true;
3087         } else {
3088                 if (!copy->hasPriceSpecification()) {
3089                         qDebug() << "copy->hasPriceSpecification() returned false!";