Skip to content
This repository was archived by the owner on Jul 8, 2022. It is now read-only.
Closed
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
82 changes: 72 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,76 @@ before_install:
- wget https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip && unzip build-wrapper-linux-x86.zip

before_script:
- docker run --name mysql_db -e MYSQL_ROOT_PASSWORD=root -d tangocs/mysql:9.2.2 --sql-mode=""
- CONTAINER=$(docker run --name tango_cs -e TANGO_HOST=127.0.0.1:10000 -e MYSQL_HOST=mysql_db:3306 -e MYSQL_USER=tango -e MYSQL_PASSWORD=tango -e MYSQL_DATABASE=tango --link mysql_db:mysql_db -d tangocs/tango-cs:latest)
- IPADDR=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' $CONTAINER)
- TANGO_HOST=${IPADDR}:10000
- >
docker run
--rm
--name mysql_db
-e MYSQL_ROOT_PASSWORD=root
-e MYSQL_INITDB_SKIP_TZINFO=1
-d
tangocs/mysql:9.2.2
--sql-mode=""
--innodb=OFF
--default-storage-engine=MyISAM
- >
docker run
--rm
--name mysql_db2
-e MYSQL_ROOT_PASSWORD=root
-e MYSQL_INITDB_SKIP_TZINFO=1
-d
tangocs/mysql:9.2.2
--sql-mode=""
--innodb=OFF
--default-storage-engine=MyISAM
- >
docker run
--name tango_cs
-e TANGO_HOST=127.0.0.1:10000
-e MYSQL_HOST=mysql_db:3306
-e MYSQL_USER=tango
-e MYSQL_PASSWORD=tango
-e MYSQL_DATABASE=tango
--link mysql_db:mysq_db
-d
tangocs/tango-cs:latest
- >
docker run
--name tango_cs2
-e TANGO_HOST=127.0.0.1:10000
-e MYSQL_HOST=mysql_db2:3306
-e MYSQL_USER=tango
-e MYSQL_PASSWORD=tango
-e MYSQL_DATABASE=tango
--link mysql_db2:mysq_db2
-d
tangocs/tango-cs:latest
- sleep 5
- docker ps -a
- docker logs tango_cs
- docker logs tango_cs2
- TANGO_HOST_IP=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tango_cs)
- TANGO_HOST_IP2=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tango_cs2)
- TANGO_HOST=${TANGO_HOST_IP}:10000
- docker build --build-arg APP_UID=$(id -u) --build-arg APP_GID=$(id -g) -t cpp_tango .travis/${OS_TYPE}
- docker run --name cpp_tango -e TANGO_HOST=${TANGO_HOST} -e BINTRAY_USER_NAME=tango-ci -e BINTRAY_API_KEY=${CI_BINTRAY_API_KEY} -e COVERALLS_REPO_TOKEN=${COVERALLS_REPO_TOKEN} --link tango_cs:tango_cs -v `pwd`:/home/tango/src -v `pwd`/idl:/home/tango/idl -v `pwd`/cppzmq:/home/tango/cppzmq -v `pwd`/coveralls-cmake:/home/tango/coveralls-cmake -v `pwd`/build-wrapper-linux-x86:/home/tango/build-wrapper-linux-x86 -dit cpp_tango
- >
docker run
--rm
--name cpp_tango
-e TANGO_HOST=${TANGO_HOST}
-e TANGO_HOST2=${TANGO_HOST_IP2}:10000
-e BINTRAY_USER_NAME=tango-ci
-e BINTRAY_API_KEY=${CI_BINTRAY_API_KEY}
-e COVERALLS_REPO_TOKEN=${COVERALLS_REPO_TOKEN}
--link tango_cs
--link tango_cs2
-v `pwd`:/home/tango/src
-v `pwd`/idl:/home/tango/idl
-v `pwd`/cppzmq:/home/tango/cppzmq
-v `pwd`/coveralls-cmake:/home/tango/coveralls-cmake
-v `pwd`/build-wrapper-linux-x86:/home/tango/build-wrapper-linux-x86
-dit
cpp_tango
- .travis/install_tango_idl.sh
- .travis/install_cppzmq.sh
#work around gcov ignored by sonar
Expand All @@ -67,8 +131,6 @@ deploy:

after-script:
- docker stop cpp_tango
- docker rm cpp_tango
- docker stop tango_cs
- docker rm tango_cs
- docker stop mysql_db
- docker rm mysql_db
- docker stop tango_cs tango_cs2
- docker rm tango_cs tango_cs2
- docker stop mysql_db mysql_db2
130 changes: 75 additions & 55 deletions cppapi/client/group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,63 +49,83 @@ bool GroupReply::exception_enabled = false;
//=============================================================================
// class GroupElementFactory
//=============================================================================
GroupElements GroupElementFactory::instanciate (const std::string& p, int tmo_ms)
GroupElements GroupElementFactory::instanciate(
const std::string& name_or_pattern,
int timeout_millis)
{
#if defined(_LOCAL_DEBUGGING)
cout << "GroupElementFactory::instanciate::pattern [" << p << "]" << endl;
#endif
//- a vector to store device names
std::vector<std::string> dnl(0);
//- is <p> a device name or a device name pattern ?
if (p.find('*', 0) == std::string::npos)
{
#if defined(_LOCAL_DEBUGGING)
cout << "\t|- pattern is pure device name" << endl;
#endif
dnl.push_back(p);
}
else
{
int db_port = 0;
std::string db_host, new_pattern;
DbDatum dbd;
parse_name(p, db_host, db_port, new_pattern);

if (db_host.size() == 0) {
Database db;
//- ask the db the list of device matching pattern p
dbd = db.get_device_exported(const_cast<std::string&>(p));
}
else {
ApiUtil *au = ApiUtil::instance();
int db_ind = au->get_db_ind(db_host,db_port);
dbd = ((au->get_db_vect())[db_ind])->get_device_exported(const_cast<std::string&>(new_pattern));
}

//- extract device names from dbd
dbd >> dnl;
#if defined(_LOCAL_DEBUGGING)
cout << "\t|- db.get_device_exported::found ";
cout << dnl.size() << " device names matching pattern" << endl;
for (unsigned int dn = 0; dn < dnl.size(); dn++) {
cout << "\t\t|- " << dnl[dn] << endl;
return create_group_elements(resolve_device_names(name_or_pattern), timeout_millis);
}

GroupElements GroupElementFactory::create_group_elements(const DeviceNames& names, int timeout_millis)
{
GroupElements group_elements;
group_elements.reserve(names.size());

for (DeviceNames::const_iterator name = names.begin(); name != names.end(); ++name)
{
group_elements.push_back(new GroupDeviceElement(*name, timeout_millis));
}
#endif
}
//- build the returned GroupElementList
GroupElements tel(0);
GroupDeviceElement* tde;
for (unsigned int i = 0; i < dnl.size(); i++) {
tde = new GroupDeviceElement(dnl[i],tmo_ms);
if (tde) {
tel.push_back(tde);

return group_elements;
}

DeviceNames GroupElementFactory::resolve_device_names(const std::string& name_or_pattern)
{
const bool is_name = name_or_pattern.find('*') == std::string::npos;

if (is_name)
{
return DeviceNames(1, name_or_pattern);
}
}
#if defined(_LOCAL_DEBUGGING)
cout << "\t|- GroupElementList contains " << tel.size() << " elements" << endl;
#endif
//- return the list to the caller
return tel;
else
{
int db_port = 0;
std::string db_host = "";
std::string name_or_pattern_without_host = "";
parse_name(name_or_pattern, db_host, db_port, name_or_pattern_without_host);

const bool is_local_device = db_host.empty();

if (is_local_device)
{
return resolve_local_device_names(name_or_pattern);
}
else
{
return resolve_remote_device_names(
db_port,
db_host,
name_or_pattern_without_host);
}
}
}

DeviceNames GroupElementFactory::resolve_local_device_names(const std::string& name_or_pattern)
{
std::string& name_or_patern_non_const = const_cast<std::string&>(name_or_pattern);
Database db;
DbDatum db_data = db.get_device_exported(name_or_patern_non_const);

DeviceNames device_names;
device_names.reserve(db_data.size());
db_data >> device_names;
return device_names;
}

DeviceNames GroupElementFactory::resolve_remote_device_names(
int db_port,
std::string& db_host,
std::string& name_or_pattern_without_host)
{
ApiUtil& api_util = *ApiUtil::instance();
const int db_index = api_util.get_db_ind(db_host, db_port);
Database& db = *(api_util.get_db_vect()[db_index]);
DbDatum db_data = db.get_device_exported(name_or_pattern_without_host);

DeviceNames device_names;
device_names.reserve(db_data.size());
db_data >> device_names;
return device_names;
}

void GroupElementFactory::parse_name (const std::string& p, string &db_host,int &db_port,string &dev_pattern)
Expand Down Expand Up @@ -864,7 +884,7 @@ void Group::remove_i (const std::string& p, bool fwd)
#endif
if (name_equals(p)) {
#if defined(_LOCAL_DEBUGGING)
cout << "Group::remove_i::failed to remove " << _p << " (can't remove self)" << endl;
cout << "Group::remove_i::failed to remove " << p << " (can't remove self)" << endl;
#endif
return;
}
Expand Down
18 changes: 12 additions & 6 deletions cppapi/client/group.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,11 @@ class GroupElement;
//=============================================================================
// Misc. Typedefs
//=============================================================================
//- group content (individual devices and/or sub-groups)
typedef std::vector<GroupElement*> GroupElements;
//- group content iterator
typedef GroupElements::iterator GroupElementsIterator;
//-----------------------------------------------------------------------------
//- define what is a list of token (for name pattern management)
typedef std::vector<std::string> TokenList;
typedef std::vector<std::string> DeviceNames;

//=============================================================================
// class ExtRequestDesc : an asynch. request holder for groups
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -585,14 +583,22 @@ class GroupAttrReplyList : public std::vector<GroupAttrReply>
//=============================================================================
class GroupElementFactory
{
friend class Group;

public:
//- instanciatethe GroupElement which name matches the specified pattern with the specified timeout
//- timeout = -1 => do not change the timeout
static GroupElements instanciate (const std::string& p, int tmo = -1);

private:
static void parse_name (const std::string& p, std::string &db_host, int &db_port, std::string &dev_pattern);

static GroupElements create_group_elements(const DeviceNames&, int timeout_millis);
static DeviceNames resolve_device_names(const std::string&);
static DeviceNames resolve_local_device_names(const std::string&);
static DeviceNames resolve_remote_device_names(
int db_port,
std::string& db_host,
std::string& name_or_pattern_without_host);

//- forbidden methods
GroupElementFactory();
~GroupElementFactory();
Expand Down