Skip to content

Commit 1bdc5d6

Browse files
committed
Generalized URL parsing in the agent using the URL parser from the agent adapter.
1 parent 16a50e7 commit 1bdc5d6

24 files changed

+398
-405
lines changed

agent_lib/CMakeLists.txt

-2
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ set(AGENT_SOURCES
214214
"${SOURCE_DIR}/source/adapter/agent_adapter/https_session.hpp"
215215
"${SOURCE_DIR}/source/adapter/agent_adapter/session.hpp"
216216
"${SOURCE_DIR}/source/adapter/agent_adapter/session_impl.hpp"
217-
"${SOURCE_DIR}/source/adapter/agent_adapter/url_parser.hpp"
218217
"${SOURCE_DIR}/source/adapter/mqtt/mqtt_adapter.hpp"
219218
"${SOURCE_DIR}/source/adapter/shdr/connector.hpp"
220219
"${SOURCE_DIR}/source/adapter/shdr/shdr_adapter.hpp"
@@ -233,7 +232,6 @@ set(AGENT_SOURCES
233232
"${SOURCE_DIR}/source/loopback_source.cpp"
234233
"${SOURCE_DIR}/source/source.cpp"
235234
"${SOURCE_DIR}/source/adapter/agent_adapter/agent_adapter.cpp"
236-
"${SOURCE_DIR}/source/adapter/agent_adapter/url_parser.cpp"
237235

238236
# src/sink HEADER_FILE_ONLY
239237

src/mtconnect/agent.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,7 @@ namespace mtconnect {
438438
}
439439
}
440440

441-
void Agent::loadDevices(list<DevicePtr> devices, const optional<string> source,
442-
bool force)
441+
void Agent::loadDevices(list<DevicePtr> devices, const optional<string> source, bool force)
443442
{
444443
if (!force && !IsOptionSet(m_options, config::EnableSourceDeviceModels))
445444
{
@@ -460,7 +459,7 @@ namespace mtconnect {
460459
{
461460
oldUuid = *oldDev->getUuid();
462461
}
463-
462+
464463
auto uuid = *device->getUuid();
465464
auto name = *device->getComponentName();
466465

@@ -475,7 +474,7 @@ namespace mtconnect {
475474
s->setOptions({{config::Device, uuid}});
476475
}
477476
}
478-
477+
479478
for (auto src : m_sources)
480479
{
481480
auto adapter = std::dynamic_pointer_cast<source::adapter::Adapter>(src);
@@ -514,7 +513,7 @@ namespace mtconnect {
514513
cerr << f.what() << endl;
515514
}
516515
};
517-
516+
518517
// Gets around a race condition in the loading of adapaters and setting of
519518
// UUID.
520519
if (m_context.isRunning() && !m_context.isPauased())

src/mtconnect/agent.hpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,7 @@ namespace mtconnect {
279279
/// @param[in] deviceXml the device xml as a string
280280
/// @param[in] source the source loading the device
281281
void loadDevices(std::list<DevicePtr> device,
282-
const std::optional<std::string> source = std::nullopt,
283-
bool force = false);
282+
const std::optional<std::string> source = std::nullopt, bool force = false);
284283

285284
/// @brief receive and parse a single device from a source
286285
/// @param[in] deviceXml the device xml as a string
@@ -591,8 +590,10 @@ namespace mtconnect {
591590
void deliverConnectStatus(entity::EntityPtr, const StringList &devices,
592591
bool autoAvailable) override;
593592
void deliverCommand(entity::EntityPtr) override;
594-
void deliverDevice(DevicePtr device) override { m_agent->loadDevices({device}, std::nullopt,
595-
true); }
593+
void deliverDevice(DevicePtr device) override
594+
{
595+
m_agent->loadDevices({device}, std::nullopt, true);
596+
}
596597
void deliverDevices(std::list<DevicePtr> devices) override { m_agent->loadDevices(devices); }
597598

598599
void sourceFailed(const std::string &identity) override { m_agent->sourceFailed(identity); }

src/mtconnect/asset/asset.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ namespace mtconnect {
160160
/// Override to skip the `hash`, `timestamp`, and `removed` properties.
161161
///
162162
/// @param[in,out] sha1 The boost sha1 accumulator
163-
void hash(boost::uuids::detail::sha1 &sha1) const override
163+
void hash(::boost::uuids::detail::sha1 &sha1) const override
164164
{
165-
static const boost::unordered_set<std::string> skip {"hash", "timestamp", "removed"};
165+
static const ::boost::unordered_set<std::string> skip {"hash", "timestamp", "removed"};
166166
entity::Entity::hash(sha1, skip);
167167
}
168168

src/mtconnect/configuration/agent_config.cpp

+12-22
Original file line numberDiff line numberDiff line change
@@ -906,31 +906,21 @@ namespace mtconnect::configuration {
906906

907907
void parseUrl(ConfigOptions &options)
908908
{
909-
string host, protocol, path;
909+
using namespace mtconnect::url;
910910
auto url = *GetOption<string>(options, configuration::Url);
911911

912-
boost::regex pat("^([^:]+)://([^:/]+)(:[0-9]+)?/?(.+)?");
913-
boost::match_results<string::const_iterator> match;
914-
if (boost::regex_match(url, match, pat))
912+
auto parsed = Url::parse(url);
913+
options[configuration::Protocol] = parsed.m_protocol;
914+
options[configuration::Host] = parsed.getHost();
915+
if (parsed.m_port)
916+
options[configuration::Port] = parsed.getPort();
917+
if (parsed.m_path != "/")
915918
{
916-
if (match[1].matched)
917-
options[configuration::Protocol] = string(match[1].first, match[1].second);
918-
if (match[2].matched)
919-
options[configuration::Host] = string(match[2].first, match[2].second);
920-
if (match[3].matched)
921-
{
922-
try
923-
{
924-
options[configuration::Port] =
925-
boost::lexical_cast<int>(string(match[3].first + 1, match[3].second).c_str());
926-
}
927-
catch (boost::bad_lexical_cast &e)
928-
{
929-
LOG(error) << "Cannot intrepret the port for " << match[3] << ": " << e.what();
930-
}
931-
}
932-
if (match[4].matched)
933-
options[configuration::Topics] = StringList {string(match[4].first, match[4].second)};
919+
StringList list;
920+
string topics = parsed.m_path.substr(1, string::npos);
921+
boost::split(list, topics, boost::is_any_of(":"),
922+
boost::token_compress_on);
923+
options[configuration::Topics] = list;
934924
}
935925
}
936926

src/mtconnect/configuration/async_context.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ namespace mtconnect::configuration {
3939
/// @brief removes the copy constructor
4040
AsyncContext(const AsyncContext &) = delete;
4141
~AsyncContext() {}
42-
42+
4343
/// @brief is the context running
4444
/// @returns running status
4545
auto isRunning() { return m_running; }
46-
46+
4747
/// @brief return the paused state
4848
/// @returns the paused state
4949
auto isPauased() { return m_paused; }

src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp

+16-13
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,11 @@ namespace mtconnect {
116116
{
117117
m_options[configuration::MqttHost] = m_options[configuration::Host];
118118
}
119-
119+
120120
auto retain = GetOption<bool>(m_options, configuration::MqttRetain);
121121
if (retain)
122122
m_retain = *retain;
123-
123+
124124
auto qoso = GetOption<string>(m_options, configuration::MqttQOS);
125125

126126
if (qoso)
@@ -133,7 +133,7 @@ namespace mtconnect {
133133
else if (qos == "exactly_once")
134134
m_qos = MqttClient::QOS::exactly_once;
135135
else
136-
LOG(warning) << "Invalid QOS for MQTT Client: " << qos
136+
LOG(warning) << "Invalid QOS for MQTT Client: " << qos
137137
<< ", must be at_most_once, at_least_once, or exactly_once";
138138
}
139139
}
@@ -269,16 +269,19 @@ namespace mtconnect {
269269
m_sinkContract->getCircularBuffer().getBufferSize(), end,
270270
firstSeq, lastSeq, *observations, false);
271271

272-
m_client->asyncPublish(topic, doc, [sampler, topic](std::error_code ec) {
273-
if (!ec)
274-
{
275-
sampler->handlerCompleted();
276-
}
277-
else
278-
{
279-
LOG(warning) << "Async publish failed for " << topic << ": " << ec.message();
280-
}
281-
}, m_retain, m_qos);
272+
m_client->asyncPublish(
273+
topic, doc,
274+
[sampler, topic](std::error_code ec) {
275+
if (!ec)
276+
{
277+
sampler->handlerCompleted();
278+
}
279+
else
280+
{
281+
LOG(warning) << "Async publish failed for " << topic << ": " << ec.message();
282+
}
283+
},
284+
m_retain, m_qos);
282285

283286
return end;
284287
}

src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ namespace mtconnect {
112112
/// @brief Mqtt Client is Connected or not
113113
/// @return `true` when the client was connected
114114
bool isConnected() { return m_client && m_client->isConnected(); }
115-
115+
116116
/// @name Retain and QOS flags
117117
///@{
118118
auto getRetain() { return m_retain; }
@@ -205,7 +205,7 @@ namespace mtconnect {
205205

206206
std::map<std::string, FilterSet> m_filters;
207207
std::map<std::string, std::shared_ptr<AsyncSample>> m_samplers;
208-
208+
209209
bool m_retain {true};
210210
MqttClient::QOS m_qos {MqttClient::QOS::at_least_once};
211211
};

src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
using namespace std;
4040
using namespace mtconnect;
4141
using namespace mtconnect::pipeline;
42+
using namespace mtconnect::url;
4243

4344
namespace mtconnect::source::adapter::agent_adapter {
4445
void AgentAdapterPipeline::build(const ConfigOptions &options)
@@ -51,11 +52,11 @@ namespace mtconnect::source::adapter::agent_adapter {
5152

5253
TransformPtr next =
5354
bind(make_shared<MTConnectXmlTransform>(m_context, m_feedback, m_device, m_uuid));
54-
55+
5556
buildObservationDelivery(next);
5657
buildDeviceDelivery(next);
5758
buildAssetDelivery(next);
58-
59+
5960
applySplices();
6061
}
6162

src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
#include "mtconnect/pipeline/mtconnect_xml_transform.hpp"
2222
#include "mtconnect/source/adapter/adapter.hpp"
2323
#include "mtconnect/source/adapter/adapter_pipeline.hpp"
24+
#include "mtconnect/utilities.hpp"
2425
#include "session.hpp"
25-
#include "url_parser.hpp"
2626

2727
namespace boost::asio::ssl {
2828
class context;
@@ -127,7 +127,7 @@ namespace mtconnect::source::adapter::agent_adapter {
127127
protected:
128128
pipeline::XmlTransformFeedback m_feedback;
129129
AgentAdapterPipeline m_pipeline;
130-
Url m_url;
130+
url::Url m_url;
131131
int m_count = 1000;
132132
std::chrono::milliseconds m_heartbeat;
133133
bool m_reconnecting = false;

src/mtconnect/source/adapter/agent_adapter/http_session.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace mtconnect::source::adapter::agent_adapter {
3333
/// @brief Create a session to connect to the remote agent
3434
/// @param ioc the asio strand to run in
3535
/// @param url URL to connect to
36-
HttpSession(boost::asio::io_context::strand &ioc, const Url &url)
36+
HttpSession(boost::asio::io_context::strand &ioc, const url::Url &url)
3737
: super(ioc, url), m_stream(ioc.context())
3838
{}
3939

src/mtconnect/source/adapter/agent_adapter/https_session.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ namespace mtconnect::source::adapter::agent_adapter {
3636
/// @param ex the strand to run in
3737
/// @param url the url to connect to
3838
/// @param ctx the TLS context
39-
explicit HttpsSession(boost::asio::io_context::strand &ex, const Url &url, ssl::context &ctx)
39+
explicit HttpsSession(boost::asio::io_context::strand &ex, const url::Url &url,
40+
ssl::context &ctx)
4041
: super(ex, url), m_stream(ex.context(), ctx)
4142
{}
4243
~HttpsSession()

src/mtconnect/source/adapter/agent_adapter/session.hpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
#include "mtconnect/config.hpp"
2626
#include "mtconnect/entity/entity.hpp"
27-
#include "url_parser.hpp"
2827

2928
namespace mtconnect::source::adapter {
3029
struct Handler;
@@ -53,7 +52,7 @@ namespace mtconnect::source::adapter::agent_adapter {
5352
/// @param stream `true` if HTTP x-multipart-replace streaming is desired
5453
/// @param next Function to determine what to do on successful read
5554
Request(const std::optional<std::string> &device, const std::string &operation,
56-
const UrlQuery &query, bool stream, Next next)
55+
const url::UrlQuery &query, bool stream, Next next)
5756
: m_sourceDevice(device),
5857
m_operation(operation),
5958
m_query(query),
@@ -65,15 +64,18 @@ namespace mtconnect::source::adapter::agent_adapter {
6564

6665
std::optional<std::string> m_sourceDevice; ///< optional source device
6766
std::string m_operation; ///< The REST operation (probe, current, sample, asset)
68-
UrlQuery m_query; ///< URL Query parameters
67+
url::UrlQuery m_query; ///< URL Query parameters
6968
bool m_stream; ///< `true` if using HTTP long pull
7069
Next m_next; ///< function to call on successful read
7170
int32_t m_agentVersion = 0; ///< agent version if required > 0 for asset requests
7271

7372
/// @brief Given a url, get a formatted target for a given operation
7473
/// @param url The base url
7574
/// @return a string with a new URL path and query (for the GET)
76-
auto getTarget(const Url &url) { return url.getTarget(m_sourceDevice, m_operation, m_query); }
75+
auto getTarget(const url::Url &url)
76+
{
77+
return url.getTarget(m_sourceDevice, m_operation, m_query);
78+
}
7779
};
7880

7981
virtual ~Session() {}

src/mtconnect/source/adapter/agent_adapter/session_impl.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace mtconnect::source::adapter::agent_adapter {
5656

5757
// Objects are constructed with a strand to
5858
// ensure that handlers do not execute concurrently.
59-
SessionImpl(boost::asio::io_context::strand &strand, const Url &url)
59+
SessionImpl(boost::asio::io_context::strand &strand, const url::Url &url)
6060
: m_resolver(strand.context()), m_strand(strand), m_url(url), m_chunk(1 * 1024 * 1024)
6161
{}
6262

@@ -595,7 +595,7 @@ namespace mtconnect::source::adapter::agent_adapter {
595595
std::optional<http::response_parser<http::dynamic_body>> m_chunkParser;
596596
std::optional<http::response_parser<http::string_body>> m_textParser;
597597
asio::io_context::strand m_strand;
598-
Url m_url;
598+
url::Url m_url;
599599

600600
std::function<std::uint64_t(std::uint64_t, boost::string_view, boost::system::error_code &)>
601601
m_chunkHandler;

0 commit comments

Comments
 (0)