Skip to content

Commit d2b9660

Browse files
Add DataStream
1 parent 7e68863 commit d2b9660

7 files changed

Lines changed: 301 additions & 0 deletions

File tree

CSAPI-lib/CSAPI-lib.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,15 @@
132132
<ClInclude Include="APIRequest.h" />
133133
<ClInclude Include="APIResponse.h" />
134134
<ClInclude Include="ConnectedSystemsAPI.h" />
135+
<ClInclude Include="DataModels\DataStream.h" />
135136
<ClInclude Include="DataModels\Link.h" />
137+
<ClInclude Include="DataModels\ObservedProperty.h" />
136138
<ClInclude Include="DataModels\Properties.h" />
137139
<ClInclude Include="DataModels\PropertiesBuilder.h" />
138140
<ClInclude Include="DataModels\System.h" />
139141
<ClInclude Include="DataModels\SystemBuilder.h" />
140142
<ClInclude Include="DataModels\TimeExtent.h" />
143+
<ClInclude Include="DataStreamsAPI.h" />
141144
<ClInclude Include="framework.h" />
142145
<ClInclude Include="OptionalTimePoint.h" />
143146
<ClInclude Include="Query\QueryParameters.h" />

CSAPI-lib/CSAPI-lib.vcxproj.filters

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,14 @@
6969
<ClInclude Include="Query\SystemsQuery.h">
7070
<Filter>Header Files\Query</Filter>
7171
</ClInclude>
72+
<ClInclude Include="DataModels\DataStream.h">
73+
<Filter>Header Files\DataModels</Filter>
74+
</ClInclude>
75+
<ClInclude Include="DataModels\ObservedProperty.h">
76+
<Filter>Header Files\DataModels</Filter>
77+
</ClInclude>
78+
<ClInclude Include="DataStreamsAPI.h">
79+
<Filter>Header Files</Filter>
80+
</ClInclude>
7281
</ItemGroup>
7382
</Project>

CSAPI-lib/ConnectedSystemsAPI.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
#include <iostream>
66
#include "APIRequest.h"
77
#include "SystemsAPI.h"
8+
#include "DataStreamsAPI.h"
89

910
namespace ConnectedSystemsAPI {
1011
class ConSysAPI {
1112
private:
1213
std::string apiRoot;
1314
std::string authHeader;
1415
SystemsAPI systemsAPI;
16+
DataStreamsAPI dataStreamsAPI;
1517

1618
public:
1719
/// <param name="apiRoot">e.g. "localhost:8181/sensorhub/api"</param>
@@ -26,6 +28,7 @@ namespace ConnectedSystemsAPI {
2628
authHeader = "Authorization: Bearer " + authenticationToken;
2729
}
2830
systemsAPI = SystemsAPI(apiRoot, authHeader);
31+
dataStreamsAPI = DataStreamsAPI(apiRoot, authHeader);
2932
}
3033

3134
/// <param name="apiRoot">e.g. "localhost:8181/sensorhub/api"</param>
@@ -38,6 +41,7 @@ namespace ConnectedSystemsAPI {
3841
const std::string& getApiRoot() const { return apiRoot; }
3942
const std::string& getAuthHeader() const { return authHeader; }
4043
SystemsAPI& getSystemsAPI() { return systemsAPI; }
44+
DataStreamsAPI& getDataStreamsAPI() { return dataStreamsAPI; }
4145
private:
4246
std::string base64_encode(const std::string& in) {
4347
static const std::string base64_chars =

CSAPI-lib/DataModels/DataStream.h

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <nlohmann/json.hpp>
5+
#include "Link.h"
6+
#include "TimeExtent.h"
7+
#include "ObservedProperty.h"
8+
9+
namespace ConnectedSystemsAPI {
10+
namespace DataModels {
11+
class DataStream {
12+
private:
13+
std::string id;
14+
std::string name;
15+
std::string description;
16+
std::optional<TimeExtent> validTime;
17+
std::optional<std::vector<std::string>> formats;
18+
std::optional<Link> systemLink;
19+
std::string outputName;
20+
std::optional<Link> procedureLink;
21+
std::optional<Link> deploymentLink;
22+
std::optional<Link> featureOfInterestLink;
23+
std::optional<Link> samplingFeatureLink;
24+
std::optional<std::vector<ObservedProperty>> observedProperties;
25+
std::optional<TimeExtent> phenomenonTime;
26+
std::string phenomenonTimeInterval;
27+
std::optional<TimeExtent> resultTime;
28+
std::string resultTimeInterval;
29+
std::string dataStreamType;
30+
std::string resultType;
31+
bool live;
32+
std::optional<std::vector<Link>> links;
33+
//std::optional<ObservationSchema> schema;
34+
35+
public:
36+
DataStream() = default;
37+
DataStream(const std::string& id,
38+
const std::string& name,
39+
const std::string& description,
40+
const std::optional<TimeExtent>& validTime,
41+
const std::optional<std::vector<std::string>>& formats,
42+
const std::optional<Link>& systemLink,
43+
const std::string& outputName,
44+
const std::optional<Link>& procedureLink,
45+
const std::optional<Link>& deploymentLink,
46+
const std::optional<Link>& featureOfInterestLink,
47+
const std::optional<Link>& samplingFeatureLink,
48+
const std::optional<std::vector<ObservedProperty>>& observedProperties,
49+
const std::optional<TimeExtent>& phenomenonTime,
50+
const std::string& phenomenonTimeInterval,
51+
const std::optional<TimeExtent>& resultTime,
52+
const std::string& resultTimeInterval,
53+
const std::string& dataStreamType,
54+
const std::string& resultType,
55+
bool live,
56+
const std::optional<std::vector<Link>>& links)
57+
: id(id), name(name), description(description), validTime(validTime), formats(formats),
58+
systemLink(systemLink), outputName(outputName), procedureLink(procedureLink),
59+
deploymentLink(deploymentLink), featureOfInterestLink(featureOfInterestLink),
60+
samplingFeatureLink(samplingFeatureLink), observedProperties(observedProperties),
61+
phenomenonTime(phenomenonTime), phenomenonTimeInterval(phenomenonTimeInterval),
62+
resultTime(resultTime), resultTimeInterval(resultTimeInterval),
63+
dataStreamType(dataStreamType), resultType(resultType), live(live), links(links) {
64+
}
65+
66+
/// <returns>Local resource ID. If set on creation, the server may ignore it.</returns>
67+
const std::string& getId() const { return id; }
68+
/// <returns>Human-readable name of the resource.</returns>
69+
const std::string& getName() const { return name; }
70+
/// <returns>Human-readable description of the resource.</returns>
71+
const std::string& getDescription() const { return description; }
72+
/// <returns>The validity period of the data stream’s description.</returns>
73+
const std::optional<TimeExtent>& getValidTime() const { return validTime; }
74+
/// <returns>The list of formats that the observations in the datastream can be encoded to.</returns>
75+
const std::optional<std::vector<std::string>>& getFormats() const { return formats; }
76+
/// <returns>Link to the system producing the observations.</returns>
77+
const std::optional<Link>& getSystemLink() const { return systemLink; }
78+
/// <returns>Name of the system output feeding this datastream.</returns>
79+
const std::string& getOutputName() const { return outputName; }
80+
/// <returns>Link to the procedure used to acquire observations
81+
/// (only provided if all observations in the datastream share the same procedure).</returns>
82+
const std::optional<Link>& getProcedureLink() const { return procedureLink; }
83+
/// <returns>Link to the deployment during which the observations are/were collected
84+
/// (only provided if all observations in the datastream share the same deployment).</returns>
85+
const std::optional<Link>& getDeploymentLink() const { return deploymentLink; }
86+
/// <returns>Link to the ultimate feature of interest
87+
/// (only provided if all observations in the datastream share the same feature of interest).</returns>
88+
const std::optional<Link>& getFeatureOfInterestLink() const { return featureOfInterestLink; }
89+
/// <returns>Link to the sampling feature
90+
/// (only provided if all observations in the datastream share the same sampling feature).</returns>
91+
const std::optional<Link>& getSamplingFeatureLink() const { return samplingFeatureLink; }
92+
/// <returns>Properties for which the observations in the datastream provide measurements.</returns>
93+
const std::optional<std::vector<ObservedProperty>>& getObservedProperties() const { return observedProperties; }
94+
/// <returns>The time period spanned by the phenomenon times of all observations in the datastream.</returns>
95+
const std::optional<TimeExtent>& getPhenomenonTime() const { return phenomenonTime; }
96+
/// <returns>An indication of how often feature of interest properties are observed.</returns>
97+
const std::string& getPhenomenonTimeInterval() const { return phenomenonTimeInterval; }
98+
/// <returns>The time period spanned by the result times of all observations in the datastream.</returns>
99+
const std::optional<TimeExtent>& getResultTime() const { return resultTime; }
100+
/// <returns>An indication of how often observation results are produced.</returns>
101+
const std::string& getResultTimeInterval() const { return resultTimeInterval; }
102+
/// <returns>Type of the data stream.</returns>
103+
const std::string& getDataStreamType() const { return dataStreamType; }
104+
/// <returns>The type of result for observations in the datastream.</returns>
105+
const std::string& getResultType() const { return resultType; }
106+
/// <returns>Indicates whether live data is available from the datastream.</returns>
107+
bool isLive() const { return live; }
108+
/// <returns>List of links associated with the data stream.</returns>
109+
const std::optional<std::vector<Link>>& getLinks() const { return links; }
110+
};
111+
112+
inline void from_json(const nlohmann::json& j, DataStream& ds) {
113+
ds = DataStream(
114+
j.value("id", ""),
115+
j.at("name").get<std::string>(),
116+
j.value("description", ""),
117+
j.value("validTime", std::optional<TimeExtent>{}),
118+
j.value("formats", std::optional<std::vector<std::string>>{}),
119+
j.value("system@link", std::optional<Link>{}),
120+
j.value("outputName", ""),
121+
j.value("procedure@link", std::optional<Link>{}),
122+
j.value("deployment@link", std::optional<Link>{}),
123+
j.value("featureOfInterest@link", std::optional<Link>{}),
124+
j.value("samplingFeature@link", std::optional<Link>{}),
125+
j.value("observedProperties", std::optional<std::vector<ObservedProperty>>{}),
126+
j.value("phenomenonTime", std::optional<TimeExtent>{}),
127+
j.value("phenomenonTimeInterval", ""),
128+
j.value("resultTime", std::optional<TimeExtent>{}),
129+
j.value("resultTimeInterval", ""),
130+
j.value("type", ""),
131+
j.value("resultType", ""),
132+
j.value("live", false),
133+
j.value("links", std::optional<std::vector<Link>>{})
134+
);
135+
}
136+
137+
inline void to_json(nlohmann::ordered_json& j, const DataStream& ds) {
138+
j = nlohmann::ordered_json::object();
139+
if (!ds.getId().empty())
140+
j["id"] = ds.getId();
141+
j["name"] = ds.getName();
142+
if (!ds.getDescription().empty())
143+
j["description"] = ds.getDescription();
144+
if (ds.getValidTime())
145+
j["validTime"] = ds.getValidTime().value();
146+
if (ds.getFormats())
147+
j["formats"] = ds.getFormats().value();
148+
if (ds.getSystemLink())
149+
j["system@link"] = ds.getSystemLink().value();
150+
if (!ds.getOutputName().empty())
151+
j["outputName"] = ds.getOutputName();
152+
if (ds.getProcedureLink())
153+
j["procedure@link"] = ds.getProcedureLink().value();
154+
if (ds.getDeploymentLink())
155+
j["deployment@link"] = ds.getDeploymentLink().value();
156+
if (ds.getFeatureOfInterestLink())
157+
j["featureOfInterest@link"] = ds.getFeatureOfInterestLink().value();
158+
if (ds.getSamplingFeatureLink())
159+
j["samplingFeature@link"] = ds.getSamplingFeatureLink().value();
160+
if (ds.getObservedProperties())
161+
j["observedProperties"] = ds.getObservedProperties().value();
162+
if (ds.getPhenomenonTime())
163+
j["phenomenonTime"] = ds.getPhenomenonTime().value();
164+
if (!ds.getPhenomenonTimeInterval().empty())
165+
j["phenomenonTimeInterval"] = ds.getPhenomenonTimeInterval();
166+
if (ds.getResultTime())
167+
j["resultTime"] = ds.getResultTime().value();
168+
if (!ds.getResultTimeInterval().empty())
169+
j["resultTimeInterval"] = ds.getResultTimeInterval();
170+
if (!ds.getDataStreamType().empty())
171+
j["type"] = ds.getDataStreamType();
172+
if (!ds.getResultType().empty())
173+
j["resultType"] = ds.getResultType();
174+
j["live"] = ds.isLive();
175+
if (ds.getLinks())
176+
j["links"] = ds.getLinks().value();
177+
}
178+
179+
inline std::ostream& operator<<(std::ostream& os, const DataStream& ds) {
180+
nlohmann::ordered_json j;
181+
ConnectedSystemsAPI::DataModels::to_json(j, ds);
182+
os << j.dump(2);
183+
return os;
184+
}
185+
}
186+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <nlohmann/json.hpp>
5+
6+
namespace ConnectedSystemsAPI {
7+
namespace DataModels {
8+
class ObservedProperty {
9+
private:
10+
std::string definition;
11+
std::string label;
12+
std::string description;
13+
14+
public:
15+
ObservedProperty() = default;
16+
ObservedProperty(const std::string& definition,
17+
const std::string& label,
18+
const std::string& description)
19+
: definition(definition), label(label), description(description) {
20+
}
21+
22+
/// <returns>Definition of the observed property.</returns>
23+
const std::string& getDefinition() const { return definition; }
24+
/// <returns>Human-readable label of the observed property.</returns>
25+
const std::string& getLabel() const { return label; }
26+
/// <returns>Human-readable description of the observed property.</returns>
27+
const std::string& getDescription() const { return description; }
28+
};
29+
30+
inline void from_json(const nlohmann::json& j, ObservedProperty& o) {
31+
o = ObservedProperty(
32+
j.value("definition", ""),
33+
j.value("label", ""),
34+
j.value("description", "")
35+
);
36+
}
37+
38+
inline void to_json(nlohmann::ordered_json& j, const ObservedProperty& o) {
39+
j = nlohmann::ordered_json::object();
40+
41+
if (!o.getDefinition().empty())
42+
j["definition"] = o.getDefinition();
43+
44+
j["label"] = o.getLabel();
45+
46+
if (!o.getDescription().empty())
47+
j["description"] = o.getDescription();
48+
}
49+
50+
inline std::ostream& operator<<(std::ostream& os, const ObservedProperty& o) {
51+
nlohmann::ordered_json j;
52+
ConnectedSystemsAPI::DataModels::to_json(j, o);
53+
os << j.dump(2);
54+
}
55+
}
56+
}

CSAPI-lib/DataStreamsAPI.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include "APIRequest.h"
5+
#include "APIResponse.h"
6+
#include "DataModels/DataStream.h"
7+
8+
namespace ConnectedSystemsAPI {
9+
class DataStreamsAPI {
10+
private:
11+
std::string apiRoot;
12+
std::string authHeader;
13+
14+
public:
15+
DataStreamsAPI() {}
16+
DataStreamsAPI(const std::string& apiRoot, const std::string& authHeader)
17+
: apiRoot(apiRoot), authHeader(authHeader) {
18+
}
19+
20+
/// <summary>
21+
/// List all data streams available from this server endpoint.
22+
/// </summary>
23+
/// <returns>A response object containing a list of data streams.</returns>
24+
APIResponse<DataModels::DataStream> getSystems() {
25+
auto response = APIRequest::Builder()
26+
.setApiRoot(apiRoot)
27+
.setMethod("GET")
28+
.setAuthHeader(authHeader)
29+
.setResourcePath("/datastreams")
30+
.build()
31+
.execute<DataModels::DataStream>();
32+
return response;
33+
}
34+
};
35+
}

CSAPI-test/CSAPI-test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <string>
33
#include "pch.h"
44
#include "CppUnitTest.h"
5+
#include "DataModels/DataStream.h"
56
#include "DataModels/System.h"
67
#include "DataModels/SystemBuilder.h"
78
#include "DataModels/Properties.h"
@@ -180,5 +181,12 @@ namespace CSAPItest {
180181
TEST_METHOD_CLEANUP(MethodCleanup) {
181182
cleanupTestSystem();
182183
}
184+
185+
TEST_METHOD(GetDataStreams) {
186+
auto response = csapi.getDataStreamsAPI().getSystems();
187+
std::cout << "Response: " << response.getResponseBody() << std::endl;
188+
Assert::IsTrue(response.isSuccessful());
189+
std::cout << "DataStream: " << response.getItems().at(0) << std::endl;
190+
}
183191
};
184192
}

0 commit comments

Comments
 (0)