Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
set(AGENT_VERSION_MAJOR 2)
set(AGENT_VERSION_MINOR 7)
set(AGENT_VERSION_PATCH 0)
set(AGENT_VERSION_BUILD 8)
set(AGENT_VERSION_BUILD 9)
set(AGENT_VERSION_RC "")

# This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent
Expand Down
2 changes: 0 additions & 2 deletions demo/compose/agent/agent.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
Devices = Devices.xml
SchemaVersion = 2.7
WorkerThreads = 3
MonitorConfigFiles = yes
Port = 5000
JsonVersion = 1

MinCompressFileSize = 10k

Expand Down
3 changes: 1 addition & 2 deletions demo/compose/agent/agentmqtt.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
Devices = Devices.xml
SchemaVersion = 2.7
WorkerThreads = 3
MonitorConfigFiles = yes
Port = 5000
JsonVersion = 1
JsonVersion = 2

MinCompressFileSize = 10k

Expand Down
2 changes: 1 addition & 1 deletion demo/styles/styles.xsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:m="urn:mtconnect.org:MTConnectDevices:2.0" xmlns:s="urn:mtconnect.org:MTConnectStreams:2.0" xmlns:e="urn:mtconnect.org:MTConnectError:2.0" xmlns:js="urn:custom-javascript"
xmlns:m="urn:mtconnect.org:MTConnectDevices:2.7" xmlns:s="urn:mtconnect.org:MTConnectStreams:2.7" xmlns:e="urn:mtconnect.org:MTConnectError:2.7" xmlns:js="urn:custom-javascript"
exclude-result-prefixes="msxsl js" xmlns:msxsl="urn:schemas-microsoft-com:xslt">

<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
Expand Down
6 changes: 5 additions & 1 deletion src/mtconnect/configuration/agent_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,8 @@ namespace mtconnect::configuration {

ConfigOptions options;
AddDefaultedOptions(logger, options,
{{"max_size", "2mb"s},
{{"max_size", ""s},
{"rotation_size", ""s}, // for backward compatibility
{"max_archive_size", "10mb"s},
{"max_index", 9},
{"file_name", defaultFileName},
Expand Down Expand Up @@ -602,8 +603,11 @@ namespace mtconnect::configuration {
auto &archiveLogDirectory = logChannel.m_archiveLogDirectory;
auto &logFileName = logChannel.m_logFileName;

logRotationSize = 2 * 1024 * 1024; // Default to 2MB for log rotation size
maxLogArchiveSize = ConvertFileSize(options, "max_archive_size", maxLogArchiveSize);
logRotationSize = ConvertFileSize(options, "rotation_size", logRotationSize);
logRotationSize = ConvertFileSize(options, "max_size", logRotationSize);

int max_index = *GetOption<int>(options, "max_index");

if (auto sched = GetOption<string>(options, "schedule"))
Expand Down
3 changes: 1 addition & 2 deletions src/mtconnect/entity/json_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@ namespace mtconnect {
return nullptr;
}

EntityPtr JsonParser::parse(FactoryPtr factory, const string& document, const string& version,
ErrorList& errors)
EntityPtr JsonParser::parse(FactoryPtr factory, const string& document, ErrorList& errors)
{
NAMED_SCOPE("entity.json_parser");
EntityPtr entity;
Expand Down
3 changes: 1 addition & 2 deletions src/mtconnect/entity/json_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ namespace mtconnect {
/// @param version the version to parse
/// @param errors Errors that occurred creating the entities
/// @return an entity shared pointer if successful
EntityPtr parse(FactoryPtr factory, const std::string &document, const std::string &version,
ErrorList &errors);
EntityPtr parse(FactoryPtr factory, const std::string &document, ErrorList &errors);

protected:
uint32_t m_version;
Expand Down
16 changes: 8 additions & 8 deletions src/mtconnect/observation/change_observer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,13 @@ namespace mtconnect::observation {
AsyncObserver(boost::asio::io_context::strand &strand,
mtconnect::buffer::CircularBuffer &buffer, FilterSet &&filter,
std::chrono::milliseconds interval, std::chrono::milliseconds heartbeat)
: AsyncResponse(interval),
m_heartbeat(heartbeat),
m_last(std::chrono::system_clock::now()),
m_filter(std::move(filter)),
m_strand(strand),
m_observer(strand),
m_buffer(buffer)
: AsyncResponse(interval),
m_heartbeat(heartbeat),
m_last(std::chrono::system_clock::now()),
m_filter(std::move(filter)),
m_strand(strand),
m_observer(strand),
m_buffer(buffer)
{}

/// @brief default destructor
Expand All @@ -335,7 +335,7 @@ namespace mtconnect::observation {
void handlerCompleted()
{
NAMED_SCOPE("AsyncObserver::handlerCompleted");

m_last = std::chrono::system_clock::now();
if (m_endOfBuffer)
{
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/parser/json_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ namespace mtconnect::parser {
{
entity::ErrorList errors;
entity::JsonParser parser(version);
auto entity = parser.parse(Device::getRoot(), jsonDoc, "2.3", errors);
auto entity = parser.parse(Device::getRoot(), jsonDoc, errors);

if (!errors.empty())
{
Expand Down
35 changes: 29 additions & 6 deletions src/mtconnect/sink/rest_sink/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,37 @@ namespace mtconnect::sink::rest_sink {
void Server::addSwaggerRoutings()
{
auto handler = [&](SessionPtr session, const RequestPtr request) -> bool {
auto pretty = *request->parameter<bool>("pretty");

StringBuffer output;
RenderJson(output, pretty, [this](auto &writer) { renderSwaggerResponse(writer); });
auto json = request->m_accepts.find("json");
auto html = request->m_accepts.find("html");
if (html == string::npos || (json != string::npos && json < html))
{
auto pretty = *request->parameter<bool>("pretty");

session->writeResponse(
make_unique<Response>(status::ok, string(output.GetString()), "application/json"));
StringBuffer output;
RenderJson(output, pretty, [this](auto &writer) { renderSwaggerResponse(writer); });

session->writeResponse(
make_unique<Response>(status::ok, string(output.GetString()), "application/json"));
}
else
{
string response = R"(<!DOCTYPE html>
<html>
<head>
<title>MTConnect API</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist/swagger-ui.css">
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({ url: '/swagger', dom_id: '#swagger-ui' });
</script>
</body>
</html>
)";
session->writeResponse(make_unique<Response>(status::ok, response, "text/html"));
}
return true;
};

Expand Down
8 changes: 8 additions & 0 deletions src/mtconnect/sink/rest_sink/session_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,15 @@ namespace mtconnect::sink::rest_sink {
m_complete = complete;
m_mimeType = mimeType;
m_streaming = true;

auto now = std::chrono::floor<std::chrono::seconds>(std::chrono::system_clock::now());
std::string date = std::format("{:%a, %d %b %Y %T} GMT", now);

auto res = make_shared<http::response<empty_body>>(status::ok, 11);
m_response = res;
res->chunked(true);
res->set(field::server, "MTConnectAgent");
res->set(field::date, date);
res->set(field::connection, "close");
res->set(field::content_type, "multipart/mixed;boundary=" + m_boundary);
res->set(field::expires, "-1");
Expand Down Expand Up @@ -361,6 +365,10 @@ namespace mtconnect::sink::rest_sink {
void SessionImpl<Derived>::addHeaders(const Response &response, Message &res)
{
res->set(http::field::server, "MTConnectAgent");
auto now = std::chrono::floor<std::chrono::seconds>(std::chrono::system_clock::now());
std::string date = std::format("{:%a, %d %b %Y %T} GMT", now);
res->set(http::field::date, date);

if (response.m_close || m_close)
res->set(http::field::connection, "close");
if (response.m_expires == 0s)
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/utilities.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ namespace mtconnect {
using boost::smatch;

auto value = GetOption<string>(options, name);
if (value)
if (value && !value->empty())
{
static const regex pat("([0-9]+)([GgMmKkBb]*)");
smatch match;
Expand Down
8 changes: 4 additions & 4 deletions test_package/agent_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2664,9 +2664,9 @@ TEST_F(AgentTest, should_handle_japanese_characters)
TEST_F(AgentTest, should_have_device_model_change_time_in_the_header_for_v1_7)
{
using namespace nlohmann;

m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "1.7", 4, true, true,
{{configuration::JsonVersion, 2 }});
{{configuration::JsonVersion, 2}});
{
PARSE_JSON_RESPONSE("/current");
json header = doc.at("/MTConnectStreams/Header"_json_pointer);
Expand All @@ -2679,9 +2679,9 @@ TEST_F(AgentTest, should_have_device_model_change_time_in_the_header_for_v1_7)
TEST_F(AgentTest, should_not_have_device_model_change_time_in_the_header_for_pre_v1_7)
{
using namespace nlohmann;

m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "1.6", 4, true, true,
{{configuration::JsonVersion, 2 }});
{{configuration::JsonVersion, 2}});
{
PARSE_JSON_RESPONSE("/current");
json header = doc.at("/MTConnectStreams/Header"_json_pointer);
Expand Down
101 changes: 101 additions & 0 deletions test_package/cutting_tool_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,107 @@ TEST_F(CuttingToolTest, test_extended_cutting_item)
sdoc);
}

TEST_F(CuttingToolTest, test_extended_cutting_tool_with_json_v2)
{
const auto doc =
R"DOC(<CuttingTool assetId="123456.10" serialNumber="10" toolId="123456">
<CuttingToolLifeCycle>
<CutterStatus>
<Status>AVAILABLE</Status>
</CutterStatus>
<ProgramToolNumber>10</ProgramToolNumber>
<Location negativeOverlap="0" positiveOverlap="0" type="POT">13</Location>
<CuttingItems count="12">
<CuttingItem indices="1">
<ItemLife countDirection="UP" initial="0" limit="0" type="PART_COUNT">0</ItemLife>
<ItemLife countDirection="UP" initial="0" limit="0" type="MINUTES">0</ItemLife>
<ItemLife countDirection="UP" initial="0" limit="0" type="WEAR">0</ItemLife>
<x:ItemCutterStatus xmlns:x="okuma.com:OkumaToolAssets">
<Status>AVAILABLE</Status>
</x:ItemCutterStatus>
<x:ItemProgramToolGroup xmlns:x="okuma.com:OkumaToolAssets">0</x:ItemProgramToolGroup>
</CuttingItem>
</CuttingItems>
</CuttingToolLifeCycle>
</CuttingTool>
)DOC";

ErrorList errors;
entity::XmlParser parser;

auto entity = parser.parse(Asset::getRoot(), doc, errors);
ASSERT_EQ(0, errors.size());

auto asset = dynamic_cast<Asset *>(entity.get());
ASSERT_NE(nullptr, asset);

entity::JsonEntityPrinter jprinter(2, true);
auto jdoc = jprinter.print(entity);

EXPECT_EQ(R"({
"CuttingTool": {
"CuttingToolLifeCycle": {
"CutterStatus": {
"Status": [
{
"value": "AVAILABLE"
}
]
},
"CuttingItems": {
"CuttingItem": [
{
"ItemLife": [
{
"value": 0.0,
"countDirection": "UP",
"initial": 0.0,
"limit": 0.0,
"type": "PART_COUNT"
},
{
"value": 0.0,
"countDirection": "UP",
"initial": 0.0,
"limit": 0.0,
"type": "MINUTES"
},
{
"value": 0.0,
"countDirection": "UP",
"initial": 0.0,
"limit": 0.0,
"type": "WEAR"
}
],
"indices": "1",
"x:ItemCutterStatus": {
"Status": "AVAILABLE",
"xmlns:x": "okuma.com:OkumaToolAssets"
},
"x:ItemProgramToolGroup": {
"value": "0",
"xmlns:x": "okuma.com:OkumaToolAssets"
}
}
],
"count": 12
},
"Location": {
"value": "13",
"negativeOverlap": 0,
"positiveOverlap": 0,
"type": "POT"
},
"ProgramToolNumber": "10"
},
"assetId": "123456.10",
"serialNumber": "10",
"toolId": "123456"
}
})", jdoc);
}

TEST_F(CuttingToolTest, test_xmlns_with_top_element_alias)
{
const auto doc =
Expand Down
Loading
Loading