diff --git a/asyncmsg/NameService.h b/asyncmsg/NameService.h index 9fc9494b2dec2fbca44015b1750baf7900039320..fd68e65f7eb4257dfdf1c92c94d4a398d614570b 100644 --- a/asyncmsg/NameService.h +++ b/asyncmsg/NameService.h @@ -4,6 +4,7 @@ #include <vector> #include <string> +#include <map> #include <tuple> #include <cstdint> #include "boost/asio.hpp" @@ -48,11 +49,12 @@ namespace daq { /** * \param[in] partition The IPC partition object. * \param[in] data_networks A list of networks in the format network/netmask. Both IP 4 and 6 are accepted. - * \param[in] is_server The IS server to publish the information to. + * \param[in] is_server The IS server to publish the information to. If the DF_CONFIG_IS_SERVER environment variable + is set, it takes precedence. */ NameService(IPCPartition partition , const std::vector<std::string>& data_networks, - const std::string& is_server = "DF") noexcept; + const std::string& is_server = "DFConfig") noexcept; ~NameService() noexcept; /** \brief Publish IS object with all valid local interfaces and port number. @@ -74,6 +76,26 @@ namespace daq { */ std::vector<boost::asio::ip::tcp::endpoint> lookup(const std::string& prefix) const; + /** \brief Look up all applications starting with the given 'prefix' and return a map of names and endpoints. + * + * \param[in] prefix The search criteria in IS will be 'prefix.*'. + * + * \returns A map of application names and boost ASIO TCP endpoints, exactly one for each remote application. + * + * \throws IS exceptions + */ + std::map<std::string,boost::asio::ip::tcp::endpoint> lookup_names(const std::string& prefix) const; + + /** \brief Look up all applications starting with the given 'prefix' and return a map of names and all endpoints. + * + * \param[in] prefix The search criteria in IS will be 'prefix.*'. + * + * \returns A map of application names and a list of all boost ASIO TCP endpoints that would be available. + * + * \throws IS exceptions + */ + std::map<std::string,std::vector<boost::asio::ip::tcp::endpoint>> lookup_all(const std::string& prefix) const; + /** \brief Resolve a single specific application. * * \param[in] Resolves exactly one specific remote applications. diff --git a/src/NameService.cxx b/src/NameService.cxx index b2244ed3475dd3fdd52203a3ded12d51751bf19b..d1c9f6a97954dcd66f3cdca69439c99b5ed9d292 100644 --- a/src/NameService.cxx +++ b/src/NameService.cxx @@ -15,6 +15,12 @@ namespace daq { : m_partition(partition), m_is_server(is_server) { + + if(const char *server = getenv("DF_CONFIG_IS_SERVER")) { + // override user argument + m_is_server = server; + } + for(const auto & network : data_networks) { m_data_networks.push_back(parse_address_network(network)); } @@ -173,6 +179,66 @@ namespace daq { return results; } + // Look up all applications of given 'type' and return a map of names and endpoints + std::map<std::string,boost::asio::ip::tcp::endpoint> + NameService::lookup_names(const std::string& prefix) const + { + + std::map<std::string,boost::asio::ip::tcp::endpoint> results; + + ISInfoIterator it(m_partition, m_is_server, ISCriteria("MSG_" + prefix + ".*", MsgInfo::type())); + + while(it++) { + std::string name(it.name()); + MsgInfo info; + + it.value(info); + + // match my local interfaces against the list + for(auto& addr_netmask : info.Addresses) { + boost::asio::ip::address addr, mask; + std::tie(addr, mask) = parse_address_network(addr_netmask); + + if(matches(addr, mask)) { + results[name.substr(4)] = boost::asio::ip::tcp::endpoint(addr, info.Port); + break; + } + } + } + + return results; + } + + // Look up all applications of given 'type' and return a map of all names and endpoints that match + std::map<std::string, std::vector<boost::asio::ip::tcp::endpoint>> + NameService::lookup_all(const std::string& prefix) const + { + + std::map<std::string,std::vector<boost::asio::ip::tcp::endpoint>> results; + + ISInfoIterator it(m_partition, m_is_server, ISCriteria("MSG_" + prefix + ".*", MsgInfo::type())); + + while(it++) { + std::string name(it.name()); + MsgInfo info; + + it.value(info); + + // match my local interfaces against the list + for(auto& addr_netmask : info.Addresses) { + boost::asio::ip::address addr, mask; + std::tie(addr, mask) = parse_address_network(addr_netmask); + + if(matches(addr, mask)) { + results[name.substr(4)].push_back(boost::asio::ip::tcp::endpoint(addr, info.Port)); + break; + } + } + } + + return results; + } + boost::asio::ip::tcp::endpoint NameService::resolve(const std::string& name) const