38#include <boost/filesystem/operations.hpp>
39#include <boost/regex.hpp>
40#include <boost/spirit/include/qi.hpp>
53namespace arg = std::placeholders;
60 connection_file ( aConnectionFile )
85 if (
id != aConnectionDescriptor.
id )
90 if ( uri != aConnectionDescriptor.
uri )
109 std::lock_guard<std::mutex> lLock (
mMutex );
110 std::vector< std::pair<std::string, std::string> > lConnectionFiles;
113 for (
const auto& x: lConnectionFiles)
122 std::lock_guard<std::mutex> lLock (
mMutex );
123 std::vector< std::pair<std::string, std::string> > lConnectionFiles;
126 for (
const auto& x: lConnectionFiles)
139 std::lock_guard<std::mutex> lLock (
mMutex );
143 exception::ConnectionUIDDoesNotExist lExc;
144 log ( lExc ,
"Connection map contains no entries" );
152 exception::ConnectionUIDDoesNotExist lExc;
153 log ( lExc ,
"Device ID , " ,
Quote ( aId ) ,
", does not exist in connection map" );
158 std::shared_ptr< Node > lNode (
NodeTreeBuilder::getInstance().getNodeTree ( lIt->second.address_table , lIt->second.connection_file ) );
159 log (
Info() ,
"ConnectionManager created node tree: " , *lNode );
168 std::lock_guard<std::mutex> lLock (
mMutex );
169 std::shared_ptr< Node > lNode (
NodeTreeBuilder::getInstance().getNodeTree ( aAddressFileExpr , boost::filesystem::current_path() /
"." ) );
170 log (
Info() ,
"ConnectionManager created node tree: " , *lNode );
179 std::lock_guard<std::mutex> lLock (
mMutex );
180 std::shared_ptr< Node > lNode (
NodeTreeBuilder::getInstance().getNodeTree ( aAddressFileExpr , boost::filesystem::current_path() /
"." ) );
181 log (
Info() ,
"ConnectionManager created node tree: " , *lNode );
182 std::shared_ptr<ClientInterface> lClientInterface (
ClientFactory::getInstance().getClient ( aId , aUri , aUserClientActivationList ) );
189 std::vector<std::string> lDevices;
194 lDevices.push_back ( lIt->first );
203 std::vector<std::string> lDevices;
208 boost::cmatch lMatch;
210 if ( boost::regex_match ( lIt->first.c_str() , lMatch , boost::regex ( aRegex ) ) )
212 lDevices.push_back ( lIt->first );
223 std::lock_guard<std::mutex> lLock (
mMutex );
224 log(
Info(),
"ConnectionManager is clearing the address filename -> Node tree cache");
231 std::pair< std::set< std::string >::iterator ,
bool > lInsert =
mPreviouslyOpenedFiles.insert ( aProtocol+ ( aPath.string() ) );
233 if ( ! lInsert.second )
235 log (
Info() ,
"File " ,
Quote ( aProtocol+ ( aPath.string() ) ) ,
" has already been parsed. I am not reparsing and will continue with next document for now but be aware!" );
258 std::pair< std::map< std::string, ConnectionDescriptor >::iterator ,
bool > lInsert =
mConnectionDescriptors.insert ( std::make_pair ( lDescriptor.
id , lDescriptor ) );
260 if ( !lInsert.second )
262 if ( lInsert.first->second == lDescriptor )
264 log (
Info() ,
"Duplicate connection entry found:"
265 "\n > id = " , lDescriptor.
id ,
266 "\n > uri = " , lDescriptor.
uri ,
268 "\n Continuing for now but be aware!" );
272 exception::DuplicatedUID lExc;
273 log ( lExc ,
"Duplicate connection ID " ,
Quote ( lDescriptor.
id ) ,
" found in connections file " ,
274 Quote ( aProtocol+ ( aPath.string() ) ) ,
" but parameters do not match! Bailing!" );
281 log (
Error() ,
"Construction of Connection Descriptor failed. Continuing with next Connection Descriptor for now but be aware!" );
xml_parse_result load_buffer_inplace(void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xpath_node_set select_nodes(const char_t *query, xpath_variable_set *variables=0) const
const_iterator end() const
const_iterator begin() const
static ClientFactory & getInstance()
Static method to retrieve the single instance of the class.
ConnectionManager(const ConnectionManager &)=delete
static void clearAddressFileCache()
Clears cache of Node tree structure for previously-opened address files (thread safe)
std::vector< std::string > getDevices() const
Return all device IDs known to this connection manager.
void CallBack(const std::string &aProtocol, const boost::filesystem::path &aPath, std::vector< uint8_t > &aFile)
Method called once the file specified in the constructor has been opened.
const std::vector< std::string > mUserClientActivationList
std::map< std::string, ConnectionDescriptor > mConnectionDescriptors
A map of connection identifiers to stucts containing details of the parsed XML node.
virtual ~ConnectionManager()
Destructor.
HwInterface getDevice(const std::string &aId)
Retrieves protocol, host, and port from the connection file to create an IPbus Client Retrieves the a...
std::set< std::string > mPreviouslyOpenedFiles
A set of previously opened filenames, so that the same file is not parsed multiple times.
static std::mutex mMutex
A mutex lock to protect access to the factory methods in multithreaded environments.
A class which bundles a node tree and an IPbus client interface together providing everything you nee...
static NodeTreeBuilder & getInstance()
Static method to retrieve the single instance of the class.
void clearAddressFileCache()
Clears address filename -> Node tree cache. NOT thread safe; for tread-safety, use ConnectionManager ...
void ParseSemicolonDelimitedUriList(const std::string &aSemicolonDelimitedUriList, std::vector< std::pair< std::string, std::string > > &aUriList)
Parse a semicolon delimited list of URIs into a vector of protocol/address pairs.
template bool GetXMLattribute< true >(const pugi::xml_node &aNode, const std::string &aAttrName, std::string &aTarget)
void PugiXMLParseResultPrettifier(const pugi::xml_parse_result &aLoadResult, const boost::filesystem::path &aPath, const std::vector< uint8_t > &aFile)
Helper function to make debugging failures when parsing XML files easier.
void OpenFile(const std::string &aProtocol, const std::string &aFilenameExpr, const boost::filesystem::path &aParentPath, const detail::FileCallback_t &aCallback)
Given a protocol and either a URL or a linux shell expression, open the file and call the callback fu...
_Quote< T > Quote(const T &aT)
void log(FatalLevel &aFatal, const T0 &aArg0)
Function to add a log entry at Fatal level.
Annotation for arguments.
A struct to hold the fields of each entry in the XML connections file.
bool operator==(const ConnectionDescriptor &aConnectionDescriptor) const
Comparison operation.
std::string id
An identifier for an individual.
std::string uri
The full uri for making the connection.
std::string address_table
The address table for building the node tree.
ConnectionDescriptor(const pugi::xml_node &aNode, const boost::filesystem::path &aConnectionFile, bool &aSuccess)
Constructor.