#Overview
This project provides a REST interface to execute queries on the databuffer.
Requirements
This project requires Java 8 or greater.
Deployment
Use the instructions provided by ch.psi.daq.install to install the application on a server.
Application Properties
Following files define and describe application properties:
- Cassandra specific properties.
- Query specific properties..
- Query REST specific properties.
It is possible to overwrite properties by defining new values in ${HOME}/.config/daq/queryrest.properties
REST Interface
Query Channel Names
Request
POST http://<host>:<port>/channels
Data
{"regex": "TRFCA|TRFCB", "dbMode": "databuffer"}
Explanation
- regex: Reqular expression used to filter channel names (default: no filtering). Filtering is done using JAVA's Pattern, more precisely Matcher.find()).
- dbMode: Defines the database to access (values: databuffer|archiverappliance)
Example
curl -H "Content-Type: application/json" -X POST -d '{"regex": "TRFCA|TRFCB"}' http://sf-nube-14.psi.ch:8080/channels
Query Data
Request
GET http://<host>:<port>/query
Data
A request is performed using JSON. The JSON query defines the channels to be queried, the range, and how the data should be aggregated (this is optional but highly recommended).
There exist following fields:
- channels: Array of channel names to be queried.
- startPulseId and endPulseId : A pulse-id range request with start and end pulse-id.
- startMillis/[startNanos] and endMillis/[endNanos]: A time range request with start and end milliseconds since January 1, 1970 (the UNIX/JAVA epoch) and optionally supplemented with the nanosecond offset to the milliseconds (range [0..999999]).
- startDate/[startNanos] and endDate/[endNanos]: A time range request with start and end date (format yyyy/MM/dd HH:mm:ss.SSS or dd.MM.yyyy HH:mm:ss.SSS) and optionally supplemented with the nanosecond offset to the milliseconds (range [0..999999]).
- ordering: The ordering of the data (see here for possible values).
- fields: The requested fields (see here for possible values).
- nrOfBins: Activates data binning. Specifies the number of bins the pulse/time range should be devided into.
- binSize: Activates data binning. Specifies the number of pulses per bin for pulse-range queries or the number of milliseconds per bin for time-range queries.
- aggregations: Activates data aggregation. Array of requested aggregations (see here for possible values). These values will be added to the data array response.
- aggregationType: Specifies the type of aggregation (see here). The default type is value aggregation (e.g., sum([1,2,3])=6). Alternatively, it is possible to define index aggregation for multiple arrays in combination with binning (e.g., sum([1,2,3], [3,2,1]) = [4,4,4]).
- aggregateChannels: Specifies whether the data of the requested channels should be combined together using the defined aggregation (values: true|false)
- dbMode: Defines the database to access (values: databuffer|archiverappliance)
Example
curl -H "Content-Type: application/json" -X POST -d '{"channels":["channel1","channel2"],"startPulseId":0,"endPulseId":4}' http://sf-nube-14.psi.ch:8080/query
Response example
The response is in JSON.
[
{
"channel":"channel1",
"data":[
{
"pulseId":0,
"iocMillis":0,
"iocNanos":0,
"globalMillis":0,
"globalNanos":0,
"value":0
},
{
"pulseId":2,
"iocMillis":2,
"iocNanos":2,
"globalMillis":2,
"globalNanos":2,
"value":2
},
{
"pulseId":4,
"iocMillis":4,
"iocNanos":4,
"globalMillis":4,
"globalNanos":4,
"value":4
}
]
},
{
"channel":"channel2",
"data":[
{
"pulseId":1,
"iocMillis":1,
"iocNanos":1,
"globalMillis":1,
"globalNanos":1,
"value":1
},
{
"pulseId":3,
"iocMillis":3,
"iocNanos":3,
"globalMillis":3,
"globalNanos":3,
"value":3
}
]
}
]
Example Queries
Following examples build on a waveform data (see below). They also work for scalars (consider it as a waveform of length = 1) and images (waveform of length = dimX * dimY).
[
{
"channel":"Channel_01",
"data":[
{
"iocMillis":0,
"iocNanos":0,
"pulseId":0,
"globalMillis":0,
"globalNanos":0,
"shape":[
4
],
"value":[
1,
2,
3,
4
]
},
{
"iocMillis":10,
"iocNanos":0,
"pulseId":1,
"globalMillis":10,
"globalNanos":0,
"shape":[
4
],
"value":[
2,
3,
4,
5
]
},
{
"iocMillis":20,
"iocNanos":0,
"pulseId":2,
"globalMillis":20,
"globalNanos":0,
"shape":[
4
],
"value":[
3,
4,
5,
6
]
},
{
"iocMillis":30,
"iocNanos":0,
"pulseId":3,
"globalMillis":30,
"globalNanos":0,
"shape":[
4
],
"value":[
4,
5,
6,
7
]
}
]
}
]
Query Examples
Query by Pulse-Id Range
{
"startPulseId":0,
"endPulseId":3,
"channels":[
"Channel_01"
]
}
Command
curl -H "Content-Type: application/json" -X POST -d '{"startPulseId":0,"endPulseId":3,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
See JSON representation of the data above.
Query by Time Range
{
"startMillis":0,
"startNanos":0,
"endMillis":30,
"endNanos":999999,
"channels":[
"Channel_01"
]
}
Command
curl -H "Content-Type: application/json" -X POST -d '{"startMillis":0,"startNanos":0,"endMillis":30,"endNanos":999999,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
See JSON representation of the data above.
Query by Date Range
{
"startDate":"1970/01/01 01:00:00.000",
"startNanos":0,
"endDate":"1970/01/01 01:00:00.030",
"endNanos":999999,
"channels":[
"Channel_01"
]
}
Supported formats: yyyy/MM/dd HH:mm:ss.SSS and dd.MM.yyyy HH:mm:ss.SSS
Command
curl -H "Content-Type: application/json" -X POST -d '{"startDate":"1970/01/01 01:00:00.000","startNanos":0,"endDate":"1970/01/01 01:00:00.030","endNanos":999999,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
See JSON representation of the data above.
Querying Archiver Appliance
{
"dbmode":"archiverappliance",
"startMillis":0,
"startNanos":0,
"endMillis":30,
"endNanos":999999,
"channels":[
"Channel_01"
]
}
Archiver Appliance supports queries by time range and date range only (as it has no notion about pulse-id).
Command
curl -H "Content-Type: application/json" -X POST -d '{"dbmode":"archiverappliance","startMillis":0,"startNanos":0,"endMillis":30,"endNanos":999999,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
See JSON representation of the data above.
Querying for Specific Fields
Allows for server side optimizations since not all data needs to be retrieved.
{
"fields":["pulseId","value"]
"startPulseId":0,
"endPulseId":3,
"channels":[
"Channel_01"
]
}
Command
curl -H "Content-Type: application/json" -X POST -d '{"fields":["pulseId","value"],"startPulseId":0,"endPulseId":3,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
[
{
"channel":"Channel_01",
"data":[
{
"pulseId":0,
"value":[
1,
2,
3,
4
]
},
{
"pulseId":1,
"value":[
2,
3,
4,
5
]
},
{
"pulseId":2,
"value":[
3,
4,
5,
6
]
},
{
"pulseId":3,
"value":[
4,
5,
6,
7
]
}
]
}
]
Data Ordering
{
"ordering":"desc",
"fields":["pulseId","value"]
"startPulseId":0,
"endPulseId":3,
"channels":[
"Channel_01"
]
}
Use none in case ordering does not matter (allows for server side optimizations).
Command
curl -H "Content-Type: application/json" -X POST -d '{"ordering":"desc","fields":["pulseId","value"],"startPulseId":0,"endPulseId":3,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
[
{
"channel":"Channel_01",
"data":[
{
"pulseId":3,
"value":[
4,
5,
6,
7
]
},
{
"pulseId":2,
"value":[
3,
4,
5,
6
]
},
{
"pulseId":1,
"value":[
2,
3,
4,
5
]
},
{
"pulseId":0,
"value":[
1,
2,
3,
4
]
}
]
}
]
Value Aggregation
{
"aggregationType":"value",
"aggregations":["min","max","mean"],
"fields":["pulseId","value"]
"startPulseId":0,
"endPulseId":3,
"channels":[
"Channel_01"
]
}
Command
curl -H "Content-Type: application/json" -X POST -d '{"aggregationType":"value","aggregations":["min","max","mean"],"fields":["pulseId","value"],"startPulseId":0,"endPulseId":3,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
[
{
"channel":"Channel_01",
"data":[
{
"pulseId":0,
"value":{
"min":1.0,
"max":4.0,
"mean":2.5
}
},
{
"pulseId":1,
"value":{
"min":2.0,
"max":5.0,
"mean":3.5
}
},
{
"pulseId":2,
"value":{
"min":3.0,
"max":6.0,
"mean":4.5
}
},
{
"pulseId":3,
"value":{
"min":4.0,
"max":7.0,
"mean":5.5
}
}
]
}
]
Array value aggregations.
Value Aggregation with Binning
{
"nrOfBins":2,
"aggregationType":"value",
"aggregations":["min","max","mean"],
"fields":["pulseId","value"]
"startPulseId":0,
"endPulseId":3,
"channels":[
"Channel_01"
]
}
Command
curl -H "Content-Type: application/json" -X POST -d '{"nrOfBins":2,"aggregationType":"value","aggregations":["min","max","mean"],"fields":["pulseId","value"],"startPulseId":0,"endPulseId":3,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
[
{
"channel":"Channel_01",
"data":[
{
"pulseId":0,
"value":{
"min":1.0,
"max":5.0,
"mean":3.0
}
},
{
"pulseId":2,
"value":{
"min":3.0,
"max":7.0,
"mean":5.0
}
}
]
}
]
Array value aggregation with additional binning.
Index Aggregation
{
"nrOfBins":1,
"aggregationType":"index",
"aggregations":["min","max","mean","sum"],
"fields":["pulseId","value"]
"startPulseId":0,
"endPulseId":3,
"channels":[
"Channel_01"
]
}
Command
curl -H "Content-Type: application/json" -X POST -d '{"nrOfBins":1,"aggregationType":"index","aggregations":["min","max","mean","sum"],"fields":["pulseId","value"],"startPulseId":0,"endPulseId":3,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
[
{
"channel":"Channel_01",
"data":[
{
"pulseId":0,
"value":[
{
"min":1.0,
"max":4.0,
"mean":2.5,
"sum":10.0
},
{
"min":2.0,
"max":5.0,
"mean":3.5,
"sum":14.0
},
{
"min":3.0,
"max":6.0,
"mean":4.5,
"sum":18.0
},
{
"min":4.0,
"max":7.0,
"mean":5.5,
"sum":22.0
}
]
}
]
}
]
Aggregation of array indices with binning (several nrOfBins are also possible).
Extrema Search
{
"aggregationType":"extrema",
"aggregations":["min","max","sum"],
"fields":["pulseId","value"]
"startPulseId":0,
"endPulseId":3,
"channels":[
"Channel_01"
]
}
Command
curl -H "Content-Type: application/json" -X POST -d '{"aggregationType":"extrema","aggregations":["min","max","sum"],"fields":["pulseId","value"],"startPulseId":0,"endPulseId":3,"channels":["Channel_01"]}' http://sf-nube-14.psi.ch:8080/query
Response
[
{
"channel":"Channel_01",
"data":{
"minima":{
"min":{
"value":1.0,
"event":{
"pulseId":0,
"value":[1,2,3,4]
}
},
"sum":{
"value":10.0,
"event":{
"pulseId":0,
"value":[1,2,3,4]
}
}
},
"maxima":{
"max":{
"value":7.0,
"event":{
"pulseId":3,
"value":[4,5,6,7]
}
},
"sum":{
"value":22.0,
"event":{
"pulseId":3,
"value":[4,5,6,7]
}
}
}
}
}
]