1 package smartapi.tests;
3 import java.util.ArrayList;
4 import java.util.Calendar;
6 import java.util.HashMap;
7 import java.util.Random;
8 import java.util.concurrent.TimeUnit;
9 import java.util.Base64;
11 import java.io.DataInputStream;
13 import java.io.FileInputStream;
14 import java.nio.charset.StandardCharsets;
15 import java.lang.reflect.InvocationTargetException;
17 import java.security.PrivateKey;
18 import java.security.PublicKey;
19 import javax.crypto.SecretKey;
20 import javax.xml.datatype.Duration;
22 import org.apache.jena.rdf.model.Model;
23 import org.apache.jena.rdf.model.Resource;
24 import org.apache.commons.lang3.time.DateUtils;
25 import org.apache.commons.lang3.tuple.ImmutablePair;
27 import smartapi.agents.OntologyAgent;
28 import smartapi.agents.RegistrationAgent;
29 import smartapi.agents.SearchAgent;
30 import smartapi.agents.SharingAgent;
31 import smartapi.agents.TradingAgent;
32 import smartapi.agents.TransactionAgent;
33 import smartapi.common.ConceptValidator;
34 import smartapi.common.Crypto;
35 import smartapi.common.CryptoKeyWallet;
36 import smartapi.common.DATATYPE;
37 import smartapi.common.HttpClient;
38 import smartapi.common.HttpMessage;
39 import smartapi.common.MessagePart;
40 import smartapi.common.NS;
41 import smartapi.common.PROPERTY;
42 import smartapi.common.RESOURCE;
43 import smartapi.common.SERIALIZATION;
44 import smartapi.common.SmartAPI;
45 import smartapi.common.Tools;
46 import smartapi.factory.Factory;
47 import smartapi.model.Account;
48 import smartapi.model.Activity;
49 import smartapi.model.Address;
50 import smartapi.model.Availability;
51 import smartapi.model.Capacity;
52 import smartapi.model.Coordinates;
53 import smartapi.model.Device;
54 import smartapi.model.Entity;
55 import smartapi.model.Enumeration;
56 import smartapi.model.Evaluation;
57 import smartapi.model.Grading;
58 import smartapi.model.Input;
59 import smartapi.model.InterfaceAddress;
60 import smartapi.model.Map;
61 import smartapi.model.Message;
62 import smartapi.model.Obj;
63 import smartapi.model.Offering;
64 import smartapi.model.Organization;
65 import smartapi.model.Output;
66 import smartapi.model.Parameter;
67 import smartapi.model.PhysicalEntity;
68 import smartapi.model.PriceSpecification;
69 import smartapi.model.Request;
70 import smartapi.model.Response;
71 import smartapi.model.Route;
72 import smartapi.model.Service;
73 import smartapi.model.SomeItems;
74 import smartapi.model.Status;
75 import smartapi.model.SystemOfInterest;
76 import smartapi.model.TemporalContext;
77 import smartapi.model.TimeSeries;
78 import smartapi.model.Transaction;
79 import smartapi.model.UnitPriceSpecification;
80 import smartapi.model.ValueObject;
81 import smartapi.model.Velocity;
82 import smartapi.rdf.*;
83 import smartapi.reasoner.UnitConverter;
86 public class TestSequence {
92 public static void main(String[] args)
95 TestSequence testSequence = new TestSequence();
96 testSequence.runSequence();
99 public void simpleSerializeParseTest()
101 Activity a = new Activity();
102 Input i = new Input();
103 Output o = new Output();
107 Route route = new Route();
108 Velocity averageSpeed = new Velocity();
109 averageSpeed.setGroundSpeed(new ValueObject(NS.UNIT + "KilometerPerHour", 10));
110 route.setAverageVelocity(averageSpeed);
112 o.add("routeData", route);
114 serializeReserialize(a);
117 public void classSerializeParseTest()
119 System.out.println("class Serialize Parse Test...");
122 String serialization = SERIALIZATION.TURTLE;
124 // // ALIVEREQUEST TEST
126 // // run TestAliveRequest and get the reference object string
127 // String javaAliveRequestString = TestAliveRequest.test(serialization);
129 // // parse to Java object
131 // AliveRequest javaAliveRequest = (AliveRequest)Tools.toObj(javaAliveRequestString, serialization);
133 // // test print, to be removed
134 // System.out.println("\nSecond serialization: \n\n" + Tools.toString(javaAliveRequest, serialization) + "\n\n");
136 // run C++ TestAliveRequest and get aliveRequest string from there
138 //String cppAliveRequestString = HttpClient.sendPost("http://seas.asema.com/webapps/tests/seasobjects/cpp", "TestAliveRequest");
139 // parse to Java object
140 //AliveRequest cppAliveRequest = AliveRequest.fromString(cppAliveRequestString, serialization);
142 // run C# TestAliveRequest and get aliveRequest string from there
144 //String csAliveRequestString = HttpClient.sendPost("http://seas.asema.com/webapps/tests/seasobjects/cs", "TestAliveRequest");
145 // parse to Java object
146 //AliveRequest csAliveRequest = AliveRequest.fromString(csAliveRequestString, serialization);
148 // compare Java object with c++
149 //javaAliveRequest.equals(cppAliveRequest);
150 // report here if cross-platform test failed
152 // compare Java object with c#
153 //javaAliveRequest.equals(csAliveRequest);
154 // report here if cross-platform test failed
155 } catch ( Exception e ) {
161 public void listSerializeParseTest(int listSize)
163 System.out.println("Running listSerializeParseTest (list size: " + listSize + ")");
164 Date testStartTime = new Date();
167 Date now = new Date();
168 Calendar calendar = Calendar.getInstance();
169 calendar.setTime(now);
171 TimeSeries ts = new TimeSeries();
173 //ArrayList<Evaluation> testList = new ArrayList<Evaluation>();
174 smartapi.rdf.List testList = new LinkedList();
176 for ( int i = 0; i < listSize; i++ ) {
177 Evaluation e = new Evaluation();
178 e.setValue(new Variant(i));
179 e.setInstant(calendar.getTime());
180 calendar.add(Calendar.DATE, 1);
185 ts.setList(testList);
186 printTestTime(testStartTime, "Time");
189 System.out.println("Serializing data...\n");
190 String stringData = Tools.toString(ts, SERIALIZATION.TURTLE);
191 System.out.println(stringData+"\n");
192 System.out.println("---test print() function \n");
194 printTestTime(testStartTime, "Time");
197 System.out.println("Parsing back the serialized data...");
198 Model model = Tools.fromString(stringData, SERIALIZATION.TURTLE);
201 res = Tools.getResourceByType(RESOURCE.TIMESERIES, model);
202 } catch (Exception e) {
203 System.err.println("Exception while trying to get smartapi:TimeSeries resource from the model.");
204 printTestTime(testStartTime, "Test interrupted in");
209 TimeSeries tsParsed = Obj.parse(TimeSeries.class, res);
210 // test if list items are still there
211 if ( tsParsed.hasList() ) {
212 ArrayList<Evaluation> tsl = (ArrayList<Evaluation>)(ArrayList<?>)tsParsed.getList().getItems();
213 if ( tsl.size() == listSize ) {
214 System.out.println("ListSerializeParseTest (list size: " + listSize + ") passed.");
215 printTestTime(testStartTime, "Test executed in");
217 System.err.println("ListSerializeParseTest (list size: " + listSize + ") failed!");
218 System.err.println("Size of serialized and parsed list is " + tsl.size() + ".");
219 printTestTime(testStartTime, "Test executed in");
222 System.err.println("ListSerializeParseTest (list size: " + listSize + ") failed!");
223 System.err.println("Size of serialized and parsed list is 0.");
224 printTestTime(testStartTime, "Test executed in");
227 catch (NoSuchMethodException e) {}
228 catch (InvocationTargetException e) {}
231 public void arraySerializeParseTest(int listSize)
233 System.out.println("Running arraySerializeParseTest (array size: " + listSize + ")");
234 Date testStartTime = new Date();
237 Date now = new Date();
238 Calendar calendar = Calendar.getInstance();
239 calendar.setTime(now);
241 TimeSeries ts = new TimeSeries();
242 OrderedList testList = new OrderedList();
244 for ( int i = 0; i < listSize; i++ ) {
245 Evaluation e = new Evaluation();
246 e.setValue(new Variant(i));
247 e.setInstant(calendar.getTime());
248 calendar.add(Calendar.DATE, 1);
249 testList.addItems(e);
252 ts.setList(testList);
253 printTestTime(testStartTime, "Time");
256 System.out.println("Serializing data...");
257 String stringData = Tools.toString(ts, SERIALIZATION.TURTLE);
258 printTestTime(testStartTime, "Time");
261 System.out.println("Parsing back the serialized data...");
262 Model model = Tools.fromString(stringData, SERIALIZATION.TURTLE);
265 res = Tools.getResourceByType(RESOURCE.TIMESERIES, model);
266 } catch (Exception e) {
267 System.err.println("Exception while trying to get smartapi:TimeSeries resource from the model.");
268 printTestTime(testStartTime, "Test interrupted in");
273 TimeSeries tsParsed = Obj.parse(TimeSeries.class, res);
275 // test if list items are still there
276 if ( tsParsed.hasList() ) {
277 ArrayList<Evaluation> tsl = (ArrayList<Evaluation>)(ArrayList<?>)tsParsed.getList().getItems();
278 if ( tsl.size() == listSize ) {
279 System.out.println("ArraySerializeParseTest (array size: " + listSize + ") passed.");
280 printTestTime(testStartTime, "Test executed in");
282 System.err.println("ArraySerializeParseTest (array size: " + listSize + ") failed!");
283 System.err.println("Size of serialized and parsed array is " + tsl.size() + ".");
284 printTestTime(testStartTime, "Test executed in");
287 System.err.println("ArraySerializeParseTest (array size: " + listSize + ") failed!");
288 System.err.println("Size of serialized and parsed array is 0.");
289 printTestTime(testStartTime, "Test executed in");
292 catch (NoSuchMethodException e) {}
293 catch (InvocationTargetException e) {}
295 public void listOfMapsTest()
297 System.out.println("List of maps test");
299 Activity a = new Activity();
300 Input i = new Input();
301 Output o = new Output();
307 ArrayList<Map> controllable_appliances = new ArrayList<Map>();
308 i.add("ControllableAppliances", controllable_appliances);
310 Map appliance1 = new Map();
311 appliance1.insert("Active", true);
312 appliance1.insert("ConsumptionRate", 1.267);
313 appliance1.insert("Name", "String content");
315 ArrayList<Map> controllable_works = new ArrayList<Map>();
316 Map works1 = new Map();
317 works1.insert("EarlyStartPeriod", 2147483647);
318 works1.insert("LateStopPeriod", 2147483647);
319 works1.insert("WorkDuration", 2147483647);
320 controllable_works.add(works1);
321 appliance1.insert("ControllableWorks", works1);
322 controllable_appliances.add(appliance1);
325 ArrayList<Map> controllable_appliance_result = new ArrayList<Map>();
326 ArrayList<Map> controllable_appliance_work_result = new ArrayList<Map>();
328 Map appliance_result_1 = new Map();
329 Map work_result_1 = new Map();
330 Map usage_information = new Map();
332 appliance_result_1.insert("Name", "String content");
333 appliance_result_1.insert("ControllableWorkResult", controllable_appliance_work_result);
334 controllable_appliance_work_result.add(work_result_1);
335 usage_information.insert("StartPeriod", 2147483647);
336 usage_information.insert("StopPeriod", 2147483647);
337 usage_information.insert("WorkDuration", 2147483647);
338 work_result_1.insert("UsageInformation", usage_information);
340 ArrayList<Map> period_consumptions = new ArrayList<Map>();
341 Map period_1 = new Map();
342 period_1.insert("Period", 2147483647);
343 period_1.insert("Value", 1.26743);
344 period_consumptions.add(period_1);
345 work_result_1.insert("PeriodConsumption", period_consumptions);
346 controllable_appliance_result.add(appliance_result_1);
347 o.add("ControllableApplianceResult", controllable_appliance_result);
349 serializeReserialize(a);
352 public void listOfMapsWithValueObjectsTest()
354 System.out.println("List of maps test");
356 Activity a = new Activity();
357 Input i = new Input();
358 Output o = new Output();
364 ArrayList<Map> controllable_appliances = new ArrayList<Map>();
365 i.add("ControllableAppliances", controllable_appliances);
367 Map appliance1 = new Map();
368 appliance1.insert("Active", true);
369 appliance1.insert("ConsumptionRate", 1.267);
370 appliance1.insert("Name", "String content");
372 ArrayList<Map> controllable_works = new ArrayList<Map>();
373 Map works1 = new Map();
374 works1.insert("EarlyStartPeriod", 2147483647);
375 works1.insert("LateStopPeriod", 2147483647);
376 works1.insert("WorkDuration", 2147483647);
377 controllable_works.add(works1);
378 appliance1.insert("ControllableWorks", works1);
379 controllable_appliances.add(appliance1);
382 ArrayList<Map> controllable_appliance_result = new ArrayList<Map>();
383 ArrayList<Map> controllable_appliance_work_result = new ArrayList<Map>();
385 Map appliance_result_1 = new Map();
386 Map work_result_1 = new Map();
387 Map usage_information = new Map();
389 appliance_result_1.insert("Name", "String content");
390 appliance_result_1.insert("ControllableWorkResult", controllable_appliance_work_result);
391 controllable_appliance_work_result.add(work_result_1);
392 usage_information.insert("StartPeriod", 2147483647);
393 usage_information.insert("StopPeriod", 2147483647);
394 usage_information.insert("WorkDuration", 2147483647);
395 work_result_1.insert("UsageInformation", usage_information);
397 ArrayList<Map> period_consumptions = new ArrayList<Map>();
398 Map period_1 = new Map();
399 period_1.insert("Period", 2147483647);
400 period_1.insert("Value", 1.26743);
401 period_consumptions.add(period_1);
402 work_result_1.insert("PeriodConsumption", period_consumptions);
403 controllable_appliance_result.add(appliance_result_1);
404 o.add("ControllableApplianceResult", controllable_appliance_result);
406 serializeReserialize(a);
409 public void routingAndEnergyTest()
411 String requesterIdentity = "http://seasexamples.asema.com/api/Crequest";
416 r = Factory.createRequest(requesterIdentity);
417 } catch (Exception ex) {}
419 Input i = new Input();
420 Activity ar = new Activity();
424 PhysicalEntity car = new PhysicalEntity();
425 car.setWeight( new ValueObject(NS.UNIT + "Kilogram", 1500));
426 car.add("frontalAerodynamicCoefficient", new ValueObject(NS.UNIT + "SquareMeter", 0.73));
427 car.add("tireRollingResistanceCoefficient", new ValueObject(0.2));
428 car.add("gearEfficiencyCoefficient", new ValueObject(0.3));
429 car.add("batteryCapacity", new ValueObject(NS.UNIT + "KilowattHour", 115000));
430 car.add("extraLoadWeight", new ValueObject(NS.UNIT + "Kilogram", 510));
431 car.add("auxiliaryEquipmentConsumption", new ValueObject(NS.UNIT + "Watt", 365));
432 car.add("maximumAcceleration", new ValueObject(NS.UNIT + "MeterPerSecondSquared", 3.4));
433 car.add("maximumDeceleration", new ValueObject(NS.UNIT + "MeterPerSecondSquared", 4.2));
434 i.add("vehicleData", car);
436 Request r_received = (Request)serializeParse(r, false);
438 // Read some value from the response
439 PhysicalEntity inputtedCar = r_received.getFirstActivity().getFirstInput().getFirstAs(PhysicalEntity.class, "vehicleData");
440 ValueObject frontalAerodynamicCoefficient = inputtedCar.getFirstAs(ValueObject.class, "frontalAerodynamicCoefficient");
441 System.out.println("Got input value for frontalAerodynamicCoefficient: " + frontalAerodynamicCoefficient.getValue().asDouble() + " which is in " + frontalAerodynamicCoefficient.getUnit());
445 String responderIdentity = "http://seasexamples.asema.com/api/Cresponse";
448 r_s = Factory.createResponse(responderIdentity);
449 } catch (Exception ex) {}
451 Activity ar_s = new Activity();
452 Output o_s = new Output();
454 r_s.addActivity(ar_s);
456 TemporalContext tc = new TemporalContext();
457 Velocity averageSpeed = new Velocity();
458 Route route = new Route();
460 averageSpeed.setGroundSpeed(new ValueObject(NS.UNIT + "KilometerPerHour", 34.1));
461 tc.setDuration("PT1H");
463 route.setLength(new ValueObject(NS.UNIT + "Kilometer", 42.3));
464 route.setEnergyConsumption(new ValueObject(NS.UNIT + "KilowattHour", 12000));
465 route.setAverageVelocity(averageSpeed);
466 route.setDuration(tc);
468 route.add(PROPERTY.ADDON, 1.22);
469 route.add(PROPERTY.FRESHNESS, Factory.createDuration(1, 2,3,4,5,6));
471 System.out.println("DEBUG: "+route.get(PROPERTY.FRESHNESS));
473 o_s.add("routeData", route);
475 //serializeReserialize(r);
476 serializeReserialize(r_s);
479 public void registrationTest()
481 String serverIdentity = "http://seasexamples.asema.com/api/Ctestserver";
482 Service service = createSampleRegistrationEntity(serverIdentity);
484 RegistrationAgent agent = new RegistrationAgent(serverIdentity);
485 agent.addEntity(service);
487 Response response = agent.registrate();
488 // print out possible errors on the response
489 Tools.printErrors(response);
490 // get response status
491 if ( response.hasStatus() ) {
492 Status status = response.getStatus();
493 // check if the operation was successful
494 if ( status.hasType(RESOURCE.ERROR) ) {
495 System.out.println("Registration failed.");
497 System.out.println("Registration successful.");
501 System.out.println(" Now try deregister:");
502 Response response2 = agent.deRegistrate();
503 Tools.printErrors(response2);
505 System.out.println(" now try search:");
506 SearchAgent agent2 = new SearchAgent(serverIdentity);
507 agent2.debugMode(true);
508 // all entities in Otaniemi, Espoo as defined by the given polygon
509 ArrayList<Coordinates> polygon = new ArrayList<Coordinates>();
510 polygon.add(new Coordinates(60.178, 24.829));
511 polygon.add(new Coordinates(60.183, 24.83));
512 polygon.add(new Coordinates(60.1926, 24.842));
513 polygon.add(new Coordinates(60.187, 24.809));
514 polygon.add(new Coordinates(60.181, 24.818));
515 agent2.polygonSearchArea(polygon);
517 java.util.List<Entity> entities = agent2.search();
518 System.out.println(entities.size());
519 for (Entity e: entities){
520 System.out.println(e.getName()+ "-"+ e.getIdentifierUri());
521 System.out.println(e.getTypes());
525 public void symmetricCryptoTest()
527 SecretKey key = Crypto.generateSymmetricKey();
528 String content = "The two men entered the Starbucks on Thursday and asked to use to the bathroom. An employee told them it was only for paying customers. When they then sat in the store without ordering anything, the manager called police, and the men were arrested for trespassing. No charges were filed. ";
530 String encrypted = Crypto.symmetricEncrypt(key, content);
531 String decrypted = Crypto.symmetricDecrypt(key, encrypted);
533 System.out.println("Crypto test.");
534 System.out.println("Original:\n" + content);
535 System.out.println("Encrypted:\n" + encrypted);
536 System.out.println("Decrypted:\n" + decrypted);
537 System.out.println("Key:\n" + Crypto.encodeKeyToBase64(key));
540 public void cryptoRegistrationTest()
542 PublicKey pubKey = null;
543 PrivateKey privKey = null;
546 pubKey = getPemPublicKey("/home/jani/workspace/git/seas/Common/Java/SeasObjects/src/seasobjects/tests/testkey_public.pem", "RSA");
547 privKey = getPemPrivateKey("/home/jani/workspace/git/seas/Common/Java/SeasObjects/src/seasobjects/tests/testkey_private.pem", "RSA");
548 } catch (Exception ex) {
549 System.out.println("Could not find keys.");
550 System.out.println(ex);
552 String serverIdentity = "http://seasexamples.asema.com/api/Ctestserver";
553 Service service = createSampleRegistrationEntity(serverIdentity);
555 RegistrationAgent agent = new RegistrationAgent(serverIdentity);
556 String payload = agent.generateEncryptedRegistrationMessage(pubKey, service).getLeft();
557 System.out.println("------");
558 System.out.println(payload);
559 System.out.println("------");
562 //payload = "PDvrIUEup/eiTAolieUHSFBgV+UI2h0vvuGhHQjnS5QXlBmPKgO4WrJTUyV60Yqx7/baPg28or6Zat4HokK0ZbXux6xUMvYUTkGpzSjrnaulrn7biv5g/p7dTKx89JkVuW0K3Oci2ICDdg4PcYC1EH/7EWVaLUoUcPb1qRn/qBpsDwieBvvHU4Solo59meo26Ch+CL4hLtsTtrdZmtCvUkn1lIFm9vc3WRo5jXZP9vpR5UMRVXDCu007fqeAD7ppgJHI6/U3kIiyc3n54yvgyzKShlAeORIaxNxMSY09QTEtoGr92M5iBoOZYsfdxndfHy0yPNuGvOhO9ab6nrXwlA==";
564 //payload += "LCBcyYE+8ILCD43DOQGBsg==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";
567 //payload = "fYM/MR0yq2nDAvDM8xEg6VvEyvz9eWZefFylY6vaQr3syQw2vATDpv7DZIUdb3fsGbX9kboJNSSQTOTEG/VDhjnPz9DWLJXygRE3868ywyhzn5ojKrBMwf+ehvYfMnJI5gco+EzbO8zFuCC2yukJV/FA72y3OV3r/BGRSsJ+r+vZrwzF92m0rAJD0qrZ/ENfxEOgtXYUAs/glcxSi0fKUtrXledAnblusSXbg6iIdPBb7+5A+OadBg8oPZqIkZT2RwscsshEUDWlXYmZhmWjAkcNhiJiU1SJU9bt0oXBTVprmMBdzxlmU00xBnBj9qsu44e73I3YDIz04jnrcS8PzQ==";
569 //payload += "Zh8VwrOxzMgke5nGy2WVaQ==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";
571 ImmutablePair<String, SecretKey> decrypted = Crypto.asymmetricDecrypt(privKey, payload);
572 System.out.println(decrypted.getLeft());
573 System.out.println("------");
574 String ct = Crypto.symmetricEncrypt(decrypted.getRight(), decrypted.getLeft());
575 //System.out.println(ct);
576 String pt = Crypto.symmetricDecrypt(decrypted.getRight(), ct);
577 //System.out.println(pt);
580 private String loadKeyFile(String filename) throws Exception {
581 System.out.println("Loading key: " + filename);
583 File f = new File("src/smartapi/tests/"+filename);
584 System.out.println(f.getAbsolutePath());
587 //File f = new File(filename);
588 FileInputStream fis = new FileInputStream(f);
589 DataInputStream dis = new DataInputStream(fis);
590 byte[] keyBytes = new byte[(int) f.length()];
591 dis.readFully(keyBytes);
594 return new String(keyBytes);
597 private PrivateKey getPemPrivateKey(String fileName, String algorithm) throws Exception {
598 String keyData = loadKeyFile(fileName);
599 return Crypto.extractPemFormatPrivateKey(keyData, algorithm);
602 private PublicKey getPemPublicKey(String fileName, String algorithm) throws Exception {
603 String keyData = loadKeyFile(fileName);
604 return Crypto.extractPemFormatPublicKey(keyData, algorithm);
607 public static Service createSampleRegistrationEntity(String serverIdentity)
609 String serverName = "A fantastic Java route energy calculation service";
611 Service service = new Service(serverIdentity);
614 Organization owner = new Organization();
615 Address acmeAddress = new Address();
616 InterfaceAddress iface = new InterfaceAddress();
618 iface.setHost("www.acme.com");
619 iface.setScheme("https");
620 iface.setPath("/seas/v1.0e1.0/access");
621 acmeAddress.setStreetAddress("Giant Rubber Band Street");
622 acmeAddress.setZipCode("12345");
623 acmeAddress.setCity("Fairfield, New Java");
624 owner.setName("Acme Industries");
625 owner.setAddress(acmeAddress);
627 service.addInterface(iface);
628 service.addOwner(owner);
629 service.setName(serverName);
630 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.");
631 service.addWebsite("http://www.acme.com/acmeoptimizers/roadrunner/beep/beep");
635 Activity a = new Activity();
636 Input i = new Input();
637 Output o = new Output();
640 service.addCapability(a);
642 PhysicalEntity car = new PhysicalEntity();
643 car.setWeight(Factory.createValueObject(NS.UNIT + "Kilogram", "Vehicle's weight without any consumables or passengers."));
644 car.add("frontalAerodynamicCoefficient", Factory.createValueObject(NS.UNIT + "SquareMeter", "Product of vehicle's frontal area and aerodynamic coefficient"));
645 car.add("tireRollingResistanceCoefficient", Factory.createValueObject(new Obj(DATATYPE.INTEGER), "Vehicle's tire rolling resistance coefficient, in interval ]0, 1["));
646 car.add("gearEfficiencyCoefficient", Factory.createValueObject("Vehicle's efficiency coefficient between engine and gear, in interval ]0, 1["));
647 car.add("batteryCapacity", Factory.createValueObject(NS.UNIT + "KilowattHour", "Vehicle's capacity of the battery (enter only if electric vehicle or hybrid rechargeable, 0 otherwise"));
648 car.add("extraLoadWeight", Factory.createValueObject(NS.UNIT + "Kilogram", "Vehicle's extra load (consumables and passengers weight)"));
649 car.add("auxiliaryEquipmentConsumption", Factory.createValueObject(NS.UNIT + "Watt", "Vehicle's instantaneous auxiliary equipments consumption"));
650 car.add("maximumAcceleration", Factory.createValueObject(NS.UNIT + "MeterPerSecondSquared", "Maximum acceleration (> 0.1), based on vehicle's acceleration capacity and expected driving behavior"));
651 car.add("maximumDeceleration", Factory.createValueObject(NS.UNIT + "MeterPerSecondSquared", "Maximum deceleration (< -0.1), based on vehicle's braking capacity and expected driving behavior"));
652 i.add("vehicleData", car);
654 TemporalContext tc = new TemporalContext();
655 Velocity averageSpeed = new Velocity();
656 Route route = new Route();
658 tc.setDescription("The timespan estimated for traveling the route.");
659 averageSpeed.setDescription("Estimated average speed for the travel.");
661 averageSpeed.setGroundSpeed(Factory.createValueObject(NS.UNIT + "KilometerPerHour", "Speed component in relation to road surface."));
663 route.setLength(Factory.createValueObject(NS.UNIT + "Kilometer", "Total length of the calculated route."));
664 route.setEnergyConsumption(Factory.createValueObject(NS.UNIT + "KilowattHour", "Total energy consumed in driving the route."));
665 route.setAverageVelocity(averageSpeed);
666 route.setDuration(tc);
668 o.add("routeData", route);
673 public void transactionProcessingTest()
675 String clientKeyId = "http://www.acme.com/services/abcd/";
676 String publicKeyServer = "http://127.0.0.1:11371";
678 // Fetch public key for clientIdUri
679 PublicKey clientPubKey = Crypto.downloadPublicKey(clientKeyId, publicKeyServer);
680 System.out.println("Got a public key");
681 System.out.println(clientPubKey);
683 PublicKey pubKey = null;
684 PrivateKey privKey = null;
687 pubKey = getPemPublicKey("/home/jani/workspace/git/seas/Common/Java/SeasObjects/src/seasobjects/tests/testkey_public.pem", "RSA");
688 privKey = getPemPrivateKey("/home/jani/workspace/git/seas/Common/Java/SeasObjects/src/seasobjects/tests/testkey_private.pem", "RSA");
689 } catch (Exception ex) {
690 System.out.println("Could not find keys for the test.");
691 System.out.println(ex);
694 String testData = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras dapibus, sapien eu consequat faucibus, ligula purus tincidunt orci, tincidunt mattis orci dolor in eros. Praesent eget enim ante. Curabitur eleifend ipsum orci, quis vehicula lectus auctor vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean congue nisl lectus. Fusce varius aliquam velit at varius. Integer eu bibendum mi, eget rhoncus metus. Morbi efficitur massa et leo viverra hendrerit. Integer fermentum, dui sed gravida interdum, orci nibh posuere elit, a tincidunt tortor urna a eros. Proin ornare ornare massa quis dignissim. Sed sit amet sapien turpis. Fusce tempus turpis vitae nunc tincidunt ornare. Nulla sit amet scelerisque lectus. Nulla facilisis ipsum ac elit fermentum pharetra. ";
695 String signature = Crypto.sign(privKey, testData);
696 System.out.println("Created signature: " + signature);
697 boolean signedProperly = false;
699 signedProperly = Crypto.verifySignature(signature, pubKey, testData);
700 } catch (Exception e) {}
701 System.out.println("Signature test result: " + signedProperly);
703 // Generate a session key
704 SecretKey sessionKey = Crypto.generateSymmetricKey();
706 // Encrypt data with sessionKey
707 String encryptedResponse = Crypto.symmetricEncrypt(sessionKey, testData.getBytes(StandardCharsets.UTF_8));
708 System.out.println("\nEncrypted response:\n" + encryptedResponse);
710 // Encrypt sessionKey with client's public key
711 String encryptedSessionKey = Crypto.encryptAndEncodeKey(pubKey, sessionKey);
712 System.out.println("\nEncrypted key:\n" + encryptedSessionKey);
714 // Calculate a hash for the encryptedResponse
715 String responseHash = Crypto.createEncodedMessageDigest(encryptedResponse);
717 System.out.println("\nHash for the response: " + responseHash);
720 boolean hashmatches = Crypto.verifyEncodedMessageDigest(responseHash, encryptedResponse);
721 System.out.println("Hash verification: " + hashmatches);
723 // Open the session key
724 SecretKey decryptedSessionKey = Crypto.decryptAndDecodeKey(privKey, encryptedSessionKey);
725 String descryptedData = Crypto.symmetricDecrypt(sessionKey, encryptedResponse);
726 System.out.println("Decrypted data: \n" + descryptedData);
729 public void transactionVerificationTestWrite()
731 String referenceId = "http://tests.b.c/ref";
732 String senderId = "http://tests.b.c/sender";
733 String myIdentity = senderId;
734 PublicKey pubKey = null;
735 PrivateKey privKey = null;
736 String testData = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras dapibus, sapien eu consequat faucibus, ligula purus tincidunt orci, tincidunt mattis orci dolor in eros. Praesent eget enim ante. Curabitur eleifend ipsum orci, quis vehicula lectus auctor vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean congue nisl lectus. Fusce varius aliquam velit at varius. Integer eu bibendum mi, eget rhoncus metus. Morbi efficitur massa et leo viverra hendrerit. Integer fermentum, dui sed gravida interdum, orci nibh posuere elit, a tincidunt tortor urna a eros. Proin ornare ornare massa quis dignissim. Sed sit amet sapien turpis. Fusce tempus turpis vitae nunc tincidunt ornare. Nulla sit amet scelerisque lectus. Nulla facilisis ipsum ac elit fermentum pharetra. ";
739 pubKey = getPemPublicKey("testkey_public.pem", "RSA");
740 privKey = getPemPrivateKey("testkey_private.pem", "RSA");
741 } catch (Exception ex) {
742 System.out.println("Could not find keys for the test.");
743 System.out.println(ex);
746 Base64.Encoder b64e = Base64.getEncoder();
747 String notary = TransactionAgent.getDefaultNotary();
748 SecretKey key = Crypto.generateSymmetricKey();
749 String sessionKeySent = Crypto.encryptAndEncodeKey(pubKey, key);
750 String contentHash = Crypto.createEncodedMessageDigest(testData);
751 String signature = Crypto.sign(privKey, contentHash);
753 System.out.println("Encrypted content key is: " + sessionKeySent);
754 System.out.println("Content signature is: " + signature);
755 System.out.println("Content hash is: " + contentHash);
758 // Emulate send operation
759 Transaction transaction = null;
761 transaction = Factory.createTransaction(referenceId, senderId);
762 } catch ( Exception e ) {
765 transaction.setSigner(senderId);
766 Message message = new Message();
767 message.setHashCode(contentHash);
768 message.setSignature(signature);
769 message.setSessionKey(sessionKeySent);
770 transaction.setNotarizedObject(message);
772 HttpMessage sentMessage = new HttpMessage();
777 r = Factory.createRequest(myIdentity);
778 } catch (Exception ex) {}
779 r.setMethod(RESOURCE.WRITE);
781 Activity a = new Activity();
784 Input i = new Input();
787 SystemOfInterest system = new SystemOfInterest();
788 system.setSameAs(TransactionAgent.getDefaultNotary());
789 i.setSystemOfInterest(system);
791 Parameter param = new Parameter();
792 param.setKey("transactions");
793 param.setName("Transaction id list");
794 param.setDescription("List of ids of transactions that are sent for storing into the database.");
795 param.addValue(new Variant(transaction.getIdentifierUri()));
796 i.addParameter(param);
798 String mainRequestString = Tools.toString(r);
799 sentMessage.add("Main", mainRequestString);
801 String mainRequestHash = Crypto.createEncodedMessageDigest(mainRequestString);
802 String requestSignature = Crypto.sign(privKey, mainRequestHash);
804 // create transaction for the main request
805 String transactionIdentifierUri = myIdentity + Crypto.generate16ByteCryptoRandomString();
806 Transaction requestTransaction = null;
808 requestTransaction = Factory.createTransaction(transactionIdentifierUri, myIdentity);
809 } catch ( Exception e ) {
812 requestTransaction.setSigner(myIdentity);
813 Message requestTransactionMessage = new Message();
814 requestTransactionMessage.setId(r.getId());
815 requestTransactionMessage.setHashCode(mainRequestHash);
816 requestTransactionMessage.setSignature(requestSignature);
817 requestTransaction.setNotarizedObject(requestTransactionMessage);
819 // Add the message signature
820 String requestTransactionString = Tools.toString(requestTransaction);
821 sentMessage.add(transactionIdentifierUri, requestTransactionString);
823 // Add transactions that are sent for storing
824 sentMessage.add(transaction.getIdentifierUri(), Tools.toString(transaction));
825 // with their respective signatures
826 sentMessage.add(transaction.getIdentifierUri(), Tools.toString(transaction));
828 String msg = sentMessage.asString();
829 System.out.println("Sending: \n" + msg + "\n------------------------ < message end > --------------");
832 /* ---- RECEIVE ---- */
835 HttpMessage receivedMessage;
837 receivedMessage = HttpMessage.parse(msg, sentMessage.getContentType());
838 } catch (Exception e) {
839 System.out.println("Failed to parse incoming message body");
843 if (receivedMessage.size() < 2) {
844 System.out.println("Request should have at least two parts");
848 // parse all request parts
849 java.util.Map<String,MessagePart> partsMap = receivedMessage.getParts();
850 Obj[] objects = new Obj[partsMap.size()];
851 String[] parts = new String[partsMap.size()];
852 int mainRequestIndex = -1;
853 Request mainRequest = null;
856 for (String partId : partsMap.keySet()) {
857 MessagePart part = partsMap.get(partId);
858 objects[mi] = Tools.toObj(part.getBody());
859 parts[mi] = part.getBody();
860 if (objects[mi] == null) {
861 System.out.println("No object returned when parsing the following part: " + parts[mi]);
865 if (partId.equals("Main")) {
866 // main Request found
867 if (objects[mi] instanceof Request) {
868 mainRequest = (Request)objects[mi];
869 mainRequestIndex = mi;
871 System.out.println("Main part should contain a Request object");
878 } catch (Exception e) {
879 System.out.println("Exception caught when parsing objects: " + e.getMessage());
882 if (mainRequest == null) {
883 System.out.println("No main Request found");
887 // now find the main transaction, which satisfies the following:
888 // (a) its id is not listed in main request as a sub-transaction
889 // (b) its seas id matches the main request seas id
890 Transaction mainTransaction = null;
892 // get contained transaction ids
893 Activity transactionIdActivity = mainRequest.getFirstActivity();
894 java.util.List<Variant> transactionIds = new ArrayList<Variant>();
895 ArrayList<String> transactionIdStrings = new ArrayList<String>(); // used for checking that transactions match
896 Parameter transactionIdParameter = new Parameter(); // needed for constructing the response
897 if (transactionIdActivity != null) {
898 java.util.List<Input> inputs = transactionIdActivity.getInputs();
899 for (Input ii : inputs) {
900 transactionIds = ii.get("transactions");
901 for (Variant v : transactionIds) {
902 transactionIdParameter.addValue(v);
903 transactionIdStrings.add(v.toString());
907 // verify that transaction ids match the contained transactions
908 // by going through all transactions and removing their ids from
909 // transactionIdStrings; they should all be there and list should
910 // be empty in the end
911 for (Obj o : objects) {
912 if (o instanceof Transaction) {
913 String transactionId = o.getIdentifierUri();
914 if (!transactionIdStrings.remove(transactionId)) {
915 // this transaction id was not in the request,
916 // so it could be the main transaction
917 Transaction t = (Transaction)o;
918 if (mainTransaction == null &&
919 t.hasNotarizedObject() &&
920 t.getNotarizedObject().hasIdentifierUri()) {
921 // transaction message id matches main request id, so this is indeed the main transaction
922 mainTransaction = (Transaction)o;
924 // this isn't the main transaction but its id
925 // cannot be found in the main request either
926 System.out.println("Transaction id " + transactionId + " is missing from the main request");
933 if (mainTransaction == null) {
934 System.out.println("Main transaction not found in the request");
938 // now all elements should have been removed from transactionIdStrings
939 if (transactionIdStrings.size() > 0) {
940 System.out.println("Main request contains " + transactionIds.size() + " unknown transaction ids");
944 // // verify signatures in the two main parts
946 // // request (message) signature
947 // if (mainTransaction.hasNotarizedObject() && mainTransaction.getNotarizedObject().hasSignature()) {
948 // String messageSignature = mainTransaction.getNotarizedObject().getSignature();
949 // String messageHash = mainTransaction.getNotarizedObject().getHashCode();
951 // if (!TransactionAgent.verifyTransactionHash(messageHash, parts[mainRequestIndex])) {
952 // // invalid request signature!
953 // System.out.println("Main request hash verification failed!");
956 // if (!TransactionAgent.verifyTransactionSignature(messageSignature, pubKey, messageHash)) {
957 // // invalid request signature!
958 // System.out.println("Main request signature verification failed!");
961 // System.out.println("Request signature verified");
964 // System.out.println("Message signature not found");
968 // // transaction signature
969 // if (mainTransaction.hasNotarizedObject() && mainTransaction.getNotarizedObject().hasSignature()) {
970 // String transactionSignature = mainTransaction.getNotarizedObject().getSignature();
971 // String transactionHash = mainTransaction.getNotarizedObject().getHashCode();
973 // if (!TransactionAgent.verifyTransactionSignature(transactionSignature, pubKey, transactionHash)) {
974 // // invalid transaction signature!
975 // System.out.println("Transaction signature verification failed!");
978 // System.out.println("Transaction signature verified");
981 // System.out.println("Transaction signature not found");
984 // } catch (Exception e) {
985 // System.out.println("Exception caught when verifying signatures: " + e.getMessage());
990 // public void transactionVerificationTestRead()
992 // String referenceId = "http://tests.b.c/ref";
993 // String senderId = "http://tests.b.c/sender";
994 // String myIdentity = senderId;
995 // String contentHash = "ABCDHashEFGH";
996 // PublicKey pubKey = null;
997 // PrivateKey privKey = null;
1000 // pubKey = getPemPublicKey("/home/jani/workspace/git/seas/Common/Java/SeasObjects/src/seasobjects/tests/testkey_public.pem", "RSA");
1001 // privKey = getPemPrivateKey("/home/jani/workspace/git/seas/Common/Java/SeasObjects/src/seasobjects/tests/testkey_private.pem", "RSA");
1002 // } catch (Exception ex) {
1003 // System.out.println("Could not find keys for the test.");
1004 // System.out.println(ex);
1007 // Base64.Encoder b64e = Base64.getEncoder();
1008 // String notaryAddress = TransactionAgent.getDefaultNotary();
1009 // String signature = Crypto.sign(privKey, contentHash);
1011 // System.out.println("Content signature is: " + signature);
1012 // System.out.println("Content hash is: " + contentHash);
1014 // /* ---- SEND ---- */
1015 // // Emulate send operation
1016 // Transaction transaction = null;
1018 // transaction = Factory.createTransaction(referenceId, senderId);
1019 // } catch ( Exception e ) {
1020 // e.printStackTrace();
1023 // transaction.setSigner(senderId);
1024 // Message message = new Message();
1025 // message.setHashCode(contentHash);
1026 // message.setSignature(signature);
1027 // transaction.setNotarizedObject(message);
1029 // HttpMessage sentHttpMessage = new HttpMessage();
1032 // Request r = null;
1034 // r = Factory.createRequest(myIdentity);
1035 // } catch (Exception ex) {}
1036 // r.setMethod(RESOURCE.READ);
1038 // Activity a = new Activity();
1039 // r.addActivity(a);
1041 // Input i = new Input();
1044 // SystemOfInterest system = new SystemOfInterest();
1045 // system.setSameAs(notaryAddress);
1046 // i.setSystemOfInterest(system);
1048 // Parameter param = new Parameter();
1049 // param.setKey("transactions");
1050 // param.setName("Transaction id list");
1051 // param.setDescription("List of ids of transactions that are sent to be fetched from the database.");
1052 // param.addValue(new Variant(transaction.getIdentifierUri()));
1053 // i.addParameter(param);
1055 // String mainRequestString = Tools.toString(r);
1056 // sentHttpMessage.add("Main", mainRequestString);
1058 // String mainRequestHash = Crypto.createEncodedMessageDigest(mainRequestString);
1059 // String requestSignature = Crypto.sign(privKey, mainRequestHash);
1061 // // create transaction for the main request
1062 // String transactionIdentifierUri = myIdentity + Crypto.generate16ByteCryptoRandomString();
1063 // Transaction requestTransaction = null;
1065 // requestTransaction = Factory.createTransaction(transactionIdentifierUri, myIdentity);
1066 // } catch ( Exception e ) {
1067 // e.printStackTrace();
1070 // requestTransaction.setSigner(myIdentity);
1071 // Message requestTransactionMessage = new Message();
1072 // requestTransactionMessage.setId(r.getId());
1073 // requestTransactionMessage.setHashCode(mainRequestHash);
1074 // requestTransactionMessage.setSignature(requestSignature);
1075 // requestTransaction.setNotarizedObject(requestTransactionMessage);
1077 // String requestTransactionString = Tools.toString(requestTransaction);
1078 // sentHttpMessage.add(transactionIdentifierUri, requestTransactionString);
1080 // // add transactions that are sent for reading
1081 // sentHttpMessage.add(transaction.getIdentifierUri(), Tools.toString(transaction));
1083 // String msg = sentHttpMessage.asString();
1084 // System.out.println("Sending: \n" + msg + "\n------------------------ < message end > --------------");
1087 // /* ---- RECEIVE ---- */
1089 // // Emulate reception
1090 // HttpMessage receivedMessage;
1092 // receivedMessage = HttpMessage.parse(msg, sentHttpMessage.getContentType());
1093 // } catch (Exception e) {
1094 // System.out.println("Failed to parse incoming message body");
1098 // if (receivedMessage.size() < 2) {
1099 // System.out.println("Request should have at least two parts");
1103 // // parse all request parts
1104 // java.util.Map<String,MessagePart> partsMap = receivedMessage.getParts();
1105 // Obj[] objects = new Obj[partsMap.size()];
1106 // String[] parts = new String[partsMap.size()];
1107 // int mainRequestIndex = -1;
1108 // Request mainRequest = null;
1111 // for (String partId : partsMap.keySet()) {
1112 // MessagePart part = partsMap.get(partId);
1113 // objects[mi] = Tools.toObj(part.getBody());
1114 // parts[mi] = part.getBody();
1115 // if (objects[mi] == null) {
1116 // System.out.println("No object returned when parsing the following part: " + parts[mi]);
1120 // if (partId.equals("Main")) {
1121 // // main Request found
1122 // if (objects[mi] instanceof Request) {
1123 // mainRequest = (Request)objects[mi];
1124 // mainRequestIndex = mi;
1126 // System.out.println("Main part should contain a Request object");
1133 // } catch (Exception e) {
1134 // System.out.println("Exception caught when parsing objects: " + e.getMessage());
1137 // if (mainRequest == null) {
1138 // System.out.println("No main Request found");
1142 // // now find the main transaction, which satisfies the following:
1143 // // (a) its id is not listed in main request as a sub-transaction
1144 // // (b) its seas id matches the main request seas id
1145 // Transaction mainTransaction = null;
1147 // // get contained transaction ids
1148 // Activity transactionIdActivity = mainRequest.getFirstActivity();
1149 // ArrayList<Variant> transactionIds = new ArrayList<Variant>();
1150 // ArrayList<String> transactionIdStrings = new ArrayList<String>(); // used for checking that transactions match
1151 // Parameter transactionIdParameter = new Parameter(); // needed for constructing the response
1152 // if (transactionIdActivity != null) {
1153 // ArrayList<Input> inputs = transactionIdActivity.getInputs();
1154 // for (Input ii : inputs) {
1155 // transactionIds = ii.get("transactions");
1156 // for (Variant v : transactionIds) {
1157 // transactionIdParameter.addValue(v);
1158 // transactionIdStrings.add(v.toString());
1162 // // verify that transaction ids match the contained transactions
1163 // // by going through all transactions and removing their ids from
1164 // // transactionIdStrings; they should all be there and list should
1165 // // be empty in the end
1166 // for (Obj o : objects) {
1167 // if (o instanceof Transaction) {
1168 // String transactionId = o.getIdentifierUri();
1169 // if (!transactionIdStrings.remove(transactionId)) {
1170 // // this transaction id was not in the request,
1171 // // so it could be the main transaction
1172 // Transaction t = (Transaction)o;
1173 // if (mainTransaction == null &&
1174 // t.hasNotarizedObject()) {
1175 // // transaction message id matches main request id, so this is indeed the main transaction
1176 // mainTransaction = (Transaction)o;
1178 // // this isn't the main transaction but its id
1179 // // cannot be found in the main request either
1180 // System.out.println("Transaction id " + transactionId + " is missing from the main request");
1187 // if (mainTransaction == null) {
1188 // System.out.println("Main transaction not found in the request");
1192 // // now all elements should have been removed from transactionIdStrings
1193 // if (transactionIdStrings.size() > 0) {
1194 // System.out.println("Main request contains " + transactionIds.size() + " unknown transaction ids");
1198 // // verify signatures in the two main parts
1200 // // request (message) signature
1201 // if (mainTransaction.hasNotarizedObject() && mainTransaction.getNotarizedObject().hasSignature()) {
1202 // String messageSignature = mainTransaction.getNotarizedObject().getSignature();
1203 // String messageHash = mainTransaction.getNotarizedObject().getHashCode();
1205 // if (!TransactionAgent.verifyTransactionHash(messageHash, parts[mainRequestIndex])) {
1206 // // invalid request signature!
1207 // System.out.println("Main request hash verification failed!");
1210 // if (!TransactionAgent.verifyTransactionSignature(messageSignature, pubKey, messageHash)) {
1211 // // invalid request signature!
1212 // System.out.println("Main request signature verification failed!");
1215 // System.out.println("Request signature verified");
1218 // System.out.println("Message signature not found");
1222 // // transaction signature
1223 // if (mainTransaction.hasNotarizedObject() && mainTransaction.getNotarizedObject().hasSignature()) {
1224 // String transactionSignature = mainTransaction.getNotarizedObject().getSignature();
1225 // String transactionHash = mainTransaction.getNotarizedObject().getHashCode();
1227 // if (!TransactionAgent.verifyTransactionSignature(transactionSignature, pubKey, transactionHash)) {
1228 // // invalid transaction signature!
1229 // System.out.println("Transaction signature verification failed!");
1232 // System.out.println("Transaction signature verified");
1235 // System.out.println("Transaction signature not found");
1238 // } catch (Exception e) {
1239 // System.out.println("Exception caught when verifying signatures: " + e.getMessage());
1244 public void routingAndEnergyRegistrationTest()
1246 String serverIdentity = "http://seasexamples.asema.com/api/Ctestserver";
1247 String serverName = "A sample charging plan calculation service";
1249 Service service = new Service(serverIdentity);
1252 Organization owner = new Organization();
1253 Address acmeAddress = new Address();
1254 InterfaceAddress iface = new InterfaceAddress();
1256 iface.setHost("www.acme.com");
1257 iface.setScheme("https");
1258 iface.setPath("/seas/v1.0e1.0/access");
1259 acmeAddress.setStreetAddress("Giant Rubber Band Street");
1260 acmeAddress.setZipCode("12345");
1261 acmeAddress.setCity("Fairfield, New Jersey");
1262 owner.setName("Acme Industries");
1263 owner.setAddress(acmeAddress);
1265 service.addInterface(iface);
1266 service.addOwner(owner);
1267 service.setName(serverName);
1268 service.setDescription("A charging plan service that supplies the available energy for charging in timeslots at a charging point.");
1269 service.addWebsite("http://www.acme.com/acmeoptimizers/roadrunner/beep/beep");
1273 Activity a = new Activity();
1274 Input i = new Input();
1275 Output o = new Output();
1278 service.addCapability(a);
1281 Map charge_need = new Map();
1282 charge_need.insert("Energy", Factory.createValueObject(NS.UNIT + "KilowattHour", "Total amount of energy requested to complete the charge."));
1283 charge_need.insert("PowerMax", Factory.createValueObject(NS.UNIT + "Watt", "Maximum allowed instant power for charging the vehicle."));
1284 charge_need.insert("PowerMin", Factory.createValueObject(NS.UNIT + "Watt", "Minumum allowed instant power for charging the vehicle."));
1285 charge_need.insert("Priority", new Obj(DATATYPE.INTEGER));
1286 charge_need.insert("Type", new Enumeration("Immediate", "Delayed"));
1287 TemporalContext tci = new TemporalContext();
1288 tci.setDescription("The desired schedule at which the charging should take place (start (optional) and end)");
1289 charge_need.insert("Schedule", tci);
1290 i.add("ChargingNeed", charge_need);
1293 Map charge_plan = new Map();
1294 ArrayList<Map> orders = new ArrayList<Map>();
1295 Map order = new Map();
1296 TemporalContext tco = new TemporalContext();
1297 tco.setDescription("The start and end times of this charging slot.");
1298 order.insert("Schedule", tco);
1299 order.insert("Power", Factory.createValueObject(NS.UNIT + "Watt", "The instant power supplied in this slot."));
1301 charge_plan.insert("Orders", orders);
1302 o.add("ChargingPlan", charge_plan);
1305 RegistrationAgent agent = new RegistrationAgent(serverIdentity);
1306 String payload = agent.generateRegistrationMessage(service).toTurtle();
1307 System.out.println(payload);
1310 public void hugeDataTest(int itemSize)
1312 System.out.println("Running HugeDataTest (data size: " + itemSize + ")");
1313 Date testStartTime = new Date();
1316 String myId = "http://seasdemos.asema.com/cplusplus/controlcommandsender/Cabcd";
1318 Date now = new Date();
1319 Calendar calendar = Calendar.getInstance();
1320 calendar.setTime(now);
1322 Response res = null;
1324 res = Factory.createResponse(myId);
1325 } catch (Exception e) {
1326 System.err.println("Exception while creating Response with ResponseFactory for " + myId + ".");
1327 printTestTime(testStartTime, "Test interrupted in");
1328 e.printStackTrace();
1330 res.setSameAs("http://hugedata.test");
1331 res.setName("Huge dataset test");
1332 res.setIdentifierUri("http://huge.data.uri");
1334 for ( int i = 0; i < itemSize; i++ ) {
1335 Evaluation ev = new Evaluation();
1336 ev.setValue(new Variant(i));
1337 ev.setInstant(calendar.getTime());
1338 calendar.add(Calendar.DATE, 1);
1339 res.add("http://evaluation.com", ev);
1341 printTestTime(testStartTime, "Time");
1344 System.out.println("Serializing data...");
1345 String stringData = Tools.toString(res, SERIALIZATION.TURTLE);
1346 printTestTime(testStartTime, "Time");
1349 System.out.println("Parsing back the serialized data...");
1350 Model model = Tools.fromString(stringData, SERIALIZATION.TURTLE);
1351 Resource resource = null;
1353 resource = Tools.getResourceByType(RESOURCE.RESPONSE, model);
1354 } catch (Exception e) {
1355 System.err.println("Exception while trying to get smartapi:Response resource from the model.");
1356 printTestTime(testStartTime, "Test interrupted in");
1357 e.printStackTrace();
1361 Response resParsed = Obj.parse(Response.class, resource);
1363 // test if list items are still there
1364 java.util.List<Variant> items = resParsed.get("http://evaluation.com");
1365 if ( items.size() != 0 ) {
1366 if ( items.size() == itemSize ) {
1367 System.out.println("HugeDataTest (data size: " + itemSize + ") passed.");
1368 printTestTime(testStartTime, "Test executed in");
1370 System.err.println("HugeDataTest (data size: " + itemSize + ") failed!");
1371 System.err.println("Size of serialized and parsed data is " + items.size() + ".");
1372 printTestTime(testStartTime, "Test executed in");
1375 System.err.println("HugeDataTest (data size: " + itemSize + ") failed!");
1376 System.err.println("Size of serialized and parsed data is 0.");
1377 printTestTime(testStartTime, "Test executed in");
1380 catch (NoSuchMethodException e) {}
1381 catch (InvocationTargetException e) {}
1384 public void fileInputTest(String fileName, String serialization)
1386 Obj o = Tools.fromFileAsObj(fileName, serialization);
1387 serializeParse(o, true);
1390 public void requestResponseTest1()
1392 String clientIdentity = "http://www.client.com/seas/Cclient";
1393 String serverIdentity = "http://www.server.com/seas/Cserver";
1396 * Test sequence 1, basic request / response
1398 System.out.println("\n\nREQUEST/RESPONSE, TEST 1");
1403 rc = Factory.createRequest(clientIdentity);
1404 } catch (Exception ex) {}
1405 rc.setMethod(RESOURCE.READ);
1406 Activity a = new Activity();
1407 Input i = new Input();
1409 i.setSystemOfInterestWithSameAs("http://a.com/b");
1412 ImmutablePair<String, String> serializedRequest = Tools.serializeRequest(rc, SERIALIZATION.TURTLE);
1413 System.out.println("REQUEST:\n" + serializedRequest.getLeft());
1416 Request rs = Tools.parseRequest(serializedRequest.getLeft(), serializedRequest.getRight());
1417 String clientId = rs.getGeneratedBy().toString();
1418 Activity aa = rs.getActivities().get(0);
1419 Input ii = aa.getInputs().get(0);
1420 System.out.println("Request, sys of interest " + ii.getSystemOfInterest().getSameAs().getIdentifierUri() + " from " + clientId);
1423 Response resp = null;
1425 resp = Factory.createResponse(serverIdentity);
1426 } catch (Exception ex) {}
1427 resp.setMethod(RESOURCE.READ);
1428 Activity ars = new Activity();
1429 Output ors = new Output();
1431 ors.setSystemOfInterestWithSameAs("http://a.com/b");
1432 resp.addActivity(ars);
1434 ImmutablePair<String, String> serializedResponse = Tools.serializeResponse(resp, SERIALIZATION.TURTLE);
1435 System.out.println("RESPONSE:\n" + serializedResponse.getLeft());
1438 Response respc = Tools.parseResponse(serializedResponse.getLeft(), serializedResponse.getRight());
1439 String serverId = respc.getGeneratedBy().toString();
1440 Activity ac = respc.getActivities().get(0);
1441 Output oc = ac.getOutputs().get(0);
1442 System.out.println("Response, sys of interest " + oc.getSystemOfInterest().getSameAs().getIdentifierUri() + " from " + serverId);
1445 public void requestResponseTest2()
1447 String clientIdentity = "http://www.client.com/seas/Cclient";
1448 String serverIdentity = "http://www.server.com/seas/Cserver";
1451 * Test sequence 2, request and response with an offer
1453 System.out.println("\n\nREQUEST/RESPONSE, TEST 2");
1458 rc = Factory.createRequest(clientIdentity);
1459 } catch (Exception ex) {}
1460 rc.setMethod(RESOURCE.READ);
1461 Activity a = new Activity();
1462 Input i = new Input();
1464 i.setSystemOfInterestWithSameAs("http://a.com/b");
1467 ImmutablePair<String, String> serializedRequest = Tools.serializeRequest(rc, SERIALIZATION.TURTLE);
1468 System.out.println("REQUEST:\n" + serializedRequest.getLeft());
1471 Request rs = Tools.parseRequest(serializedRequest.getLeft(), serializedRequest.getRight());
1472 String clientId = rs.getGeneratedBy().toString();
1473 Activity aa = rs.getActivities().get(0);
1474 Input ii = aa.getInputs().get(0);
1475 System.out.println("Request, sys of interest " + ii.getSystemOfInterest().getSameAs().getIdentifierUri() + " from " + clientId);
1478 Response resp = null;
1480 resp = Factory.createResponse(serverIdentity);
1481 } catch (Exception ex) {}
1482 resp.setMethod(RESOURCE.READ);
1484 Offering offering = new Offering("http://a.com/b#" + Crypto.generate16ByteCryptoRandomString(), "Test offer", "Test offer description");
1485 offering.setBusinessFunction(RESOURCE.SELL);
1487 PriceSpecification priceSpecification = new UnitPriceSpecification();
1488 priceSpecification.setCurrency("EUR");
1489 priceSpecification.setCurrencyValue(123);
1490 offering.addPriceSpecification(priceSpecification);
1491 SomeItems items = new SomeItems(RESOURCE.REQUEST, "Service request", "Any kind of service request.", serverIdentity);
1492 offering.addIncludes(items);
1494 aa.addOffering(offering);
1495 resp.addActivity(aa);
1497 ImmutablePair<String, String> serializedResponse = Tools.serializeResponse(resp, SERIALIZATION.TURTLE);
1498 System.out.println("RESPONSE:\n" + serializedResponse.getLeft());
1501 Response respc = Tools.parseResponse(serializedResponse.getLeft(), serializedResponse.getRight());
1502 String serverId = respc.getGeneratedBy().toString();
1503 Activity ac = respc.getActivities().get(0);
1504 Offering oc = ac.getOfferings().get(0);
1505 System.out.println("Response, offering at price " + oc.getPriceSpecification().get(0).getCurrencyValue());
1508 public void requestResponseTest3()
1510 String clientIdentity = "http://www.client.com/seas/Cclient";
1511 String serverIdentity = "http://www.server.com/seas/Cserver";
1513 SecretKey sessionKey = Crypto.generateSymmetricKey();
1516 * Test sequence 3, request and response with encrypted data
1518 System.out.println("\n\nREQUEST/RESPONSE, TEST 3");
1523 rc = Factory.createRequest(clientIdentity);
1524 } catch (Exception ex) {}
1525 rc.setMethod(RESOURCE.READ);
1526 Activity a = new Activity();
1527 Input i = new Input();
1529 i.setSystemOfInterestWithSameAs("http://a.com/b");
1532 System.out.println("---------explain()-----");
1534 System.out.println("---------turtlePrint()----------");
1536 System.out.println("-------------------");
1538 ImmutablePair<String, String> serializedRequest = Tools.serializeRequest(rc, SERIALIZATION.TURTLE);
1539 System.out.println("REQUEST:\n" + serializedRequest.getLeft());
1540 System.out.println("Request Content-Type: " + serializedRequest.getRight());
1543 Request rs = Tools.parseRequest(serializedRequest.getLeft(), serializedRequest.getRight());
1544 String clientId = rs.getGeneratedBy();
1545 Activity aa = rs.getActivities().get(0);
1546 Input ii = aa.getInputs().get(0);
1547 System.out.println("Request, sys of interest " + ii.getSystemOfInterest().getSameAs().getIdentifierUri() + " from " + clientId);
1550 Response resp = null;
1552 resp = Factory.createResponse(serverIdentity);
1553 } catch (Exception ex) {}
1554 resp.setMethod(RESOURCE.READ);
1555 Activity ars = new Activity();
1556 Output ors = new Output();
1558 ors.setSystemOfInterestWithSameAs("http://a.com/b");
1559 ors.encrypt(sessionKey);
1560 resp.addActivity(ars);
1562 ImmutablePair<String, String> serializedResponse = Tools.serializeResponse(resp, SERIALIZATION.TURTLE);
1563 System.out.println("RESPONSE:\n" + serializedResponse.getLeft());
1564 System.out.println("Reponse Content-Type: " + serializedResponse.getRight());
1567 Response respc = Tools.parseResponse(serializedResponse.getLeft(), serializedResponse.getRight());
1568 String serverId = respc.getGeneratedBy();
1569 Activity ac = respc.getActivities().get(0);
1570 Output oc = ac.getOutputs().get(0);
1571 oc.decrypt(sessionKey);
1572 System.out.println("Response, sys of interest " + oc.getSystemOfInterest().getSameAs().getIdentifierUri() + " from " + serverId);
1575 public void requestResponseTest4()
1577 String clientIdentity = "http://www.client.com/seas/Cclient";
1578 String serverIdentity = "http://www.server.com/seas/Cserver";
1580 PublicKey pubKey = null;
1581 PrivateKey privKey = null;
1585 pubKey = getPemPublicKey("testkey_public.pem", "RSA");
1586 privKey = getPemPrivateKey("testkey_private.pem", "RSA");
1587 } catch (Exception ex) {
1588 System.out.println("Could not find keys for the test.");
1589 System.out.println(ex);
1593 * Test sequence 4, request and response with signed data
1595 System.out.println("\n\nREQUEST/RESPONSE, TEST 4");
1600 rc = Factory.createRequest(clientIdentity);
1601 } catch (Exception ex) {}
1602 rc.setMethod(RESOURCE.READ);
1603 Activity a = new Activity();
1604 Input i = new Input();
1606 i.setSystemOfInterestWithSameAs("http://a.com/b");
1611 ImmutablePair<String, String> serializedRequest = Tools.serializeRequest(rc, SERIALIZATION.TURTLE);
1612 System.out.println("REQUEST:\n" + serializedRequest.getLeft());
1615 Request rs = Tools.parseRequest(serializedRequest.getLeft(), serializedRequest.getRight());
1618 String clientId = rs.getGeneratedBy();
1619 System.out.println("after parsing, we get GeneratedBy: "+ clientId);
1620 Activity aa = rs.getActivities().get(0);
1621 Input ii = aa.getInputs().get(0);
1622 System.out.println("Request, sys of interest " + ii.getSystemOfInterest().getSameAs().getIdentifierUri() + " from " + clientId);
1625 Response resp = null;
1627 resp = Factory.createResponse(serverIdentity);
1628 } catch (Exception ex) {}
1629 resp.setMethod(RESOURCE.READ);
1630 Activity ars = new Activity();
1631 Output ors = new Output();
1633 ors.setSystemOfInterestWithSameAs("http://a.com/b");
1635 resp.addActivity(ars);
1637 ImmutablePair<String, String> serializedResponse = Tools.serializeResponse(resp, SERIALIZATION.TURTLE);
1638 System.out.println("RESPONSE:\n" + serializedResponse.getLeft());
1641 Response respc = Tools.parseResponse(serializedResponse.getLeft(), serializedResponse.getRight());
1642 String serverId = respc.getGeneratedBy();
1643 Activity ac = respc.getActivities().get(0);
1644 Output oc = ac.getOutputs().get(0);
1645 boolean verified = false;
1647 verified = oc.verifySignature(pubKey);
1648 } catch (Exception e) {}
1649 System.out.println("Signature verification " + (verified ? "successful" : "failed") );
1650 System.out.println("Response, sys of interest " + oc.getSystemOfInterest()+ " from " + serverId);
1653 void notaryKeyStoreTest()
1655 String myId = "http://seas.test.asema.com/notarykeytest";
1656 String referenceId = "http://seas.test.asema.com/notarykeytest/ref1" + Crypto.generate16ByteCryptoRandomString();
1657 String 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.";
1658 // to make the content different during each run, otherwise test will fail
1659 content = content + Crypto.generate16ByteCryptoRandomString();
1661 PublicKey pubKey = null;
1662 PrivateKey privKey = null;
1664 pubKey = getPemPublicKey("testkey_public.pem", "RSA");
1665 privKey = getPemPrivateKey("testkey_private.pem", "RSA");
1666 } catch (Exception ex) {
1667 System.out.println("Could not find keys for the test.");
1668 System.out.println(ex);
1670 CryptoKeyWallet.setPublicKey(pubKey);
1671 CryptoKeyWallet.setPrivateKey(privKey);
1673 Base64.Encoder b64e = Base64.getEncoder();
1674 String notary = TransactionAgent.getDefaultNotary();
1675 SecretKey key = Crypto.generateSymmetricKey();
1676 String sessionKeySent = new String(b64e.encode(key.getEncoded()));
1677 String contentHash = Crypto.createEncodedMessageDigest(content);
1678 String signature = Crypto.sign(privKey, content);
1679 boolean sentOK = TransactionAgent.sendKeyToNotary(myId, referenceId, contentHash, sessionKeySent, signature, notary, privKey) != null;
1680 String sessionKeyReceived = TransactionAgent.fetchKeyFromNotary(myId, referenceId, contentHash, signature, notary, privKey);
1682 System.out.println("Sent ok: " + sentOK);
1683 System.out.println("Sent key: " + sessionKeySent);
1684 System.out.println("Received key: " + sessionKeyReceived);
1685 System.out.println("Keys match?: " + sessionKeyReceived.equals(sessionKeySent));
1688 void keyServerTest()
1690 String 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.";
1691 String keyId = "http://www.acme.com/services/abcd/";
1692 String publicKeyServer = "http://127.0.0.1:11371";
1693 PublicKey downloadedKey = Crypto.downloadPublicKey(keyId, publicKeyServer);
1694 PublicKey pubKey = null;
1695 PrivateKey privKey = null;
1697 pubKey = getPemPublicKey("testkey_public.pem", "RSA");
1698 privKey = getPemPrivateKey("testkey_private.pem", "RSA");
1699 } catch (Exception ex) {
1700 System.out.println("Could not find keys for the test.");
1701 System.out.println(ex);
1704 String signature = Crypto.sign(privKey, content);
1705 boolean verified = false;
1707 verified = Crypto.verifySignature(signature, pubKey, content);
1708 } catch (Exception e) {}
1709 System.out.println("Signature verification, key on disk " + (verified ? "successful" : "failed") );
1712 verified = Crypto.verifySignature(signature, downloadedKey, content);
1713 } catch (Exception e) {
1716 System.out.println("Signature verification, downloaded key " + (verified ? "successful" : "failed") );
1719 public boolean keyHandlingTest()
1721 System.out.println("Running keyHandlingTest..");
1723 ImmutablePair<String,String> keyPair = Tools.createCryptoKeys();
1724 System.out.println("public key: \n" + keyPair.getRight());
1725 System.out.println("private key: \n" + keyPair.getLeft());
1726 Tools.uploadPublicKey(keyPair.getRight(), "http://demo.smart-api.io/testkey", "test", "test", "http://127.0.0.1:11371");
1727 Tools.revokePublicKey("http://demo.smart-api.io/testkey", "test", "test", "http://127.0.0.1:11371");
1728 } catch ( Exception e ) {
1729 System.out.println("KeyHandlingTest failed.");
1730 e.printStackTrace();
1733 System.out.println("KeyHandlingTest passed.");
1738 void simpleHashTest()
1740 Base64.Decoder b64d = Base64.getDecoder();
1741 String r = "Simple hash input";
1742 String responseHash = Crypto.createEncodedMessageDigest(r);
1743 System.out.println("Hash for the text: " + responseHash);
1746 public void printTestTime(Date testStartTime, String text) {
1747 Date testEndTime = new Date();
1748 long testDuration = testEndTime.getTime() - testStartTime.getTime();
1749 long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(testDuration);
1750 long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(testDuration);
1751 long diffInHours = TimeUnit.MILLISECONDS.toHours(testDuration);
1752 if ( diffInSeconds != 0 ) {
1753 testDuration = testDuration - diffInSeconds*1000;
1755 if ( diffInMinutes != 0 ) {
1756 diffInSeconds = diffInSeconds - diffInMinutes*60;
1758 if ( diffInHours != 0 ) {
1759 diffInMinutes = diffInMinutes - diffInHours*60;
1761 System.out.println("\n" + text + ": " + (diffInHours != 0 ? (diffInHours + "h ") : "") +
1762 (diffInMinutes != 0 ? (diffInMinutes + "m ") : "") +
1763 (diffInSeconds != 0 ? (diffInSeconds + "s ") : "") +
1764 (testDuration != 0 ? (testDuration + "ms ") : "") + "\n");
1767 private void serializeReserialize(Obj o)
1769 Obj o_parsed = serializeParse(o, true);
1770 String reserialized = Tools.toString(o_parsed, SERIALIZATION.TURTLE);
1772 System.out.println("----");
1773 System.out.println("Re-serialized: " + reserialized);
1776 private Obj serializeParse(Obj o, boolean doPrint)
1778 String serialized = Tools.toString(o, SERIALIZATION.TURTLE);
1779 if (doPrint) System.out.println("Serialized: " + serialized);
1780 return Tools.fromStringAsObj(serialized, SERIALIZATION.TURTLE);
1784 * 1. Registers boiler device with an Offering for controlling its power.
1785 * 2. Shares boiler by creating Availability and using SharingAgent.
1786 * 3. Searches for available devices that can be controlled with reasonable price.
1787 * 4. Removes sharing.
1788 * 5. Searches again to confirm sharing removal.
1790 public boolean availabilityTest()
1792 System.out.println("Running TestSequence.testAvailability()");
1794 boolean testFailed = false;
1797 String myIdentity = "http://acme.com/boiler/C756fdg76dgfh4376dshg";
1798 String powerIdentifier = "/Cpower";
1799 String volumeIdentifier = "/Cvolume";
1800 String offeringIdentifier = "/Coffering";
1803 Device boiler = new Device(myIdentity);
1804 boiler.addType(RESOURCE.WATERBOILER);
1806 // info about energy consumption (power capacity)
1807 Capacity power = new Capacity(myIdentity + powerIdentifier);
1808 power.setSystemOfInterestWithType(RESOURCE.RESISTOR);
1809 power.setQuantity(RESOURCE.POWER);
1810 power.setUnit(RESOURCE.KILOWATT);
1811 power.setMaximum(new Variant(6));
1812 power.setStep(new Variant(3));
1813 power.setValue(new Variant(6));
1814 boiler.addCapacity(power);
1816 // info about water volume (volume capacity)
1817 Capacity volume = new Capacity(myIdentity + volumeIdentifier);
1818 volume.setSystemOfInterestWithType(RESOURCE.WATERTANK);
1819 volume.setQuantity(RESOURCE.VOLUME);
1820 volume.setUnit(RESOURCE.LITER);
1821 volume.setMaximum(new Variant(500));
1822 volume.setValue(new Variant(500));
1823 boiler.addCapacity(volume);
1825 // price for controlling on/off of this device
1826 Offering offering = new Offering(myIdentity + offeringIdentifier);
1827 boiler.addOffering(offering);
1828 PriceSpecification priceSpecification = new UnitPriceSpecification();
1829 priceSpecification.setGrName("Price to control this boiler");
1830 priceSpecification.setGrDescription("The amount in Euro to be paid for being able to control the two 3 kW resistors of this boiler for one hour.");
1831 priceSpecification.setCurrency("EUR");
1832 priceSpecification.setCurrencyValue(1.5);
1833 offering.addPriceSpecification(priceSpecification);
1834 SomeItems items = new SomeItems(RESOURCE.SERVICESUBSCRIPTION, "Service subscription", "Right to control this device for one hour.", null);
1835 items.setDuration(0, 0, 0, 1, 0, 0); // one hour
1836 offering.addIncludes(items);
1838 // activity for controlling this device
1839 Activity activity = new Activity();
1840 boiler.addCapability(activity);
1841 Input input = new Input();
1842 activity.addInput(input);
1843 input.addEntity(new Entity());
1844 Output output = new Output();
1845 activity.addOutput(output);
1846 output.addEntity(new Entity());
1848 // register boiler description (including offering)
1849 RegistrationAgent registrationAgent = new RegistrationAgent(myIdentity);
1850 registrationAgent.addEntity(boiler);
1851 Response response = registrationAgent.registrate();
1852 // print out possible errors on the response
1853 Tools.printErrors(response);
1854 // get response status
1855 if ( response.hasStatus() ) {
1856 Status status = response.getStatus();
1857 // check if the operation was successful
1858 if ( status.hasType(RESOURCE.ERROR) ) {
1859 System.out.println(" ..Registration failed.");
1862 System.out.println(" ..Registration successful. ");
1865 System.out.println(" ..No status found in response. Registration probably failed.");
1868 // create availability of the control of this boiler
1869 Availability availability = new Availability();
1870 // available from now on for two weeks
1871 Date now = new Date();
1872 availability.addAvailability(now, Tools.add(now, 0, 0, 14, 0, 0, 0));
1873 // available local time from 8 am to 4 pm and 1 am to 4 am (local time) on weekdays
1874 availability.addAvailability(Factory.createTimeFromLocalTimeString("08:00:00"), Factory.createTimeFromLocalTimeString("16:00:00"), RESOURCE.WEEKDAY);
1875 availability.addAvailability(Factory.createTimeFromLocalTimeString("01:00:00"), Factory.createTimeFromLocalTimeString("04:00:00"), RESOURCE.WEEKDAY);
1876 // available local time from 1 am to 9 am (local time) on weekends
1877 availability.addAvailability(Factory.createTimeFromLocalTimeString("01:00:00"), Factory.createTimeFromLocalTimeString("09:00:00"), RESOURCE.WEEKEND);
1878 // available in Finland
1879 availability.addAvailability(new Address("Finland", null, null, null));
1881 // share boiler with defined availability
1882 SharingAgent sharingAgent = new SharingAgent(myIdentity);
1884 * add authentication information
1886 String username = "senni";
1887 String password = "12345";
1889 // for now using HTTP basic authentication, i.e., using username:password combination.
1890 sharingAgent.setHTTPBasicAccessAuthenticationCredentials(username, password);
1893 boolean addAvailabilitySuccessful = sharingAgent.share(myIdentity, availability) != null;
1894 if ( !addAvailabilitySuccessful ) {
1895 System.out.println(" ..Adding availability failed.");
1898 System.out.println(" ..Adding availability successful. ");
1901 // search for available devices with power capacity..
1902 Entity entity = new Device();
1903 Capacity capacity = new Capacity();
1904 capacity.setQuantity(RESOURCE.POWER);
1905 entity.addCapacity(capacity);
1907 // ..that are available for control from now on for at least 3 hours..
1908 Availability av = new Availability();
1909 Date currentDateTime = new Date();
1910 av.setTemporalContext(currentDateTime, Tools.add(currentDateTime, 0, 0, 0, 3, 0, 0));
1912 // ..with maximum price of 1.8 euros per hour
1913 Offering offer = new Offering();
1914 PriceSpecification ps = new UnitPriceSpecification();
1915 ps.setCurrency("EUR");
1916 ps.setCurrencyValue(1.8);
1917 offer.addPriceSpecification(ps);
1918 SomeItems si = new SomeItems(RESOURCE.SERVICESUBSCRIPTION, null, null, null);
1919 si.setDuration(0, 0, 0, 1, 0, 0);
1920 offer.addIncludes(si);
1922 // SharingAgent searchAgent = new SharingAgent("http://acme.com/test/searcher");
1923 // boolean foundBoiler = false;
1924 // java.util.List<Entity> found = searchAgent.search(entity, av, offer);
1925 // for ( Entity e : found ) {
1926 // if ( boiler.getIdentifierUri().equals(e.getIdentifierUri()) ) {
1927 // foundBoiler = true;
1930 // if ( !foundBoiler ) {
1931 // System.out.println(" ..Error: could not find boiler using sharing agent!");
1932 // testFailed = true;
1934 // System.out.println(" ..Searching shared entity successful. ");
1937 // // remove sharing
1938 // boolean deregistrationSuccessful = sharingAgent.removeSharing(myIdentity);
1939 // if ( !deregistrationSuccessful ) {
1940 // System.out.println(" ..Removing availability failed.");
1942 // System.out.println(" ..Removing sharing successful. ");
1945 // // search again for available devices to make sure it is not found anymore
1946 // foundBoiler = false;
1947 // found = searchAgent.search(entity, av, offer);
1948 // for ( Entity e : found ) {
1949 // if ( boiler.getIdentifierUri().equals(e.getIdentifierUri()) ) {
1950 // foundBoiler = true;
1953 // if ( foundBoiler ) {
1954 // System.out.println(" ..Error: found boiler even though its sharing should be removed!");
1955 // testFailed = true;
1957 // System.out.println(" ..Confirmed removing sharing successful. ");
1960 // if ( testFailed ) {
1961 // System.out.println("TestSequence.testAvailability() FAILED");
1964 // System.out.println("TestSequence.testAvailability() passed");
1970 public void simpleSignatureVerificationTest()
1972 String signature = "r6mUVMZyGD//o7zFAttovTQwDxD3Wx/uvmDfTZTJQ2MZt9iQYaBHRMbFS4eY3O3erwf12T1v5KJR+CbbPyFvjNReoGVn6TUWNxe7mYf0Oqp38qxFnGDH2c/7wP/G1gqbAu3QConw2be7jCdWNV+YTaf28w4zB5S5O6Ig3J8OwAZdbTWjYMpWOtYzcZa4wPwDSO/QZ948mKEHSIOXcGqt1GZxn3cmFkwfkASr0hT//Y1PRZKUamZpXhViZZLeE0TfwhRhKcMyOzYk5Ht2kZKaKKETEZ4aMf6wKF6bMwG/ud70Z5X8DVBZ3uS7b8+kND3oYhQvAl/ayWSWaNvi18e4pA==";
1974 String 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.";
1976 PublicKey pubKey = null;
1977 PrivateKey privKey = null;
1979 pubKey = getPemPublicKey("testkey_public.pem", "RSA");
1980 privKey = getPemPrivateKey("testkey_private.pem", "RSA");
1981 } catch (Exception ex) {
1982 System.out.println("Could not find keys for the test.");
1983 System.out.println(ex);
1986 String refSignature = Crypto.sign(privKey, content);
1987 System.out.println("Reference signature: " + refSignature);
1988 System.out.println("Received signature: " + signature);
1990 boolean signedProperly = false;
1992 signedProperly = Crypto.verifySignature(signature, pubKey, content);
1993 } catch (Exception e) {}
1994 System.out.println("Signature test result: " + signedProperly);
1997 public void printLists()
1999 Calendar calendar = Calendar.getInstance();
2000 calendar.setTime(new Date());
2002 TimeSeries ts = new TimeSeries();
2005 smartapi.rdf.List testList = new OrderedList();
2006 for ( int i = 0; i < 3; i++ ) {
2007 Evaluation e = new Evaluation();
2008 e.setValue(new Variant(i));
2009 e.setInstant(calendar.getTime());
2010 calendar.add(Calendar.DATE, 1);
2011 testList.addItems(e);
2013 ts.setList(testList);
2014 System.out.println("\n-------- orderedlist! -----------\n");
2017 testList = new OrderedList();
2018 for ( int i = 0; i < 3; i++ ) {
2019 testList.addItems(i);
2021 ts.setList(testList);
2022 Evaluation baseObject = new Evaluation();
2023 baseObject.setQuantity(RESOURCE.ENERGYANDWORK);
2024 baseObject.setUnit(RESOURCE.KILOWATTHOUR);
2025 ts.setBaseObject(baseObject);
2026 ts.setTemporalContext(new TemporalContext(Tools.stringToDate("2017-02-17T15:30:50.000")));
2027 ts.setTimeStep("PT1S");
2031 testList = new LinkedList();
2032 for ( int i = 0; i < 3; i++ ) {
2033 Evaluation e = new Evaluation();
2034 e.setValue(new Variant(i));
2035 e.setInstant(calendar.getTime());
2036 calendar.add(Calendar.DATE, 1);
2037 testList.addItems(e);
2039 ts.setList(testList);
2040 System.out.println("\n-------- linkedlist! -----------\n");
2043 testList = new LinkedList();
2044 for ( int i = 0; i < 3; i++ ) {
2045 testList.addItems(i);
2047 ts.setList(testList);
2048 ts.setBaseObject(baseObject);
2049 ts.setTemporalContext(new TemporalContext(Tools.stringToDate("2017-02-17T15:30:50.000")));
2050 ts.setTimeStep("PT1S");
2051 System.out.println("\n--------also linkedlist! -----------\n");
2056 testList = new NudeList();
2057 for ( int i = 0; i < 3; i++ ) {
2058 Evaluation e = new Evaluation();
2059 e.setValue(new Variant(i));
2060 e.setInstant(calendar.getTime());
2061 calendar.add(Calendar.DATE, 1);
2062 testList.addItems(e);
2064 ts.setList(testList);
2065 System.out.println("\n-------- nudelist! -----------\n");
2068 testList = new NudeList();
2069 for ( int i = 0; i < 3; i++ ) {
2070 testList.addItems(i);
2072 ts.setList(testList);
2073 ts.setBaseObject(baseObject);
2074 ts.setTemporalContext(new TemporalContext(Tools.stringToDate("2017-02-17T15:30:50.000")));
2075 ts.setTimeStep("PT1S");
2079 testList = new ItemizedList();
2080 for ( int i = 0; i < 3; i++ ) {
2081 Evaluation e = new Evaluation();
2082 e.setValue(new Variant(i));
2083 e.setInstant(calendar.getTime());
2084 calendar.add(Calendar.DATE, 1);
2085 testList.addItems(e);
2087 ts.setList(testList);
2088 System.out.println("\n-------- itemizedlist! -----------\n");
2091 testList = new ItemizedList();
2092 for ( int i = 0; i < 3; i++ ) {
2093 testList.addItems(i);
2095 ts.setList(testList);
2096 ts.setBaseObject(baseObject);
2097 ts.setTemporalContext(new TemporalContext(Tools.stringToDate("2017-02-17T15:30:50.000")));
2098 ts.setTimeStep("PT1S");
2103 * Testing serialization and parsing of cross-linked objects
2106 public boolean serializeParseLoopTest()
2108 System.out.println("Running serializeParseLoopTest..");
2109 String rootId = "http://serializeParseLoopTest.test/root";
2110 String requestId = "http://serializeParseLoopTest.test/request";
2111 String entityId = "http://serializeParseLoopTest.test/entity";
2112 String rootProp = NS.SMARTAPI + "testPropertyRoot";
2113 String loopProp = NS.SMARTAPI + "testPropertyLoop";
2114 String selfRefProp = NS.SMARTAPI + "testPropertySelfRef";
2116 Entity root = new Entity(rootId);
2117 Request r = new Request(requestId);
2118 Entity e = new Entity(entityId);
2119 root.add(rootProp, r);
2121 r.newActivity().addEntity(e);
2123 // also make one link to self
2124 e.add(selfRefProp, e);
2126 String rdf = Tools.toString(root);
2127 System.out.println("serialization successful");
2129 System.out.println(rdf);
2131 Entity parsedRoot = (Entity)Tools.toObj(rdf);
2132 System.out.println("parsing successful");
2134 System.out.println(Tools.toString(parsedRoot));
2135 // test if content is still valid
2136 Request r2 = parsedRoot.getFirstAs(Request.class, rootProp);
2137 Entity e2 = r2.getFirstActivity().getEntities().get(0);
2138 if ( !(r2.getIdentifierUri().equals(e2.getFirstAs(Obj.class, loopProp).getIdentifierUri())) ) {
2139 System.out.println("serializeParseLoopTest FAILED!");
2142 if ( !(e2.getIdentifierUri().equals(e2.getFirstAs(Obj.class, selfRefProp).getIdentifierUri())) ) {
2143 System.out.println("serializeParseLoopTest FAILED!");
2146 System.out.println("content check successful");
2147 } catch ( Exception e ) {
2148 System.out.println("serializeParseLoopTest FAILED!");
2149 e.printStackTrace();
2152 System.out.println("serializeParseLoopTest passed");
2156 public boolean identifierManagementTest()
2158 System.out.println("Running identifierManagementTest..");
2159 String domain = "asema.com";
2160 String systemId = "iotc/123";
2161 String objId = "/obj%567&/>qwerty/";
2164 Entity e = new Entity(Tools.createIdentifierUri(domain, systemId, objId));
2165 System.out.println("identifier creation successful");
2167 String domain2 = e.getDomain();
2168 String systemId2 = e.getSystemIdentifier();
2169 String objId2 = e.getObjectIdentifier();
2170 String secondObjetcId = e.getObjectIdentifier(2);
2171 System.out.println("domain: " + domain2);
2172 System.out.println("systemId: " + systemId2);
2173 System.out.println("objectId: " + objId2);
2174 System.out.println("secondObjetcId: " + secondObjetcId);
2175 System.out.println("identifier partition successful");
2176 if ( domain.equals(domain2) ) {
2177 System.out.println("domain correct");
2179 System.err.println("domain match FAILED!");
2182 if ( systemId.equals(systemId2) ) {
2183 System.out.println("systemId correct");
2185 System.err.println("systemId match FAILED!");
2188 if ( objId.equals(objId2) ) {
2189 System.out.println("objId correct");
2191 System.err.println("objId match FAILED!");
2194 if ( secondObjetcId == null ) {
2195 System.out.println("secondObjetcId correct");
2197 System.err.println("secondObjetcId match FAILED!");
2200 } catch ( Exception e ) {
2201 e.printStackTrace();
2203 System.out.println("identifierManagementTest passed");
2207 public void readAndWriteObjectTest()
2209 System.out.println("Running readAndWriteObjectTest..");
2210 String domain = "asema.com";
2211 String systemId = "iotc123";
2212 String objId = "lamp";
2214 Device d = new Device(Tools.createIdentifierUri(domain, systemId, objId));
2216 InterfaceAddress itf = Factory.createInterface("http://asema.com:8082/smartapi/v1.0e1.0/access/nonstandard");
2218 ValueObject vo = new ValueObject(NS.SMARTAPI + "Brightness", RESOURCE.PERCENT, null, null, "smartapi:Actuator", "smartapi:Dimmer");
2219 d.addValueObject(vo);
2221 ValueObject vo2 = new ValueObject(NS.SMARTAPI + "Powered", DATATYPE.BOOLEAN, null, null, "smartapi:Actuator", "smartapi:PowerSwitch");
2222 d.addValueObject(vo2);
2224 ValueObject vo3 = new ValueObject(null, null, DATATYPE.STRING, "String message shown on lamp screen, use the lamp keyboard to change the message", "smartapi:Sensor");
2225 d.addValueObject(vo3);
2227 Activity aRead = Factory.createStandardReadActivity(itf, vo, vo2, vo3);
2228 d.addCapability(aRead);
2229 Activity aReadts = Factory.createStandardReadTimeSeriesActivity(itf, vo, vo2);
2230 d.addCapability(aReadts);
2231 Activity aWrite = Factory.createStandardWriteActivity(itf, vo, vo2);
2232 d.addCapability(aWrite);
2233 Activity aWritets = Factory.createStandardWriteTimeSeriesActivity(itf, vo);
2234 d.addCapability(aWritets);
2237 // debug print device description
2240 HttpClient client = new HttpClient();
2241 // enable debug mode to see printout of uri and request body
2242 client.debugMode(true);
2243 // just some random temporal context
2244 TemporalContext tcx = new TemporalContext(Tools.add(new Date(), 0, 0, 0, -6, 0, 0), new Date());
2246 // test call to read whole lamp device object
2247 client.getObject(d);
2248 // test call to read brightness value object time series data
2249 client.getValueObject(d, tcx, d.getFirstValueObjectByQuantity(NS.SMARTAPI + "Brightness"), d.getFirstValueObjectByQuantity((NS.SMARTAPI + "PowerOnState")));
2250 // test call to write time series data to lamp
2251 client.setObject(d, new TimeSeries());
2252 // test call to write brightness value
2253 d.getFirstValueObjectByQuantity(NS.SMARTAPI + "Brightness").setValue(80);
2254 client.setValueObject(d, d.getFirstValueObjectByQuantity(NS.SMARTAPI + "Brightness"));
2256 } catch ( Exception e ) {
2257 System.err.println("Exception in readAndWriteObjectTest. It is normal if it is caused by network problem because there is no server to actually respond for these requests.");
2258 e.printStackTrace();
2263 * See values changing by reloading page on browser:
2264 * http://seas.asema.com/webapps/SimpleRW/API/smartapi/v1.0e1.0/access
2267 public boolean standardRWtest()
2269 System.out.println("Running standard RW test against SimpleRW servlet...");
2271 // search for SimpleRW device, should find one
2272 for ( Entity e : SearchAgent.searchByNameAndType(SmartAPI.getMyIdentity(), 500, new String[]{"SimpleRW"}, new String[]{RESOURCE.DEVICE}) ) {
2277 ValueObject brightness = e.getFirstValueObjectByQuantity(NS.SMARTAPI + "Brightness");
2278 ValueObject powerOnState = e.getFirstValueObjectByQuantity(NS.SMARTAPI + "Powered");
2279 HttpClient client = new HttpClient();
2280 // enable debug mode to see printout of uri and request body
2281 //client.debugMode(true);
2282 int brightnessValue = 0;
2283 boolean powerValue = true;
2285 // fetch brightness value
2286 Entity updated = client.getValueObject(e, brightness).getEntities().get(0);
2287 brightnessValue = updated.getFirstValueObjectByQuantity(NS.SMARTAPI + "Brightness").getValueAsInt();
2288 //System.out.println("Read: " + brightnessValue);
2290 // set new brightness value
2291 if ( brightnessValue > 50 ) {
2292 brightnessValue = 30;
2294 brightnessValue = 80;
2297 // send new brightness value
2298 updated.getFirstValueObjectByQuantity(NS.SMARTAPI + "Brightness").setValue(brightnessValue);
2299 updated = client.setValueObject(e, updated.getFirstValueObjectByQuantity(NS.SMARTAPI + "Brightness")).getEntities().get(0);
2301 // fetch brightness value again to see if it changed correctly
2302 updated = client.getValueObject(e, brightness).getEntities().get(0);
2303 int newValue = updated.getFirstValueObjectByQuantity(NS.SMARTAPI + "Brightness").getValueAsInt();
2305 if ( brightnessValue != newValue ) {
2306 System.err.println("Standard RW test failed. Value (brightness) was not set correctly!");
2310 // fetch power on state value
2311 updated = client.getValueObject(e, powerOnState).getEntities().get(0);
2312 powerValue = updated.getFirstValueObjectByQuantity(RESOURCE.POWERED).getValueAsBoolean();
2314 // set new power on value
2315 powerValue = !powerValue;
2317 // send new power on state value
2318 updated.getFirstValueObjectByQuantity(RESOURCE.POWERED).setValue(powerValue);
2319 updated = client.setValueObject(e, updated.getFirstValueObjectByQuantity(RESOURCE.POWERED)).getEntities().get(0);
2321 // fetch power on state value
2322 updated = client.getValueObject(e, powerOnState).getEntities().get(0);
2323 boolean newPowerValue = updated.getFirstValueObjectByQuantity(RESOURCE.POWERED).getValueAsBoolean();
2325 if ( powerValue != newPowerValue ) {
2326 System.err.println("Standard RW test failed. Value (power on state) was not set correctly!");
2330 // note that all read timeseries are just generated, not real values and wrote timeseries values
2331 // are not followed by any actions on the server side
2333 // fetch brightness timeseries for the last 5 hours
2334 Date now = new Date();
2335 TimeSeries readBrightnessTS = null;
2337 readBrightnessTS = client.getValueObject(e, new TemporalContext(Tools.add(now, 0, 0, 0, -5, 0, 0), now), brightness).getTimeSeries().get(0);
2338 } catch ( Exception ex ) {
2339 System.err.println("Standard RW test failed. Error while fetching brightness timeseries!");
2343 // debug printing for comparing with the ts seen on browser ui
2344 System.out.println("Read brightness timeseries:");
2345 for ( int count = 0; count < readBrightnessTS.getListSize(); count++ ) {
2346 System.out.print(((ValueObject)readBrightnessTS.getListItem(count)).getValueAsInt() + " ");
2348 System.out.println("\n"); // line break
2350 if ( readBrightnessTS.getListSize() < 1 ) {
2351 System.err.println("Standard RW test failed. Error while fetching brightness timeseries! Zero items in returned list.");
2355 // fetch poweronstate timeseries for the last 5 hours
2356 TimeSeries readPowerOnStateTS = null;
2358 readPowerOnStateTS = client.getValueObject(e, new TemporalContext(Tools.add(now, 0, 0, 0, -5, 0, 0), now), powerOnState).getTimeSeries().get(0);
2359 } catch ( Exception ex ) {
2360 System.err.println("Standard RW test failed. Error while fetching brightness timeseries!");
2364 // debug printing for comparing with the ts seen on browser ui
2365 System.out.println("Read PowerOnState timeseries:");
2366 for ( int count = 0; count < readPowerOnStateTS.getListSize(); count++ ) {
2367 System.out.print(((ValueObject)readPowerOnStateTS.getListItem(count)).getValueAsBoolean() + " ");
2369 System.out.println("\n"); // line break
2371 if ( readPowerOnStateTS.getListSize() < 1 ) {
2372 System.err.println("Standard RW test failed. Error while fetching power on state timeseries! Zero items in returned list.");
2376 // send timeseries command (next 5 hours)
2377 Date end = Tools.add(now, 0, 0, 0, 5, 0, 0);
2378 TemporalContext tcx = new TemporalContext(now, end);
2379 TimeSeries ts = new TimeSeries();
2380 ts.setTemporalContext(tcx);
2382 ts.setList(new smartapi.rdf.OrderedList());
2383 // 1 hour timestep between data values
2384 Duration timeStep = Factory.createDuration(0, 0, 0, 1, 0, 0);
2385 ts.setTimeStep(timeStep.toString());
2386 Random rnd = new Random();
2387 Date currentDate = (Date)now.clone();
2388 ValueObject baseObject = (ValueObject)brightness.clone();
2389 baseObject.setValue((Variant)null);
2390 ts.setBaseObject(baseObject);
2391 while ( currentDate.before(end) ) {
2392 // list items as int
2393 ts.addListItem(rnd.nextInt(101));
2394 timeStep.addTo(currentDate);
2397 // debug printing for comparing with the ts seen on browser ui
2398 System.out.println("Wrote brightness timeseries:");
2399 for ( int count = 0; count < ts.getListSize(); count++ ) {
2400 System.out.print(((ValueObject)ts.getListItem(count)).getValueAsInt() + " ");
2402 System.out.println("\n"); // line break
2404 TimeSeries wroteBrightnessTS = null;
2406 wroteBrightnessTS = client.setValueObject(e, ts, brightness).getTimeSeries().get(0);
2407 } catch ( Exception ex ) {
2408 System.err.println("Standard RW test failed. Error while writing brightness timeserie!");
2412 if ( wroteBrightnessTS.getListSize() < 1 ) {
2413 System.err.println("Standard RW test failed. Error while writing brightness timeserie! Zero items in returned list.");
2417 System.out.println("Standard RW test passed.");
2421 public boolean UnitConversionTest()
2423 System.out.println("Running UnitConversionTest...");
2424 //SmartAPI.setValidationMode(ValidationMode.DONT_UPDATE);
2426 System.out.println("ENERGYPRICE from e/kWh to pound/MWh");
2427 ValueObject vo = new ValueObject(RESOURCE.CURRENCY, RESOURCE.EURO, RESOURCE.ENERGYANDWORK, RESOURCE.KILOWATTHOUR, 0.02);
2429 ValueObject vo2 = UnitConverter.convert(vo, RESOURCE.POUNDSTERLING, RESOURCE.WATTHOUR);
2431 if ( !vo2.getUnit().equals(RESOURCE.POUNDSTERLING) || !vo2.getSecondaryUnit().equals(RESOURCE.WATTHOUR) ||
2432 vo2.getValue().equals(new Variant(0.02)) ) {
2433 System.err.println("EnergyPrice conversion from e/kWh to pound/MWh failed!");
2437 System.out.println("ANGLE from radian to degree");
2438 ValueObject vo3 = new ValueObject(RESOURCE.PLANEANGLE, RESOURCE.RADIAN, 3.14159265);
2440 ValueObject vo4 = UnitConverter.convert(vo3, RESOURCE.DEGREEANGLE);
2442 if ( !vo4.getUnit().equals(RESOURCE.DEGREEANGLE) ||
2443 vo4.getValue().equals(new Variant(3.14159265)) ) {
2444 System.err.println("Angle conversion from radian to degree failed!");
2448 System.out.println("CURRENCY from euro to pound");
2449 ValueObject vo5 = new ValueObject(RESOURCE.CURRENCY, RESOURCE.EURO, 5);
2451 ValueObject vo6 = UnitConverter.convert(vo5, RESOURCE.POUNDSTERLING);
2453 if ( !vo6.getUnit().equals(RESOURCE.POUNDSTERLING) ||
2454 vo6.getValue().equals(new Variant(5)) ) {
2455 System.err.println("Currency conversion from euro to pound failed!");
2459 System.out.println("ENERGY CONSUMPTION from kWh/km to Wh/m");
2460 ValueObject vo7 = new ValueObject(RESOURCE.ENERGYANDWORK, RESOURCE.KILOWATTHOUR, RESOURCE.LENGTH, RESOURCE.KILOMETER, 8);
2462 ValueObject vo8 = UnitConverter.convert(vo7, RESOURCE.WATTHOUR, RESOURCE.METER);
2464 if ( !vo8.getUnit().equals(RESOURCE.WATTHOUR) || !vo8.getSecondaryUnit().equals(RESOURCE.METER) ||
2465 vo8.getValue().asInt() != 8 ) {
2466 System.err.println("Energy consumption conversion from kWh/km to Wh/m failed!");
2470 System.out.println("UnitConversionTest passed.");
2474 public boolean graphTests()
2476 GraphTests gt = new GraphTests();
2477 return gt.runTests();
2481 * Tests serialization and parsing of objects where signing has been done to multiple levels in objects,
2482 * resulting in several multipart objects
2484 public boolean recursiveMultipartTest()
2486 System.out.println("Running recursive multipart test...");
2487 PublicKey pubKey = null;
2488 PrivateKey privKey = null;
2489 Transaction transaction = null;
2493 pubKey = getPemPublicKey("testkey_public.pem", "RSA");
2494 privKey = getPemPrivateKey("testkey_private.pem", "RSA");
2495 transaction = Factory.createTransaction("http://www.my.org/sender");
2496 req = Factory.createRequest("http://www.my.org/me");
2497 } catch (Exception ex) {
2498 System.out.println("Could not find keys for the test.");
2499 System.out.println(ex);
2502 Entity e = new Entity("http://www.my.org/entity");
2503 Offering o = new Offering();
2507 transaction.setSigner("http://www.my.org/signer");
2508 transaction.setNotarizedObject(e);
2509 transaction.sign(privKey);
2511 Activity a = new Activity("http://www.my.org/activity");
2512 a.setTransaction(transaction);
2513 a.setMethod(RESOURCE.WRITE);
2518 // The data is now ready to be serialized into the message.
2519 ImmutablePair<String, String> serializedRequest = Tools.serializeRequest(req, SERIALIZATION.TURTLE);
2520 System.out.println("REQUEST:\n" + serializedRequest.getLeft());
2522 Request rr = Tools.parseRequest(serializedRequest.getLeft(), serializedRequest.getRight());
2523 System.out.println("Resulting Activity: " + rr.getFirstActivity());
2524 Transaction tt = (Transaction)rr.getFirstActivity().getTransaction();
2525 System.out.println("Resulting Transaction: " + tt);
2526 System.out.println("Resulting Object: " + tt.getNotarizedObject());
2527 System.out.println("Resulting Offerings: " + tt.getNotarizedObject().getOfferings());
2528 return tt.getNotarizedObject().getOfferings().size() > 0;
2531 public boolean conceptValidationTest()
2533 System.out.println("Running concept validation test...");
2536 Service s = new Service("http://concept.validation.test/");
2537 // add undefined concept
2538 s.addType(NS.SMARTAPI + "MyType");
2539 s.add(PROPERTY.METHOD, new Obj(RESOURCE.READ));
2540 // add illegal value type (string instead of resource)
2541 s.add(PROPERTY.METHOD, RESOURCE.READ);
2542 // add undefined concept
2543 s.add(PROPERTY.METHOD, new Obj(NS.SMARTAPI + "MyMethod"));
2544 // add undefined property
2545 s.add(NS.SMARTAPI + "myProp", "helloy");
2546 s.setName("Concept validation test Service ");
2547 s.setDescription("Sample service description for concept validation test.");
2548 s.setInterface(Factory.createStandardInterface("acme.com"));
2549 s.addCapability(Factory.createStandardReadActivity("http://acme.com/service/Cread"));
2552 Grading g = OntologyAgent.quickValidate(s);
2554 // check that there were errors
2555 if ( g.hasValueGrade() && g.getValueGrade().asDouble() < 10 && g.getValueGrade().asDouble() > 0 &&
2556 g.hasConceptGrade() && g.getConceptGrade().asDouble() < 10 && g.getConceptGrade().asDouble() > 0 &&
2557 g.hasGrade() && g.getGrade().asDouble() < 10 && g.getGrade().asDouble() > 0 ) {
2558 System.out.println("Concept validation test passed.");
2561 System.out.println("Concept validation test failed.");
2565 } catch ( Exception e ) {
2566 System.out.println("Exception in ConceptValidationTest.");
2567 e.printStackTrace();
2572 public boolean baseObjectTest()
2574 System.out.println("Running BaseObject test...");
2576 // test items as value of baseobjectproperty
2577 TimeSeries ts = new TimeSeries();
2578 smartapi.rdf.List list = new smartapi.rdf.OrderedList();
2579 ValueObject baseObject = new ValueObject();
2580 baseObject.setQuantity(NS.SMARTAPI + "Brightness");
2581 baseObject.setUnit(RESOURCE.PERCENT);
2582 list.setBaseObject(baseObject);
2583 list.setBaseObjectProperty(PROPERTY.MINIMUM);
2591 TimeSeries ts2 = (TimeSeries)Tools.serializeParse(ts);
2593 //ts2.turtlePrint();
2595 List list2 = ts2.getList();
2596 if ( ((ValueObject)list2.getItem(0)).getMinimum().asInt().intValue() != 1 ) {
2597 System.out.println("ValueObject->minimum should be 1.");
2598 System.out.println("ValueObject:");
2599 ((ValueObject)list2.getItem(0)).turtlePrint();
2600 System.out.println("BaseObjectTest failed.");
2603 // test object items without baseobjectproperty
2604 list = new smartapi.rdf.OrderedList();
2605 list.setBaseObject(baseObject);
2607 o.add(PROPERTY.MINIMUM, -1);
2608 o.add(PROPERTY.MAXIMUM, 1);
2611 o2.add(PROPERTY.MINIMUM, -2);
2612 o2.add(PROPERTY.MAXIMUM, 2);
2618 ts2 = (TimeSeries)Tools.serializeParse(ts);
2620 //ts2.turtlePrint();
2622 list2 = ts2.getList();
2623 if ( ((ValueObject)list2.getItem(0)).getMaximum().asInt().intValue() != 1 ) {
2624 System.out.println("ValueObject->maximum should be 1.");
2625 System.out.println("ValueObject:");
2626 ((ValueObject)list2.getItem(0)).turtlePrint();
2627 System.out.println("BaseObjectTest failed.");
2631 // test object items with baseobjectproperty
2632 list = new smartapi.rdf.OrderedList();
2633 list.setBaseObject(baseObject);
2634 list.setBaseObjectProperty(PROPERTY.OBJECT);
2636 o3.add(PROPERTY.MINIMUM, -1);
2637 o3.add(PROPERTY.MAXIMUM, 1);
2640 o4.add(PROPERTY.MINIMUM, -2);
2641 o4.add(PROPERTY.MAXIMUM, 2);
2647 ts2 = (TimeSeries)Tools.serializeParse(ts);
2649 //ts2.turtlePrint();
2651 list2 = ts2.getList();
2652 if ( ((ValueObject)list2.getItem(0)).getFirstAs(Obj.class, PROPERTY.OBJECT).getFirstAsVariant(PROPERTY.MAXIMUM).asInt().intValue() != 1 ) {
2653 System.out.println("ValueObject->maximum should be 1.");
2654 System.out.println("ValueObject:");
2655 ((ValueObject)list2.getItem(0)).turtlePrint();
2656 System.out.println("BaseObjectTest failed.");
2660 System.out.println("BaseObjectTest passed.");
2662 } catch ( Exception e ) {
2663 System.out.println("Exception in BaseObjectTest.");
2664 e.printStackTrace();
2669 public boolean fetchSharingsByOfferingTest()
2671 System.out.println("Running fetchSharingsByOfferingTest...");
2673 String myId = "http://fetch-sharings-by-offering-test.com";
2674 String entityIdSell = myId + "/device_i_want_to_sell";
2675 String entityIdBuy = myId + "/device_i_want_to_buy";
2677 // register entities to registry
2678 RegistrationAgent rAgent = new RegistrationAgent(myId);
2679 Device dSell = new Device(entityIdSell);
2680 Device dBuy = new Device(entityIdBuy);
2681 rAgent.addEntity(dSell);
2682 rAgent.addEntity(dBuy);
2683 rAgent.registrate();
2685 // create sell offering
2686 Offering sellOffering = new Offering("http://acme.com/serviceX/sell_offering");
2687 sellOffering.setBusinessFunction(RESOURCE.SELL);
2688 PriceSpecification readPriceSpecification = new UnitPriceSpecification();
2689 readPriceSpecification.setGrName("Price to subscribe to receive real-time values");
2690 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.");
2691 readPriceSpecification.setCurrency("EUR");
2692 readPriceSpecification.setCurrencyValue(0.05);
2693 sellOffering.addPriceSpecification(readPriceSpecification);
2694 // offer item is a one hour subscription for controlling
2695 SomeItems readItems = new SomeItems(RESOURCE.SERVICESUBSCRIPTION, "Service subscription", "Right to receive data values of this device for one day.", null);
2696 readItems.setDuration(0, 0, 1, 0, 0, 0);
2697 readItems.setMethod(RESOURCE.SUBSCRIBE);
2698 sellOffering.addIncludes(readItems);
2700 // create buy offering
2701 Offering buyOffering = new Offering("http://acme.com/serviceX/buy_offering");
2702 buyOffering.setBusinessFunction(RESOURCE.BUY);
2703 PriceSpecification readPriceSpecification2 = new UnitPriceSpecification();
2704 readPriceSpecification2.setGrName("Price to subscribe to receive real-time values");
2705 readPriceSpecification2.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.");
2706 readPriceSpecification2.setCurrency("EUR");
2707 readPriceSpecification2.setCurrencyValue(0.05);
2708 buyOffering.addPriceSpecification(readPriceSpecification2);
2709 // offer item is a one hour subscription for controlling
2710 SomeItems readItems2 = new SomeItems(RESOURCE.SERVICESUBSCRIPTION, "Service subscription", "Right to receive data values of this device for one day.", null);
2711 readItems2.setDuration(0, 0, 1, 0, 0, 0);
2712 readItems2.setMethod(RESOURCE.SUBSCRIBE);
2713 buyOffering.addIncludes(readItems2);
2715 // share: add one buy and one sell offering to an entity
2716 SharingAgent sAgent = new SharingAgent(myId);
2717 sAgent.setHTTPBasicAccessAuthenticationCredentials("senni", "12345");
2718 // create also availability for the entity if you wish
2719 Date now = new Date();
2720 Availability availability = new Availability(now, Tools.add(now, 0, 0, 14, 0, 0, 0));
2721 // share sell offering
2722 boolean success = sAgent.share(entityIdSell, availability, sellOffering) != null;
2724 System.out.println("FetchSharingsByOfferingTest FAILED to share entity with availability and offering.");
2727 // share buy offering
2728 success = sAgent.share(entityIdBuy, availability, buyOffering) != null;
2730 System.out.println("FetchSharingsByOfferingTest FAILED to share entity with availability and offering.");
2733 // fetch shared by me
2734 java.util.List<Entity> shared = sAgent.fetchSharings();
2735 if ( shared.size() != 2 ) {
2736 System.out.println("FetchSharingsByOfferingTest FAILED to fetch all shared entities. Shared 2, found " + shared.size() + ".");
2739 // create offering templates for searches
2740 Offering buyOfferingTemplate = new Offering();
2741 buyOfferingTemplate.setBusinessFunction(RESOURCE.BUY);
2742 Offering sellOfferingTemplate = new Offering();
2743 sellOfferingTemplate.setBusinessFunction(RESOURCE.SELL);
2745 // fetch my shared entities (sells)
2746 shared = sAgent.fetchSharings(sellOfferingTemplate);
2747 if ( shared.size() == 1 ) {
2748 if ( shared.get(0).getOfferings().get(0).getBusinessFunction().hasIdentifierUri(RESOURCE.SELL) ) {
2749 System.out.println("Sell offering found succesfully.");
2751 System.out.println("Sell offering search FAILED. Found entity is not sell offer.");
2755 System.out.println("Sell offering search FAILED. Found:");
2756 for ( Entity e : shared ) {
2762 // fetch entities I offer to buy (buys)
2763 shared = sAgent.fetchSharings(buyOfferingTemplate);
2764 if ( shared.size() == 1 ) {
2765 if ( shared.get(0).getOfferings().get(0).getBusinessFunction().hasIdentifierUri(RESOURCE.BUY) ) {
2766 System.out.println("Buy offering found succesfully.");
2768 System.out.println("Buy offering search FAILED. Found entity is not sell offer.");
2772 System.out.println("Buy offering search FAILED. Found:");
2773 for ( Entity e : shared ) {
2780 sAgent.removeSharings();
2781 rAgent.deRegistrate();
2782 System.out.println("fetchSharingsByOfferingTest finished succesfully.");
2786 public boolean blankEntityAndOfferingTest()
2788 System.out.println("Running blankEntityAndOfferingTest...");
2790 String myId = "http://blank-entity-and-offering-test.com";
2792 Entity entity = new Entity();
2794 // create sell offering
2795 Offering sellOffering = new Offering();
2796 sellOffering.setBusinessFunction(RESOURCE.SELL);
2797 entity.addOffering(sellOffering);
2799 // create buy offering
2800 Offering buyOffering = new Offering();
2801 buyOffering.setBusinessFunction(RESOURCE.BUY);
2802 entity.addOffering(buyOffering);
2804 // share: add one buy and one sell offering to an entity
2805 SharingAgent sAgent = new SharingAgent(myId);
2806 sAgent.setHTTPBasicAccessAuthenticationCredentials("senni", "12345");
2807 // share sell offering
2808 Entity ret = sAgent.share(entity);
2809 if ( ret == null ) {
2810 System.out.println("BlankEntityAndOfferingTest FAILED as share returned null.");
2813 if ( ret.hasIdentifierUri() ) {
2814 if ( ret.hasOffering() ) {
2815 boolean sellFound = false;
2816 boolean buyFound = false;
2817 for ( Offering o : ret.getOfferings() ) {
2818 if ( o.hasIdentifierUri() ) {
2819 if ( o.hasBusinessFunction() ) {
2820 if ( o.getBusinessFunction().getIdentifierUri().equals(RESOURCE.SELL) ) {
2823 if ( o.getBusinessFunction().getIdentifierUri().equals(RESOURCE.BUY) ) {
2827 System.out.println("BlankEntityAndOfferingTest FAILED as share returned offering without business function.");
2831 System.out.println("BlankEntityAndOfferingTest FAILED as share returned offering without identifier.");
2836 System.out.println("BlankEntityAndOfferingTest FAILED as share returned entity without sell offering.");
2840 System.out.println("BlankEntityAndOfferingTest FAILED as share returned entity without buy offering.");