Skip to content

Expose servus_host and servus_port keys #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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: 2 additions & 0 deletions doc/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

# git master

* [82](https://github.com/HBPVis/Servus/pull/20):
Expose servus_host and servus_port keys.
* [80](https://github.com/HBPVis/Servus/pull/80):
Failsafe when Servus implementation can't be created and fallback to dummy.
* [77](https://github.com/HBPVis/Servus/pull/77):
Expand Down
12 changes: 7 additions & 5 deletions servus/avahi/servus.h
Original file line number Diff line number Diff line change
Expand Up @@ -313,16 +313,17 @@ class Servus : public servus::Servus::Impl
static void _resolveCBS(AvahiServiceResolver* resolver, AvahiIfIndex,
AvahiProtocol, AvahiResolverEvent event,
const char* name, const char*, const char*,
const char* host, const AvahiAddress*, uint16_t,
AvahiStringList* txt, AvahiLookupResultFlags flags,
void* servus)
const char* host, const AvahiAddress*,
const uint16_t port, AvahiStringList* txt,
AvahiLookupResultFlags flags, void* servus)
{
((Servus*)servus)->_resolveCB(resolver, event, name, host, txt, flags);
((Servus*)servus)
->_resolveCB(resolver, event, name, host, port, txt, flags);
}

void _resolveCB(AvahiServiceResolver* resolver,
const AvahiResolverEvent event, const char* name,
const char* host, AvahiStringList* txt,
const char* host, const uint16_t port, AvahiStringList* txt,
const AvahiLookupResultFlags flags)
{
// If browsing through the local interface, consider only the local
Expand All @@ -342,6 +343,7 @@ class Servus : public servus::Servus::Impl
{
ValueMap& values = _instanceMap[name];
values["servus_host"] = host;
values["servus_port"] = std::to_string(unsigned(port));
for (; txt; txt = txt->next)
{
const std::string entry(reinterpret_cast<const char*>(
Expand Down
8 changes: 5 additions & 3 deletions servus/dnssd/servus.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,19 +294,21 @@ class Servus : public servus::Servus::Impl
static void resolveCBS_(DNSServiceRef, DNSServiceFlags,
uint32_t /*interfaceIdx*/,
DNSServiceErrorType error, const char* /*name*/,
const char* host, uint16_t /*port*/,
const char* host, const uint16_t port,
uint16_t txtLen, const unsigned char* txt,
Servus* servus)
{
if (error == kDNSServiceErr_NoError)
servus->resolveCB_(host, txtLen, txt);
servus->resolveCB_(host, port, txtLen, txt);
servus->_result = error;
}

void resolveCB_(const char* host, uint16_t txtLen, const unsigned char* txt)
void resolveCB_(const char* host, const uint16_t port, uint16_t txtLen,
const unsigned char* txt)
{
ValueMap& values = _instanceMap[_browsedName];
values["servus_host"] = host;
values["servus_port"] = std::to_string(unsigned(ntohs(port)));

char key[256] = {0};
const char* value = 0;
Expand Down
3 changes: 3 additions & 0 deletions servus/servus.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ static const std::string TEST_DRIVER{"_servus._test"};
* to browse a ZeroConf service. If the Servus library is compiled without
* zeroconf support (@sa isAvailable()), this class does not do anything useful.
*
* The keys 'servus_host' and 'servus_port' are set for discovered instances to
* the values of the implementation-specific dnssd hostname and port.
*
* Example: @include tests/servus.cpp
*/
class Servus
Expand Down
27 changes: 14 additions & 13 deletions servus/test/servus.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2017, Stefan.Eilemann@epfl.ch
/* Copyright (c) 2017-2018, Stefan.Eilemann@epfl.ch
*
* This file is part of Servus <https://github.com/HBPVIS/Servus>
*
Expand All @@ -18,7 +18,7 @@

#include <algorithm>
#include <mutex>
#include <set>
#include <unordered_map>

namespace servus
{
Expand All @@ -31,7 +31,7 @@ namespace
struct
{
std::mutex mutex;
std::set<Servus*> instances;
std::unordered_map<Servus*, std::string> instances;
} _directory;
}

Expand Down Expand Up @@ -60,7 +60,7 @@ class Servus : public servus::Servus::Impl
_instance = getHostname();
else
_instance = instance;
_directory.instances.insert(this);
_directory.instances[this] = _instance;
_announced = true;
return servus::Servus::Result(servus::Result::SUCCESS);
}
Expand Down Expand Up @@ -91,7 +91,7 @@ class Servus : public servus::Servus::Impl
{
std::lock_guard<std::mutex> lock(_directory.mutex);

std::vector<Servus*> diff;
std::vector<std::pair<Servus*, std::string>> diff;
std::set_symmetric_difference(_directory.instances.begin(),
_directory.instances.end(),
_instances.begin(), _instances.end(),
Expand All @@ -100,27 +100,28 @@ class Servus : public servus::Servus::Impl
_instanceMap.clear();
for (auto i : _directory.instances)
{
ValueMap& values = _instanceMap[i->_instance];
ValueMap& values = _instanceMap[i.second];
values.clear();
values["servus_host"] = "localhost";
values["servus_port"] = std::to_string(unsigned(_port));

for (const auto& j : i->_data)
for (const auto& j : i.first->_data)
values[j.first] = j.second;
}

for (auto i : diff)
{
if (_instances.count(i) == 0)
if (_instances.count(i.first) == 0)
{
_instances.insert(i);
_instances[i.first] = i.second;
for (Listener* listener : _listeners)
listener->instanceAdded(i->_instance);
listener->instanceAdded(i.second);
}
else
{
for (Listener* listener : _listeners)
listener->instanceRemoved(i->_instance);
_instances.erase(i);
listener->instanceRemoved(i.second);
_instances.erase(i.first);
}
}
return servus::Servus::Result(servus::Servus::Result::SUCCESS);
Expand All @@ -139,7 +140,7 @@ class Servus : public servus::Servus::Impl
bool _announced{false};
bool _browsing{false};

std::set<Servus*> _instances;
std::unordered_map<Servus*, std::string> _instances;

void _updateRecord() final { /*nop*/}
};
Expand Down
24 changes: 12 additions & 12 deletions tests/itemModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ class WatchRemove : public Watchdog, public servus::Listener
{
}

void instanceAdded(const std::string&) final {}
void instanceAdded(const std::string& instance) final
{
BOOST_CHECK_EQUAL(instance, TEST_INSTANCE);
}

void instanceRemoved(const std::string& instance) final
{
BOOST_CHECK_EQUAL(instance, TEST_INSTANCE);
Expand All @@ -114,10 +118,7 @@ BOOST_GLOBAL_FIXTURE(GlobalQtApp);

BOOST_AUTO_TEST_CASE(invalidAccess)
{
const std::string serviceName =
"_servustest_" + servus::make_UUID().getString() + "._tcp";

servus::Servus service(serviceName);
servus::Servus service(servus::TEST_DRIVER);
const servus::qt::ItemModel model(service);

const QVariant invalidHeader =
Expand All @@ -131,10 +132,7 @@ BOOST_AUTO_TEST_CASE(invalidAccess)

BOOST_AUTO_TEST_CASE(servusItemModel)
{
const std::string serviceName =
"_servustest_" + servus::make_UUID().getString() + "._tcp";

servus::Servus service(serviceName);
servus::Servus service(servus::TEST_DRIVER);
const servus::qt::ItemModel model(service);

WatchAdd watchAdd;
Expand All @@ -146,10 +144,10 @@ BOOST_AUTO_TEST_CASE(servusItemModel)
model.headerData(0, Qt::Horizontal, Qt::DisplayRole)
.toString()
.toStdString();
BOOST_CHECK_EQUAL(header, "Instances for " + serviceName);
BOOST_CHECK_EQUAL(header, "Instances for " + servus::TEST_DRIVER);
BOOST_CHECK(model.data(QModelIndex()) == QVariant());

servus::Servus service2(serviceName);
servus::Servus service2(servus::TEST_DRIVER);
const servus::Servus::Result& result = service2.announce(0, TEST_INSTANCE);
if (result != servus::Result::SUCCESS) // happens on CI VMs
{
Expand Down Expand Up @@ -178,15 +176,17 @@ BOOST_AUTO_TEST_CASE(servusItemModel)
model.data(instanceIndex, Qt::UserRole).toString().toStdString(),
service.get(TEST_INSTANCE, "servus_host"));
BOOST_CHECK(model.data(instanceIndex, Qt::EditRole) == QVariant());
BOOST_REQUIRE_EQUAL(model.rowCount(instanceIndex), 2);
BOOST_REQUIRE_EQUAL(model.rowCount(instanceIndex), 3);
const QModelIndex kv1Index = model.index(0, 0, instanceIndex);
BOOST_CHECK(model.parent(kv1Index) == instanceIndex);
BOOST_CHECK(model.data(kv1Index, Qt::UserRole) == QVariant());
const QVariant kv1 = model.data(kv1Index);
const QVariant kv2 = model.data(model.index(1, 0, instanceIndex));
const QVariant kv3 = model.data(model.index(2, 0, instanceIndex));
BOOST_REQUIRE_EQUAL(model.rowCount(kv1Index), 0);
BOOST_CHECK_EQUAL(kv1.toString().toStdString(), "foo = bar");
BOOST_CHECK(kv2.toString().startsWith("servus_host = "));
BOOST_CHECK(kv3.toString().startsWith("servus_port = "));

WatchRemove watchRemove;
service.addListener(&watchRemove);
Expand Down
3 changes: 3 additions & 0 deletions tests/servus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ void test(const std::string& serviceName)
BOOST_REQUIRE_EQUAL(hosts.size(), 1);
BOOST_CHECK_EQUAL(hosts.front(), std::to_string(port));
BOOST_CHECK(service.containsKey(hosts.front(), "foo"));
BOOST_CHECK(service.containsKey(hosts.front(), "servus_host"));
BOOST_CHECK_EQUAL(service.get(hosts.front(), "servus_port"),
std::to_string(unsigned(port)));
BOOST_CHECK_EQUAL(service.get(hosts.front(), "foo"), "bar");
BOOST_CHECK_EQUAL(service.get("bar", "foo"), std::string());
BOOST_CHECK_EQUAL(service.get(hosts.front(), "foobar"), std::string());
Expand Down