linksmart / historical-datastore Goto Github PK
View Code? Open in Web Editor NEWLightweight time-series storage on the Edge of IoT
License: Apache License 2.0
Lightweight time-series storage on the Edge of IoT
License: Apache License 2.0
Discuss and improve the simplified API:
https://docs.linksmart.eu/display/HDS/Simplified+SensorThings+API
Don't like the new name? Visit: https://docs.linksmart.eu/display/LSI/OGC+SersorThings+Service+Candidates
Considering the status of current OGC-ST implementations and the complexity of creating another fully-compliant OGC-ST service, we would like to propose the use of OGC-ST data model alongside a custom and simplified RESTful API. This task will focus on creating OpenAPI specs for the aforementioned service.
[LS-200] created by tavakoli[LS-255] created by carvajal
Also aggregation?
[LS-483] created by tavakoliCritical TODOs:
And return appropriate errors!
[LS-484] created by tavakoli
[LS-336] created by jannis.warnat
[LS-123] created by marco.jahn
HDS needs an end-to-end integration test to avoid issues such as LS-379
DoD:
[LS-286] created by carvajal
It is much more convenient to start submitting SenML data without the need to register data sources beforehand.
An optional configurable feature can enable automatic registration of data source upon first submission of a SenML entry.
[LS-248] created by tavakoliBroker-based resource(thing) and service registration.
Related to:
https://docs.linksmart.eu/display/LSI/2017/10/10/Broker-based+Dataflow+Proposal
[LS-482] created by tavakoli
[LS-475] created by tavakoli
Jannis Warnat: when I register resources in HDS that require a password for the MQTT broker, these passwords are not stored in LevelDB (only *****). Do you know whether there was a conscious decision to do so for security reasons or can I change this? I understand that we probably do not want users to see the password by just checking the /registry endpoint. But it would be much easier if HDS could retrieve the passwords from LevelDB after a restart. I guess I would have to analyze where the json is "marshalled".
[LS-350] created by tavakoliAfter the Broker fails all components must re-send their registration info.
This task may be split several tasks or a sub-task per component must be created.
Deleting measurements and retention policies sometimes create error messages like this:
Error deleting data source: Error removing historical data: Statement error: shard 1: engine is closed
Todo:
Sample code: https://github.com/eclipse/paho.mqtt.golang/blob/master/cmd/ssl/main.go
[LS-307] created by tavakoliCompliance to OGCSensorThings > =1.0: IoT Device Gateway, Resource Catalogue, IoT Agents, Historicla Datastore, Sensor Platform
[LS-107] created by marco.jahnToDo:
[LS-479] created by tavakoli
[LS-373] created by tavakoli
DOD :
[LS-279] created by devasya
Create Swagger specification (either inside components or external)
[LS-109] created by marco.jahnDoD:
A specification for MQTT apis is defined
[LS-234] created by devasyaThis issue is created to support Web of things Things description specification for storage of the metadata.
Example
{
"@context": "https://www.w3.org/2019/wot/td/v1",
"id": "urn:dev:ops:32473-WoTTemp-1234",
"title": "MyLampThing",
"securityDefinitions": {
"basic_sc": {"scheme": "basic", "in":"header"}
},
"security": ["basic_sc"],
"base": "/data/",
"properties": {
"source" : {
"type": "float",
"forms": [{
"href": "https://gw1.iot/status",
"contentType": "application/senml+json",
"op": ["readproperty", "writeproperty"],
"security": ["basic_sc"]
}],
},
"storage" : {
"readOnly" : true,
"type": "float",
"forms": [{"href": "/data/urn:dev:ops:32473-WoTTemp-1234","security": ["basic_sc"]}]
}
}
}
In the above example. properties/source
property represents the original device that produced the data. On the other hand, properties/storage
represents the data stored as part of historical datastore.
The sample senml:
[
{"bn":"urn:dev:ops:32473-WoTTemp-1234","bu":"Cel","t":1.276020076e+09, "v":20},
{"t":1.276020091e+09, "v":23.5},
]
How it is now:
{ "bn": "string", "bu": "string", "bts": "int", "bte": "int", "e": [ { "n": "string", "ts": "int", "te": "int", "mean": "float", "stddev": "float", "sum": "float", "min": "float", "max": "float", "median": "float" } ] }
The aggregate could be instead part of the name. "te" is not needed. The rest can fit into SenML.
[LS-485] created by tavakoliToDo:
A wiki page comparing OGC sensorthings servers (FROST and GOST ) is prepared
[LS-291] created by devasyaThis should allow submission of data to /data endpoint without explicitly providing the ID. The ID will be retrieved based on the SenML name field.
[LS-247] created by tavakoliHistorical Datastore should be improved to support expected use-cases with simple and pragmatic APIs.
Use cases:
Features:
[LS-446] created by tavakoli
When two measurements are published together with the same topic in a single SenML message, HDS only subscribes once. If one of the measurements are not registered, the message will be dropped completely resulting in loss of both measurements.
[LS-374] created by tavakoli[LS-112] created by marco.jahn
To optimize the backend and fix race condition issue between data and aggregation storages, retention policies can be instead configured prior to runtime and created during startup. The datasources then will only be able to use the preconfigured retention policies.
[LS-346] created by tavakoli2018/08/10 09:45:05 [hds] PANIC: runtime error: index out of range goroutine 11212 [running]: runtime/debug.Stack(0xc420290f18, 0x9546c0, 0xd2add0) /usr/local/go/src/runtime/debug/stack.go:24 +0xa7 main.recoverHandler.func1.1(0x7fe05de67670, 0xc420a9e140) /data/src/code.linksmart.eu/hds/historical-datastore/handlers.go:31 +0x5a panic(0x9546c0, 0xd2add0) /usr/local/go/src/runtime/panic.go:502 +0x229 code.linksmart.eu/hds/historical-datastore/data.(*InfluxStorage).Query(0xc420133300, 0x0, 0xe7791f700, 0xd3c7a0, 0x39232b9b, 0xed2ff55a1, 0x0, 0x9fa41c, 0x4, 0xffffffffffffffff, ...) /data/src/code.linksmart.eu/hds/historical-datastore/data/influxdb.go:191 +0x13b1 code.linksmart.eu/hds/historical-datastore/data.(*HTTPAPI).Query(0xc42019acc0, 0x7fe05de67670, 0xc420a9e140, 0xc420105f00) /data/src/code.linksmart.eu/hds/historical-datastore/data/http.go:301 +0x702 code.linksmart.eu/hds/historical-datastore/data.(*HTTPAPI).Query-fm(0x7fe05de67670, 0xc420a9e140, 0xc420105f00) /data/src/code.linksmart.eu/hds/historical-datastore/main.go:155 +0x48 net/http.HandlerFunc.ServeHTTP(0xc42015bc50, 0x7fe05de67670, 0xc420a9e140, 0xc420105f00) /usr/local/go/src/net/http/server.go:1947 +0x44 main.commonHeaders.func1(0x7fe05de67670, 0xc420a9e140, 0xc420105f00) /data/src/code.linksmart.eu/hds/historical-datastore/router.go:65 +0x195 net/http.HandlerFunc.ServeHTTP(0xc4201af820, 0x7fe05de67670, 0xc420a9e140, 0xc420105f00) /usr/local/go/src/net/http/server.go:1947 +0x44 main.recoverHandler.func1(0x7fe05de67670, 0xc420a9e140, 0xc420105f00) /data/src/code.linksmart.eu/hds/historical-datastore/handlers.go:35 +0x95 net/http.HandlerFunc.ServeHTTP(0xc4201af840, 0x7fe05de67670, 0xc420a9e140, 0xc420105f00) /usr/local/go/src/net/http/server.go:1947 +0x44 main.loggingHandler.func1(0xa6f040, 0xc4201362a0, 0xc420105f00) /data/src/code.linksmart.eu/hds/historical-datastore/handlers.go:21 +0x236 net/http.HandlerFunc.ServeHTTP(0xc4201af860, 0xa6f040, 0xc4201362a0, 0xc420105f00) /usr/local/go/src/net/http/server.go:1947 +0x44 code.linksmart.eu/hds/historical-datastore/vendor/github.com/gorilla/context.ClearHandler.func1(0xa6f040, 0xc4201362a0, 0xc420105f00) /data/src/code.linksmart.eu/hds/historical-datastore/vendor/github.com/gorilla/context/context.go:141 +0x8b net/http.HandlerFunc.ServeHTTP(0xc4201af880, 0xa6f040, 0xc4201362a0, 0xc420105f00) /usr/local/go/src/net/http/server.go:1947 +0x44 code.linksmart.eu/hds/historical-datastore/vendor/github.com/gorilla/mux.(*Router).ServeHTTP(0xc4201a8370, 0xa6f040, 0xc4201362a0, 0xc420105f00) /data/src/code.linksmart.eu/hds/historical-datastore/vendor/github.com/gorilla/mux/mux.go:114 +0xdc net/http.serverHandler.ServeHTTP(0xc420152820, 0xa6f040, 0xc4201362a0, 0xc420104d00) /usr/local/go/src/net/http/server.go:2694 +0xbc net/http.(*conn).serve(0xc4203acf00, 0xa70c40, 0xc42043a440) /usr/local/go/src/net/http/server.go:1830 +0x651 created by net/http.(*Server).Serve /usr/local/go/src/net/http/server.go:2795 +0x27b 2018/08/10 09:45:05 [hds] "GET /data/05bf9f68-96ac-40fb-be1c-35ff375d5583?page=22 HTTP/1.1" 500 22 19.464926ms
The openapi spec describes /registry/
{path}/{op}/{value} and gives an invalid example (copies from SC?). The implementation expects /registry/{type}/{path}/
{op}/
{value}.
[LS-304] created by tavakoliThe default configuration of HDS is not working
DoD:
HDS docker image runs without issues
Binary distributions should be build with Travis and published along releases.
Datasource v0.5
{ "id": "9b1921c1-b20f-496a-a127-b5a01f0a91a5", "url": "/registry/9b1921c1-b20f-496a-a127-b5a01f0a91a5", "data": "/data/9b1921c1-b20f-496a-a127-b5a01f0a91a5", "resource": "13/0/49/4/power", "meta": { "name": "Philip's laptop" }, "connector": { "mqtt": { "url": "ssl://demo.linksmart.eu:8883", "topic": "LS/v2/ZGW/linksmart-philip/senml", "qos": 1 } }, "retention": "1w", "aggregation": [ { "id": "4efaf6fb", "interval": "1m", "data": "/aggr/4efaf6fb/9b1921c1-b20f-496a-a127-b5a01f0a91a5", "aggregates": [ "mean" ], "retention": "" } ], "type": "float", "format": "application/senml+json" }
Problems
[LS-447] created by tavakoli
[LS-481] created by tavakoli
Because of this bug, every time the retention period is changed, HDS will just switch to a new measurement under the new period in influx without moving the data.
[LS-372] created by tavakoliAgree or update the LinkSmart specs in https://docs.linksmart.eu/pages/viewpage.action?pageId=5570896
[LS-253] created by carvajalfor more see https://docs.linksmart.eu/display/LSI/Data+Flow+Proposal
[LS-188] created by carvajalThe filtering API of HDS can be simplified by removing the {type} and taking the /many behaviour as default. The efficiency effects should be considered.
[LS-430] created by tavakoli
[LS-480] created by tavakoli
The go package name should be changed from code.linksmart.eu/hds/historical-datastore to github.com/linksmart/historical-datastore.
[LS-371] created by tavakoli
[LS-249] created by tavakoli
Supporting aggregation function in HDS:
DoD:
A registry API has nextLink way of pagination
[LS-493] created by devasyaCreating integration tests between the Service Catalog and each Linksmart® Service
[LS-254] created by carvajalA declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.