Skip to content

Commit ac72830

Browse files
committed
Server side implementation.
1 parent cf83fae commit ac72830

File tree

15 files changed

+330
-59
lines changed

15 files changed

+330
-59
lines changed

apps/service.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ using namespace brayns;
2525

2626
int main(int argc, const char **argv)
2727
{
28-
return runService(argc, argv);
28+
return runServiceFromArgv(argc, argv);
2929
}

src/brayns/core/Launcher.cpp

+35-14
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,39 @@
2323

2424
#include <iostream>
2525

26+
#include <brayns/core/endpoints/CoreEndpoints.h>
2627
#include <brayns/core/service/Service.h>
2728
#include <brayns/core/utils/Logger.h>
29+
#include <brayns/core/utils/String.h>
2830

2931
namespace
3032
{
3133
using namespace brayns;
3234

33-
Service createService(const ServiceSettings &settings, Logger &logger)
35+
void startServerAndRunService(const ServiceSettings &settings, Logger &logger)
3436
{
3537
auto level = getEnumValue<LogLevel>(settings.logLevel);
3638
logger.setLevel(level);
3739

40+
auto token = StopToken();
41+
42+
logger.info("Building JSON-RPC API");
43+
44+
auto api = Api();
45+
46+
auto builder = ApiBuilder();
47+
48+
addCoreEndpoints(builder, api, token);
49+
50+
api = builder.build();
51+
52+
logger.info("JSON-RCP API ready");
53+
54+
auto methods = api.getMethods();
55+
logger.debug("Available methods:\n {}", join(methods, "\n "));
56+
57+
logger.info("Starting websocket server on {}:{}", settings.host, settings.port);
58+
3859
auto ssl = std::optional<SslSettings>();
3960

4061
if (settings.ssl)
@@ -47,7 +68,7 @@ Service createService(const ServiceSettings &settings, Logger &logger)
4768
};
4869
}
4970

50-
auto server = WebSocketServerSettings{
71+
auto serverSettings = WebSocketServerSettings{
5172
.host = settings.host,
5273
.port = settings.port,
5374
.maxThreadCount = settings.maxThreadCount,
@@ -56,21 +77,19 @@ Service createService(const ServiceSettings &settings, Logger &logger)
5677
.ssl = std::move(ssl),
5778
};
5879

59-
auto api = Api({});
80+
auto server = startServer(serverSettings, logger);
6081

61-
auto context = std::make_unique<ServiceContext>(ServiceContext{
62-
.logger = logger,
63-
.server = std::move(server),
64-
.api = std::move(api),
65-
});
82+
logger.info("Websocket server started");
6683

67-
return Service(std::move(context));
84+
logger.info("Service running");
85+
86+
runService(server, api, token, logger);
6887
}
6988
}
7089

7190
namespace brayns
7291
{
73-
int runService(int argc, const char **argv)
92+
int runServiceFromArgv(int argc, const char **argv)
7493
{
7594
auto logger = createConsoleLogger("brayns");
7695

@@ -90,20 +109,22 @@ int runService(int argc, const char **argv)
90109
return 0;
91110
}
92111

93-
auto service = createService(settings, logger);
112+
logger.info("{}", getCopyright());
113+
114+
logger.debug("Service options:{}", stringifyArgvSettings(settings));
94115

95-
service.run();
116+
startServerAndRunService(settings, logger);
96117

97118
return 0;
98119
}
99120
catch (const std::exception &e)
100121
{
101-
logger.fatal("Cannot start service: {}", e.what());
122+
logger.fatal("Fatal error: {}", e.what());
102123
return 1;
103124
}
104125
catch (...)
105126
{
106-
logger.fatal("Cannot start service for unknown reason");
127+
logger.fatal("Unknown fatal error");
107128
return 1;
108129
}
109130
}

src/brayns/core/Launcher.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,5 @@ struct ArgvSettingsReflector<ServiceSettings>
101101
}
102102
};
103103

104-
int runService(int argc, const char **argv);
104+
int runServiceFromArgv(int argc, const char **argv);
105105
}

src/brayns/core/api/Api.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace brayns
3333
class Api
3434
{
3535
public:
36-
explicit Api(std::map<std::string, Endpoint> endpoints);
36+
explicit Api(std::map<std::string, Endpoint> endpoints = {});
3737
~Api();
3838

3939
Api(const Api &) = delete;

src/brayns/core/api/ApiReflector.h

+40-2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,25 @@ struct Params
7070
std::string binary = {};
7171
};
7272

73+
template<>
74+
struct ApiReflector<RawParams>
75+
{
76+
static JsonSchema getSchema()
77+
{
78+
return getJsonSchema<JsonValue>();
79+
}
80+
81+
static RawResult serialize(RawParams)
82+
{
83+
throw std::invalid_argument("Cannot serialize params");
84+
}
85+
86+
static RawParams deserialize(RawParams params)
87+
{
88+
return params;
89+
}
90+
};
91+
7392
template<ReflectedJson T>
7493
struct ApiReflector<Params<T>>
7594
{
@@ -78,7 +97,7 @@ struct ApiReflector<Params<T>>
7897
return getJsonSchema<T>();
7998
}
8099

81-
static RawResult serialize(Params<T> value)
100+
static RawResult serialize(Params<T>)
82101
{
83102
throw std::invalid_argument("Cannot serialize params");
84103
}
@@ -96,6 +115,25 @@ struct Result
96115
std::string binary = {};
97116
};
98117

118+
template<>
119+
struct ApiReflector<RawResult>
120+
{
121+
static JsonSchema getSchema()
122+
{
123+
return getJsonSchema<JsonValue>();
124+
}
125+
126+
static RawResult serialize(RawResult value)
127+
{
128+
return value;
129+
}
130+
131+
static RawResult deserialize(RawParams)
132+
{
133+
throw std::invalid_argument("Cannot deserialize result");
134+
}
135+
};
136+
99137
template<ReflectedJson T>
100138
struct ApiReflector<Result<T>>
101139
{
@@ -109,7 +147,7 @@ struct ApiReflector<Result<T>>
109147
return {serializeToJson(result.value), std::move(result.binary)};
110148
}
111149

112-
static Result<T> deserialize(RawParams params)
150+
static Result<T> deserialize(RawParams)
113151
{
114152
throw std::invalid_argument("Cannot deserialize result");
115153
}

src/brayns/core/api/Endpoint.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct EndpointSchema
4141
};
4242

4343
template<>
44-
struct JsonReflector<EndpointSchema>
44+
struct JsonObjectReflector<EndpointSchema>
4545
{
4646
static auto reflect()
4747
{

src/brayns/core/api/Progress.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct ProgressInfo
3838
};
3939

4040
template<>
41-
struct JsonReflector<ProgressInfo>
41+
struct JsonObjectReflector<ProgressInfo>
4242
{
4343
static auto reflect()
4444
{

src/brayns/core/api/Task.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ struct JsonObjectReflector<TaskResult>
6262
static auto reflect()
6363
{
6464
auto builder = JsonBuilder<TaskResult>();
65-
builder.field("task_id", [](auto &object) { return &object.taskId; });
65+
builder.field("task_id", [](auto &object) { return &object.taskId; })
66+
.description("ID of the task started by the method");
6667
return builder.build();
6768
}
6869
};
@@ -72,4 +73,16 @@ struct TaskInfo
7273
TaskId id;
7374
ProgressInfo progress;
7475
};
76+
77+
template<>
78+
struct JsonObjectReflector<TaskInfo>
79+
{
80+
static auto reflect()
81+
{
82+
auto builder = JsonBuilder<TaskInfo>();
83+
builder.field("id", [](auto &object) { return &object.id; }).description("Task ID to monitor it");
84+
builder.field("progress", [](auto &object) { return &object.progress; }).description("Current task progress");
85+
return builder.build();
86+
}
87+
};
7588
}

src/brayns/core/cli/CommandLine.h

+27-6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct ArgvOption
4747
std::string description;
4848
std::string defaultValue;
4949
std::function<void(std::string_view, SettingsType &)> parse;
50+
std::function<std::string(const SettingsType &)> toString;
5051
};
5152

5253
template<typename SettingsType>
@@ -109,6 +110,18 @@ class ArgvInfo
109110
return result;
110111
}
111112

113+
std::string toString(const SettingsType &settings) const
114+
{
115+
auto stream = std::ostringstream();
116+
117+
for (const auto &[key, option] : _options)
118+
{
119+
stream << "\n --" << key << ": " << option.toString(settings);
120+
}
121+
122+
return stream.str();
123+
}
124+
112125
private:
113126
std::string _description;
114127
ArgvOptions<SettingsType> _options;
@@ -119,7 +132,7 @@ struct ArgvReflector;
119132

120133
template<typename T>
121134
concept ReflectedArgvOption = std::same_as<std::string, decltype(ArgvReflector<T>::getType())>
122-
&& std::same_as<std::string, decltype(ArgvReflector<T>::display(T()))>
135+
&& std::same_as<std::string, decltype(ArgvReflector<T>::toString(T()))>
123136
&& std::same_as<T, decltype(ArgvReflector<T>::parse(std::string_view()))>;
124137

125138
template<>
@@ -130,7 +143,7 @@ struct ArgvReflector<bool>
130143
return "boolean";
131144
}
132145

133-
static std::string display(bool value)
146+
static std::string toString(bool value)
134147
{
135148
return value ? "true" : "false";
136149
}
@@ -155,7 +168,7 @@ struct ArgvReflector<T>
155168
return std::is_integral_v<T> ? "integer" : "number";
156169
}
157170

158-
static std::string display(const T &value)
171+
static std::string toString(const T &value)
159172
{
160173
return fmt::format("{}", value);
161174
}
@@ -174,7 +187,7 @@ struct ArgvReflector<std::string>
174187
return "string";
175188
}
176189

177-
static std::string display(const std::string &value)
190+
static std::string toString(const std::string &value)
178191
{
179192
return value;
180193
}
@@ -203,7 +216,7 @@ class ArgvOptionBuilder
203216
template<ReflectedArgvOption T>
204217
ArgvOptionBuilder defaultValue(const T &value)
205218
{
206-
_option->defaultValue = ArgvReflector<T>::display(value);
219+
_option->defaultValue = ArgvReflector<T>::toString(value);
207220
return *this;
208221
}
209222

@@ -221,7 +234,8 @@ using GetOptionType = std::decay_t<std::remove_pointer_t<std::invoke_result_t<Ge
221234

222235
template<typename GetterType, typename SettingsType>
223236
concept ArgvOptionGetter =
224-
std::invocable<GetterType, SettingsType &> && std::is_pointer_v<std::invoke_result_t<GetterType, SettingsType &>>
237+
std::invocable<GetterType, SettingsType &> && std::invocable<GetterType, const SettingsType &>
238+
&& std::is_pointer_v<std::invoke_result_t<GetterType, SettingsType &>>
225239
&& ReflectedArgvOption<GetOptionType<GetterType, SettingsType>>;
226240

227241
template<typename SettingsType>
@@ -249,6 +263,7 @@ class ArgvBuilder
249263
option.key = std::move(key);
250264
option.type = Reflector::getType();
251265
option.parse = [=](auto data, auto &settings) { *getOptionPtr(settings) = Reflector::parse(data); };
266+
option.toString = [=](const auto &settings) { return Reflector::toString(*getOptionPtr(settings)); };
252267

253268
return ArgvOptionBuilder<SettingsType>(option);
254269
}
@@ -294,4 +309,10 @@ SettingsType parseArgvAs(int argc, const char **argv)
294309
auto map = parseArgv(argc, argv);
295310
return parseArgvAs<SettingsType>(map);
296311
}
312+
313+
template<ReflectedArgvSettings SettingsType>
314+
std::string stringifyArgvSettings(const SettingsType &settings)
315+
{
316+
return reflectArgvSettings<SettingsType>().toString(settings);
317+
}
297318
}

0 commit comments

Comments
 (0)