Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 5)
set(AGENT_VERSION_BUILD 6)
set(AGENT_VERSION_RC "")

# This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent
Expand Down
60 changes: 43 additions & 17 deletions src/mtconnect/configuration/agent_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,9 @@ namespace mtconnect::configuration {
cerr << "Loading configuration from:" << *path << endl;

m_configFile = fs::canonical(*path);
addPathFront(m_configPaths, m_configFile.parent_path());
addPathBack(m_dataPaths, m_configFile.parent_path());
m_configPath = m_configFile.parent_path();
addPathFront(m_configPaths, m_configPath);
addPathBack(m_dataPaths, m_configPath);

ifstream file(m_configFile.c_str());
std::stringstream buffer;
Expand Down Expand Up @@ -598,6 +599,7 @@ namespace mtconnect::configuration {
auto &rotationLogInterval = logChannel.m_rotationLogInterval;
auto &logArchivePattern = logChannel.m_logArchivePattern;
auto &logDirectory = logChannel.m_logDirectory;
auto &archiveLogDirectory = logChannel.m_archiveLogDirectory;
auto &logFileName = logChannel.m_logFileName;

maxLogFileSize = ConvertFileSize(options, "max_size", maxLogFileSize);
Expand All @@ -618,29 +620,51 @@ namespace mtconnect::configuration {
auto file_name = *GetOption<string>(options, "file_name");
auto archive_pattern = *GetOption<string>(options, "archive_pattern");

// Default the log directory to the configuration file path.
logDirectory = m_configPath;
logFileName = fs::path(file_name);
logArchivePattern = fs::path(archive_pattern);
if (!logArchivePattern.has_filename())

// Determine the log directory based on the provided file name and archive pattern
if (logFileName.is_absolute())
logDirectory = logFileName.parent_path();
else if (logArchivePattern.is_absolute())
logDirectory = logArchivePattern.parent_path();

// If the log file name is relative and has a parent path, use it to determine the log directory
if (logFileName.is_relative() && logFileName.has_parent_path())
{
logArchivePattern = logArchivePattern / archiveFileName(get<string>(options["file_name"]));
logDirectory = logDirectory / logFileName.parent_path();
logFileName = logFileName.filename();
}
else if (logArchivePattern.is_relative() && logArchivePattern.has_parent_path())
{
logDirectory = logDirectory / logArchivePattern.parent_path();
logArchivePattern = logArchivePattern.filename();
}

if (logArchivePattern.is_relative())
logArchivePattern = fs::current_path() / logArchivePattern;
// Make sure the log archive pattern includes a file name, use the default file name as the
// base.
if (!logArchivePattern.has_filename())
logArchivePattern = logArchivePattern / archiveFileName(get<string>(options["file_name"]));

// Get the log directory from the archive path.
logDirectory = logArchivePattern.parent_path();
// Make the logArchivePattern and logFileName absolute paths
logDirectory = logDirectory.lexically_normal();

// If the file name does not specify a log directory, use the
// archive directory
logFileName = fs::path(file_name);
if (!logFileName.has_parent_path())
if (logArchivePattern.is_relative())
logArchivePattern = logDirectory / logArchivePattern;
logArchivePattern = logArchivePattern.lexically_normal();
archiveLogDirectory = logArchivePattern.parent_path();
fs::create_directories(archiveLogDirectory);

if (logFileName.is_relative())
logFileName = logDirectory / logFileName;
else if (logFileName.is_relative())
logFileName = fs::current_path() / logFileName;
logFileName = logFileName.lexically_normal();
fs::create_directories(logFileName.parent_path());

// Create a text file sink
auto sink = boost::make_shared<text_sink>(
kw::file_name = logFileName, kw::target_file_name = logArchivePattern.filename(),
kw::file_name = logFileName.string(), kw::target_file_name = logArchivePattern.string(),
kw::auto_flush = true, kw::rotation_size = logRotationSize,
kw::open_mode = ios_base::out | ios_base::app, kw::format = formatter);

Expand All @@ -649,7 +673,8 @@ namespace mtconnect::configuration {

// Set up where the rotated files will be stored
sink->locked_backend()->set_file_collector(logr::sinks::file::make_collector(
kw::target = logDirectory, kw::max_size = maxLogFileSize, kw::max_files = max_index));
kw::target = archiveLogDirectory.string(), kw::max_size = maxLogFileSize,
kw::max_files = max_index));

if (rotationLogInterval > 0)
{
Expand Down Expand Up @@ -1248,7 +1273,8 @@ namespace mtconnect::configuration {
}
catch (exception &e)
{
LOG(info) << "Cannot load plugin " << name << " from " << path << " Reason: " << e.what();
LOG(debug) << "Plugin " << name << " from " << path << " not found, Reason: " << e.what()
<< ", trying next path if available.";
}
}

Expand Down
18 changes: 16 additions & 2 deletions src/mtconnect/configuration/agent_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,14 @@ namespace mtconnect {
{
return m_logChannels[channelName].m_logArchivePattern;
}

/// @brief gets the archive log directory
/// @return log directory
const auto &getArchiveLogDirectory(const std::string &channelName = "agent")
{
return m_logChannels[channelName].m_archiveLogDirectory;
}

/// @brief Get the maximum size of all the log files
/// @return the maximum size of all log files
auto getMaxLogFileSize(const std::string &channelName = "agent")
Expand Down Expand Up @@ -260,6 +268,10 @@ namespace mtconnect {
/// @param path the path to add
void addPluginPath(const std::filesystem::path &path) { addPathBack(m_pluginPaths, path); }

///@brief set the config path for testing
///@param path the path to set for the config file directory
void setConfigPath(const std::filesystem::path &path) { m_configPath = path; }

protected:
DevicePtr getDefaultDevice();
void loadAdapters(const ptree &tree, const ConfigOptions &options);
Expand Down Expand Up @@ -295,7 +307,7 @@ namespace mtconnect {
else
{
LOG(debug) << "Cannot find file '" << file << "' "
<< " in path " << path;
<< " in path " << path << ", continuing...";
}
}

Expand All @@ -312,7 +324,7 @@ namespace mtconnect {
if (!ec)
paths.emplace_back(con);
else
LOG(debug) << "Cannot file path: " << path << ", " << ec.message();
LOG(debug) << "Cannot find path: " << path << ", " << ec.message() << ", skipping...";
}

void addPathFront(std::list<std::filesystem::path> &paths, std::filesystem::path path)
Expand Down Expand Up @@ -348,6 +360,7 @@ namespace mtconnect {
{
std::string m_channelName;
std::filesystem::path m_logDirectory;
std::filesystem::path m_archiveLogDirectory;
std::filesystem::path m_logArchivePattern;
std::filesystem::path m_logFileName;

Expand All @@ -374,6 +387,7 @@ namespace mtconnect {
std::string m_devicesFile;
std::filesystem::path m_exePath;
std::filesystem::path m_working;
std::filesystem::path m_configPath;

std::list<std::filesystem::path> m_configPaths;
std::list<std::filesystem::path> m_dataPaths;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ namespace mtconnect {
Requirement("Rotation", ValueType::VECTOR, 3, false),
Requirement("TranslationDataSet", ValueType::DATA_SET, false),
Requirement("RotationDataSet", ValueType::DATA_SET, false)});
transformation->setOrder({"Translation", "TranslationDataSet", "Rotation", "RotationDataSet"});
transformation->setOrder(
{"Translation", "TranslationDataSet", "Rotation", "RotationDataSet"});

auto coordinateSystem = make_shared<Factory>(Requirements {
Requirement("id", true), Requirement("name", false), Requirement("nativeName", false),
Expand Down
3 changes: 2 additions & 1 deletion src/mtconnect/device_model/configuration/motion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ namespace mtconnect {
Requirement("Rotation", ValueType::VECTOR, 3, false),
Requirement("TranslationDataSet", ValueType::DATA_SET, false),
Requirement("RotationDataSet", ValueType::DATA_SET, false)});
transformation->setOrder({"Translation", "TranslationDataSet", "Rotation", "RotationDataSet"});
transformation->setOrder(
{"Translation", "TranslationDataSet", "Rotation", "RotationDataSet"});

static auto motion = make_shared<Factory>(Requirements {
Requirement("id", true), Requirement("parentIdRef", false),
Expand Down
11 changes: 6 additions & 5 deletions src/mtconnect/device_model/configuration/solid_model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ namespace mtconnect {
if (!solidModel)
{
static auto transformation = make_shared<Factory>(
Requirements {Requirement("Translation", ValueType::VECTOR, 3, false),
Requirement("Rotation", ValueType::VECTOR, 3, false),
Requirement("TranslationDataSet", ValueType::DATA_SET, false),
Requirement("RotationDataSet", ValueType::DATA_SET, false)});
transformation->setOrder({"Translation", "TranslationDataSet", "Rotation", "RotationDataSet"});
Requirements {Requirement("Translation", ValueType::VECTOR, 3, false),
Requirement("Rotation", ValueType::VECTOR, 3, false),
Requirement("TranslationDataSet", ValueType::DATA_SET, false),
Requirement("RotationDataSet", ValueType::DATA_SET, false)});
transformation->setOrder(
{"Translation", "TranslationDataSet", "Rotation", "RotationDataSet"});

solidModel = make_shared<Factory>(
Requirements {{"id", true},
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/entity/xml_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ namespace mtconnect::entity {
}
else
{
LOG(warning) << "Unexpected element: " << nodeQName(child);
// LOG(warning) << "Unexpected element: " << nodeQName(child);
errors.emplace_back(
new EntityError("Invalid element '" + nodeQName(child) + "'", qname));
}
Expand Down
15 changes: 14 additions & 1 deletion src/mtconnect/parser/xml_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,26 @@ namespace mtconnect::parser {
{
auto device =
entity::XmlParser::parseXmlNode(Device::getRoot(), nodeset->nodeTab[i], errors);

if (device)
{
deviceList.emplace_back(dynamic_pointer_cast<Device>(device));
}
else
{
LOG(error) << "Failed to parse device, skipping";
}

if (!errors.empty())
{
for (auto &e : errors)
LOG(warning) << "Error parsing device: " << e->what();
{
if (device)
LOG(warning) << "When loading device " << device->get<string>("name")
<< ", A problem was skipped: " << e->what();
else
LOG(error) << "Failed to load device: " << e->what();
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/mtconnect/pipeline/shdr_token_mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ namespace mtconnect {
}
catch (entity::PropertyError &e)
{
LOG(warning) << "Cannot convert value for data item id '" << dataItem->getId()
<< "': " << *token << " - " << e.what();
LOG(debug) << "Cannot convert value for data item id '" << dataItem->getId()
<< "': " << *token << " - " << e.what();
if (schemaVersion >= SCHEMA_VERSION(2, 5) && validation)
{
props.insert_or_assign("quality", "INVALID"s);
Expand Down
3 changes: 3 additions & 0 deletions src/mtconnect/sink/rest_sink/parameter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ namespace mtconnect::sink::rest_sink {
Parameter(const std::string &n, ParameterType t = STRING, UrlPart p = PATH)
: m_name(n), m_type(t), m_part(p)
{}
Parameter(const std::string_view &n, ParameterType t = STRING, UrlPart p = PATH)
: m_name(n), m_type(t), m_part(p)
{}
Parameter(const Parameter &o) = default;

/// @brief to support std::set interface
Expand Down
4 changes: 4 additions & 0 deletions src/mtconnect/sink/rest_sink/response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <boost/beast/http/status.hpp>

#include <filesystem>
#include <list>
#include <unordered_map>

#include "cached_file.hpp"
Expand Down Expand Up @@ -64,6 +65,9 @@ namespace mtconnect {
std::optional<std::string> m_requestId; ///< Request id from websocket sub

CachedFilePtr m_file; ///< Cached file if a file is being returned

/// @brief Additional per-response header fields (e.g. for CORS preflight)
std::list<std::pair<std::string, std::string>> m_fields;
};

using ResponsePtr = std::unique_ptr<Response>;
Expand Down
Loading
Loading