Skip to content

Commit 260768f

Browse files
Added configurable sua server address
1 parent 613ccb9 commit 260768f

File tree

5 files changed

+188
-17
lines changed

5 files changed

+188
-17
lines changed

Diff for: src/Utils/ServerAddressParser.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2022 Contributors to the Eclipse Foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
#include "ServerAddressParser.h"
18+
19+
#include "spdlog/fmt/fmt.h"
20+
21+
#include <regex>
22+
#include <algorithm>
23+
24+
namespace sua {
25+
26+
void ServerAddressParser::parse(const std::string & address, std::string & transport, std::string & host, int & port)
27+
{
28+
std::regex regex("^([a-zA-Z]+)\\:\\/\\/([^:\\/?#]+)(?:\\:([0-9]+))?$");
29+
std::smatch result;
30+
31+
std::regex_match(address, result, regex);
32+
33+
// 4 total because:
34+
// [0] is entire match (address)
35+
// [1],[2],[3] are transport,host,port
36+
if(result.size() != 4) {
37+
throw std::runtime_error(fmt::format("Invalid server address: {}", address));
38+
}
39+
40+
if(result[1].str().empty()) {
41+
throw std::runtime_error("Missing transport");
42+
}
43+
transport = result[1];
44+
std::transform(transport.begin(), transport.end(), transport.begin(), ::tolower);
45+
46+
if(result[2].str().empty()) {
47+
throw std::runtime_error("Missing host");
48+
}
49+
host = result[2];
50+
51+
if(result[3].str().empty()) {
52+
throw std::runtime_error("Missing port");
53+
}
54+
port = std::stoi(result[3]);
55+
}
56+
57+
} // namespace sua

Diff for: src/Utils/ServerAddressParser.h

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2022 Contributors to the Eclipse Foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
#ifndef SDV_SUA_SERVERADDRESSPARSER_H
18+
#define SDV_SUA_SERVERADDRESSPARSER_H
19+
20+
#include <string>
21+
22+
namespace sua {
23+
24+
class ServerAddressParser {
25+
public:
26+
void parse(const std::string & address, std::string & transport, std::string & host, int & port);
27+
};
28+
29+
} // namespace sua
30+
31+
#endif

Diff for: src/main.cpp

+49-17
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020
#include "Mqtt/MqttMessagingProtocolYAML.h"
2121
#include "Mqtt/MqttConfiguration.h"
2222
#include "Utils/BundleChecker.h"
23+
#include "Utils/ServerAddressParser.h"
2324
#include "SelfUpdateAgent.h"
2425
#include "Logger.h"
2526
#include "version.h"
2627

28+
#include <cstdlib>
2729
#include <iostream>
2830
#include <memory>
2931

@@ -34,21 +36,29 @@ The system needs to be restarted manually for the update to take effect.
3436
3537
Usage: sdv-self-update-agent [OPTIONS]
3638
39+
Environment variables:
40+
SUA_SERVER sets and overrides MQTT server address to connect
41+
(default is 'tcp://mosquitto:1883')
42+
3743
Options:
3844
-h, --help display this help and exit
3945
-v, --version display version (git hash and build number) used to build sua
4046
-p, --path path where downloaded update bundles will be stored (default is '/data/selfupdates')
4147
-a, --api use 'k8s' or 'bfb' format for mqtt communication (default is 'bfb')
42-
--host MQTT broker host to connect (default is 'mosquitto')
43-
--port MQTT broker port to conenct (default is '1883')
48+
-s, --server MQTT broker server to connect (default is 'tcp://mosquitto:1883')
49+
(has precedence over SUA_SERVER environment variable)
4450
)";
4551

4652
int main(int argc, char* argv[])
4753
{
4854
std::string hostPathToSelfupdateDir{"/data/selfupdates"};
49-
std::string api = "bfb";
50-
std::string host = "mosquitto";
51-
int port = 1883;
55+
std::string api = "bfb";
56+
std::string server = "tcp://mosquitto:1883";
57+
58+
const char * env_server = std::getenv("SUA_SERVER");
59+
if(env_server) {
60+
server = env_server;
61+
}
5262

5363
if(argc > 1) {
5464
for(int i = 1; i < argc; i++) {
@@ -79,27 +89,49 @@ int main(int argc, char* argv[])
7989
continue;
8090
}
8191

82-
if("--host" == opt) {
83-
if((i + 1) < argc) {
84-
host = argv[i + 1];
85-
}
86-
continue;
87-
}
88-
89-
if("--port" == opt) {
92+
if(("-s" == opt) || ("--server" == opt)) {
9093
if((i + 1) < argc) {
91-
port = std::stoi(argv[i + 1]);
94+
server = argv[i + 1];
9295
}
9396
continue;
9497
}
9598
}
9699
}
97100

101+
bool failure_detected = false;
102+
103+
std::cout << "Self Update Agent:" << std::endl;
104+
105+
std::string transport = "tcp";
106+
std::string host = "mosquitto";
107+
int port = 1883;
108+
109+
try {
110+
sua::ServerAddressParser().parse(server, transport, host, port);
111+
} catch (const std::invalid_argument & e) {
112+
std::cout << fmt::format("Invalid port in address '{}'\n", server);
113+
failure_detected = true;
114+
} catch (const std::out_of_range & e) {
115+
std::cout << fmt::format("Invalid port in address '{}'\n", server);
116+
failure_detected = true;
117+
} catch (const std::runtime_error & e) {
118+
std::cout << e.what() << std::endl;
119+
failure_detected = true;
120+
}
121+
122+
if(transport != "tcp") {
123+
std::cout << "Unsupported transport '" << transport << "', 'tcp' in one valid option." << std::endl;
124+
failure_detected = true;
125+
}
126+
98127
if((api != "k8s") && (api != "bfb")) {
99-
std::cout << "Self Update Agent:" << std::endl;
100128
std::cout << "Unsupported api '" << api << "', valid are 'k8s' and 'bfb' only."
101129
<< std::endl;
102-
return 0;
130+
failure_detected = true;
131+
}
132+
133+
if(failure_detected) {
134+
return 0;
103135
}
104136

105137
sua::Logger::instance().init();
@@ -132,7 +164,7 @@ int main(int argc, char* argv[])
132164
sua::Logger::info("SUA commit hash : '{}'", SUA_COMMIT_HASH );
133165
sua::Logger::info("Communication protocol : '{}'", api);
134166
sua::Logger::info("Updates directory : '{}'", ctx.updatesDirectory);
135-
sua::Logger::info("MQTT broker address : '{}:{}'", conf.brokerHost, conf.brokerPort);
167+
sua::Logger::info("MQTT broker address : '{}://{}:{}'", transport, conf.brokerHost, conf.brokerPort);
136168

137169
sua.init();
138170
sua.start(conf);

Diff for: utest/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_executable(TestSelfUpdateAgent
33
TestFSM.cpp
44
TestMqttMessagingProtocolYAML.cpp
55
TestMqttMessagingProtocolJSON.cpp
6+
TestServerAddressParser.cpp
67
Utils.cpp
78
)
89

Diff for: utest/TestServerAddressParser.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include "gtest/gtest.h"
2+
#include "Utils/ServerAddressParser.h"
3+
4+
namespace
5+
{
6+
7+
class TestServerAddressParser : public ::testing::Test {
8+
public:
9+
void parse(const std::string & address) {
10+
sua::ServerAddressParser().parse(address, transport, host, port);
11+
}
12+
13+
std::string transport;
14+
std::string host;
15+
int port;
16+
};
17+
18+
TEST_F(TestServerAddressParser, parse_missingTransport_throws)
19+
{
20+
EXPECT_THROW(parse("://host:42"), std::runtime_error);
21+
EXPECT_THROW(parse("//host:42"), std::runtime_error);
22+
EXPECT_THROW(parse("host:42"), std::runtime_error);
23+
}
24+
25+
TEST_F(TestServerAddressParser, parse_missingHost_throws)
26+
{
27+
EXPECT_THROW(parse("tcp://:42"), std::runtime_error);
28+
EXPECT_THROW(parse("tcp://42"), std::runtime_error);
29+
}
30+
31+
TEST_F(TestServerAddressParser, parse_missingPort_throws)
32+
{
33+
EXPECT_THROW(parse("tcp://host"), std::runtime_error);
34+
EXPECT_THROW(parse("tcp://host:"), std::runtime_error);
35+
}
36+
37+
TEST_F(TestServerAddressParser, parse_success)
38+
{
39+
parse("tcp://host:42");
40+
EXPECT_EQ(transport, "tcp");
41+
EXPECT_EQ(host, "host");
42+
EXPECT_EQ(port, 42);
43+
44+
parse("TCP://host:42");
45+
EXPECT_EQ(transport, "tcp");
46+
EXPECT_EQ(host, "host");
47+
EXPECT_EQ(port, 42);
48+
}
49+
50+
}

0 commit comments

Comments
 (0)