Skip to content

Commit 6ccd1cf

Browse files
Cleanup, comments
1 parent d7911f6 commit 6ccd1cf

4 files changed

Lines changed: 199 additions & 58 deletions

File tree

CSAPI-lib/ConnectedSystemsAPI.h

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include "ControlStreamsAPI.h"
99

1010
namespace ConnectedSystemsAPI {
11+
/// <summary>
12+
/// Main API class for interacting with the Connected Systems API on a server.
13+
/// </summary>
1114
class ConSysAPI {
1215
private:
1316
std::string apiRoot;
@@ -18,50 +21,61 @@ namespace ConnectedSystemsAPI {
1821
ControlStreamsAPI controlStreamsAPI;
1922

2023
public:
21-
/// <param name="apiRoot">e.g. "localhost:8181/sensorhub/api"</param>
24+
/// <summary>
25+
/// Constructs a ConnectedSystemsAPI instance, used to access an API endpoint on a server.
26+
/// </summary>
27+
/// <param name="apiRoot">e.g. "localhost:8181/sensorhub/api". If no protocol is specified, defaults to https://</param>
2228
/// <param name="authenticationToken">If isBasicAuth is true, this should be a base64-encoded "username:password" string. If isBasicAuth is false, this should be a bearer token.</param>
2329
/// <param name="isBasicAuth">If true, use Basic authentication with the provided base64-encoded "username:password" string. If false, use Bearer token authentication.</param>
2430
ConSysAPI(const std::string& apiRoot, const std::string& authenticationToken, bool isBasicAuth)
25-
: apiRoot(apiRoot) {
26-
if (isBasicAuth) {
27-
authHeader = "Authorization: Basic " + authenticationToken;
28-
}
29-
else {
30-
authHeader = "Authorization: Bearer " + authenticationToken;
31-
}
32-
systemsAPI = SystemsAPI(apiRoot, authHeader);
33-
dataStreamsAPI = DataStreamsAPI(apiRoot, authHeader);
34-
observationsAPI = ObservationsAPI(apiRoot, authHeader);
35-
controlStreamsAPI = ControlStreamsAPI(apiRoot, authHeader);
36-
}
37-
38-
// Overload to accept C-style string literals to avoid list-initialization narrowing issues
39-
ConSysAPI(const char* apiRootC, const char* usernameC, const char* passwordC)
40-
: ConSysAPI(std::string(apiRootC), std::string(usernameC), std::string(passwordC)) {
31+
: apiRoot(apiRoot),
32+
authHeader(isBasicAuth ? std::string("Authorization: Basic ") + authenticationToken : std::string("Authorization: Bearer ") + authenticationToken),
33+
systemsAPI(this->apiRoot, authHeader),
34+
dataStreamsAPI(this->apiRoot, authHeader),
35+
observationsAPI(this->apiRoot, authHeader),
36+
controlStreamsAPI(this->apiRoot, authHeader) {
4137
}
4238

43-
/// <param name="apiRoot">e.g. "localhost:8181/sensorhub/api"</param>
39+
/// <summary>
40+
/// Constructs a ConnectedSystemsAPI instance, used to access an API endpoint on a server.
41+
/// </summary>
42+
/// <param name="apiRoot">e.g. "localhost:8181/sensorhub/api". If no protocol is specified, defaults to https://</param>
4443
/// <param name="username">Username for Basic authentication</param>
4544
/// <param name="password">Password for Basic authentication</param>
4645
ConSysAPI(const std::string& apiRoot, const std::string& username, const std::string& password)
4746
: ConSysAPI(apiRoot, base64_encode(username + ":" + password), true) {
4847
}
4948

49+
// Overload to accept C-style string literals to avoid list-initialization narrowing issues
50+
/// <summary>
51+
/// Constructs a ConnectedSystemsAPI instance, used to access an API endpoint on a server.
52+
/// </summary>
53+
/// <param name="apiRoot">e.g. "localhost:8181/sensorhub/api". If no protocol is specified, defaults to https://</param>
54+
/// <param name="username">Username for Basic authentication</param>
55+
/// <param name="password">Password for Basic authentication</param>
56+
ConSysAPI(const char* apiRootC, const char* usernameC, const char* passwordC)
57+
: ConSysAPI(std::string(apiRootC), std::string(usernameC), std::string(passwordC)) {
58+
}
59+
5060
const std::string& getApiRoot() const { return apiRoot; }
5161
const std::string& getAuthHeader() const { return authHeader; }
5262
SystemsAPI& getSystemsAPI() { return systemsAPI; }
5363
DataStreamsAPI& getDataStreamsAPI() { return dataStreamsAPI; }
5464
ObservationsAPI& getObservationsAPI() { return observationsAPI; }
5565
ControlStreamsAPI& getControlStreamsAPI() { return controlStreamsAPI; }
5666
private:
57-
std::string base64_encode(const std::string& in) {
58-
static const std::string base64_chars =
67+
static std::string base64_encode(const std::string& in) {
68+
static const char base64_chars[] =
5969
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
6070
"abcdefghijklmnopqrstuvwxyz"
6171
"0123456789+/";
6272

6373
std::string out;
64-
int val = 0, valb = -6;
74+
out.reserve(((in.size() + 2) / 3) * 4);
75+
76+
unsigned int val = 0;
77+
int valb = -6;
78+
6579
for (unsigned char c : in) {
6680
val = (val << 8) + c;
6781
valb += 8;
@@ -70,8 +84,13 @@ namespace ConnectedSystemsAPI {
7084
valb -= 6;
7185
}
7286
}
73-
if (valb > -6) out.push_back(base64_chars[((val << 8) >> (valb + 8)) & 0x3F]);
74-
while (out.size() % 4) out.push_back('=');
87+
88+
if (valb > -6)
89+
out.push_back(base64_chars[((val << 8) >> (valb + 8)) & 0x3F]);
90+
91+
while (out.size() % 4)
92+
out.push_back('=');
93+
7594
return out;
7695
}
7796
};

CSAPI-lib/ControlStreamsAPI.h

Lines changed: 118 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include "DataModels/CommandSchema.h"
99

1010
namespace ConnectedSystemsAPI {
11+
/// <summary>
12+
/// API for interacting with control streams in the Connected Systems API.
13+
/// </summary>
1114
class ControlStreamsAPI {
1215
private:
1316
std::string apiRoot;
@@ -19,7 +22,12 @@ namespace ConnectedSystemsAPI {
1922
: apiRoot(apiRoot), authHeader(authHeader) {
2023
}
2124

22-
APIResponse<DataModels::ControlStream> getControlStreams(std::string queryString = "") {
25+
/// <summary>
26+
/// List all control streams available from this server endpoint.
27+
/// </summary>
28+
/// <param name="queryString">The query string.</param>
29+
/// <returns>A response object containing a list of control streams.</returns>
30+
APIResponse<DataModels::ControlStream> getControlStreams(const std::string& queryString = "") const {
2331
auto response = APIRequest::Builder()
2432
.setApiRoot(apiRoot)
2533
.setMethod("GET")
@@ -31,7 +39,16 @@ namespace ConnectedSystemsAPI {
3139
return response;
3240
}
3341

34-
APIResponse<DataModels::ControlStream> getControlStreamsOfSystem(const std::string& systemId, std::string queryString = "") {
42+
/// <summary>
43+
/// List all control streams available from the parent system.
44+
/// </summary>
45+
/// <param name="systemId">The local identifier of a system.</param>
46+
/// <param name="queryString">The query string.</param>
47+
/// <returns>A response object containing a list of control streams.</returns>
48+
APIResponse<DataModels::ControlStream> getControlStreamsOfSystem(const std::string& systemId, const std::string& queryString = "") const {
49+
if (systemId.empty())
50+
return APIResponse<DataModels::ControlStream>(400, "Invalid systemId", "", {});
51+
3552
auto response = APIRequest::Builder()
3653
.setApiRoot(apiRoot)
3754
.setMethod("GET")
@@ -45,7 +62,15 @@ namespace ConnectedSystemsAPI {
4562
return response;
4663
}
4764

48-
APIResponse<DataModels::ControlStream> getControlStreamById(const std::string& controlStreamId) {
65+
/// <summary>
66+
/// Get a specific control stream by its ID.
67+
/// </summary>
68+
/// <param name="controlStreamId">The local identifier of a control stream.</param>
69+
/// <returns>A response object containing the control stream.</returns>
70+
APIResponse<DataModels::ControlStream> getControlStreamById(const std::string& controlStreamId) const {
71+
if (controlStreamId.empty())
72+
return APIResponse<DataModels::ControlStream>(400, "Invalid controlStreamId", "", {});
73+
4974
auto response = APIRequest::Builder()
5075
.setApiRoot(apiRoot)
5176
.setMethod("GET")
@@ -57,7 +82,15 @@ namespace ConnectedSystemsAPI {
5782
return response;
5883
}
5984

60-
APIResponse<DataModels::CommandSchema> getControlStreamSchema(const std::string& controlStreamId) {
85+
/// <summary>
86+
/// Get the command schema for a specific control stream by its ID.
87+
/// </summary>
88+
/// <param name="controlStreamId">The local identifier of a control stream.</param>
89+
/// <returns>A response object containing the command schema.</returns>
90+
APIResponse<DataModels::CommandSchema> getControlStreamSchema(const std::string& controlStreamId) const {
91+
if (controlStreamId.empty())
92+
return APIResponse<DataModels::CommandSchema>(400, "Invalid controlStreamId", "", {});
93+
6194
auto response = APIRequest::Builder()
6295
.setApiRoot(apiRoot)
6396
.setMethod("GET")
@@ -69,5 +102,86 @@ namespace ConnectedSystemsAPI {
69102
.execute<DataModels::CommandSchema>();
70103
return response;
71104
}
105+
106+
/// <summary>
107+
/// Create a new control stream under the specified parent system.
108+
/// </summary>
109+
/// <param name="systemId">The local identifier of the parent system.</param>
110+
/// <param name="controlStream">The control stream to create.</param>
111+
/// <returns>A response object indicating success or failure.</returns>
112+
APIResponse<void> createControlStream(const std::string& systemId, const DataModels::ControlStream& controlStream) const {
113+
if (systemId.empty())
114+
return APIResponse<void>(400, "Invalid systemId", "", {});
115+
116+
nlohmann::ordered_json j;
117+
ConnectedSystemsAPI::DataModels::to_json(j, controlStream);
118+
119+
auto response = APIRequest::Builder()
120+
.setApiRoot(apiRoot)
121+
.setMethod("POST")
122+
.setAuthHeader(authHeader)
123+
.addHeader("Content-Type", "application/json")
124+
.setResourcePath("systems")
125+
.setResourceId(systemId)
126+
.setSubResourcePath("controlstreams")
127+
.setBody(j.dump())
128+
.build()
129+
.execute<void>();
130+
return response;
131+
}
132+
133+
/// <summary>
134+
/// Update an existing control stream by its ID.
135+
/// </summary>
136+
/// <param name="controlStreamId">The local identifier of the control stream to update.</param>
137+
/// <param name="controlStream">The updated control stream.</param>
138+
/// <returns>A response object indicating success or failure.</returns>
139+
APIResponse<void> updateControlStream(const std::string& controlStreamId, const DataModels::ControlStream& controlStream) const {
140+
if (controlStreamId.empty())
141+
return APIResponse<void>(400, "Invalid controlStreamId", "", {});
142+
143+
nlohmann::ordered_json j;
144+
ConnectedSystemsAPI::DataModels::to_json(j, controlStream);
145+
146+
auto response = APIRequest::Builder()
147+
.setApiRoot(apiRoot)
148+
.setMethod("PUT")
149+
.setAuthHeader(authHeader)
150+
.addHeader("Content-Type", "application/json")
151+
.setResourcePath("controlstreams")
152+
.setResourceId(controlStreamId)
153+
.setBody(j.dump())
154+
.build()
155+
.execute<void>();
156+
return response;
157+
}
158+
159+
/// <summary>
160+
/// Delete a control stream by its ID, with an option to delete all associated commands.
161+
/// </summary>
162+
/// <param name="controlStreamId">The local identifier of the control stream to delete.</param>
163+
/// <param name="cascade">If true, all associated commands will also be deleted.
164+
/// If false, associated commands will be preserved.
165+
/// If undefined, the server's default behavior will be applied (false unless otherwise specified).</param>
166+
/// <returns>A response object indicating success or failure.</returns>
167+
APIResponse<void> deleteControlStream(const std::string& controlStreamId, std::optional<bool> cascade = std::nullopt) const {
168+
if (controlStreamId.empty())
169+
return APIResponse<void>(400, "Invalid controlStreamId", "", {});
170+
171+
std::string queryString;
172+
if (cascade.has_value())
173+
queryString = cascade.value() ? "?cascade=true" : "?cascade=false";
174+
175+
auto response = APIRequest::Builder()
176+
.setApiRoot(apiRoot)
177+
.setMethod("DELETE")
178+
.setAuthHeader(authHeader)
179+
.setResourcePath("controlstreams")
180+
.setResourceId(controlStreamId)
181+
.setQueryString(queryString)
182+
.build()
183+
.execute<void>();
184+
return response;
185+
}
72186
};
73187
}

CSAPI-lib/DataModels/CommandSchema.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
#include "Component/DataComponent.h"
77
#include "Component/DataComponentRegistry.h"
8-
#include "Component/DataRecord.h"
98

109
namespace ConnectedSystemsAPI {
1110
namespace DataModels {
@@ -21,7 +20,7 @@ namespace ConnectedSystemsAPI {
2120
CommandSchema(const std::string& commandFormat,
2221
std::unique_ptr<Component::DataComponent> parametersSchema,
2322
std::unique_ptr<Component::DataComponent> resultSchema)
24-
: commandFormat(commandFormat), resultSchema(std::move(resultSchema)) {
23+
: commandFormat(commandFormat), parametersSchema(std::move(parametersSchema)), resultSchema(std::move(resultSchema)) {
2524
}
2625

2726
CommandSchema(const CommandSchema&) = delete;

0 commit comments

Comments
 (0)