control: Handle updating service states
Add the necessary functions to handle updating the cached services tree
with the service names and owner states for any give path and interface.
A future commit is going to shift the manager's service handling
functions away from being static once all the required objects get an
ability to retrieve their associated manager object.
Change-Id: I6d1c80c3eeaffa6c38d527680454fd98432e8e03
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json/manager.cpp b/control/json/manager.cpp
index b0dc6e3..ec15d18 100644
--- a/control/json/manager.cpp
+++ b/control/json/manager.cpp
@@ -47,7 +47,7 @@
std::vector<std::string> Manager::_activeProfiles;
std::map<std::string,
- std::map<std::pair<std::string, bool>, std::vector<std::string>>>
+ std::map<std::string, std::pair<bool, std::vector<std::string>>>>
Manager::_servTree;
std::map<std::string,
std::map<std::string, std::map<std::string, PropertyVariantType>>>
@@ -148,21 +148,136 @@
// Path not found in cache, therefore owner missing
return false;
}
- for (const auto& serv : itServ->second)
+ for (const auto& service : itServ->second)
{
auto itIntf = std::find_if(
- serv.second.begin(), serv.second.end(),
+ service.second.second.begin(), service.second.second.end(),
[&intf](const auto& interface) { return intf == interface; });
- if (itIntf != std::end(serv.second))
+ if (itIntf != std::end(service.second.second))
{
// Service found, return owner state
- return serv.first.second;
+ return service.second.first;
}
}
// Interface not found in cache, therefore owner missing
return false;
}
+void Manager::setOwner(const std::string& path, const std::string& serv,
+ const std::string& intf, bool isOwned)
+{
+ auto itServ = _servTree.find(path);
+ if (itServ == _servTree.end())
+ {
+ auto intfs = {intf};
+ _servTree[path] = {{serv, std::make_pair(isOwned, intfs)}};
+ return;
+ }
+ for (auto& service : itServ->second)
+ {
+ auto itIntf = std::find_if(
+ service.second.second.begin(), service.second.second.end(),
+ [&intf](const auto& interface) { return intf == interface; });
+ if (itIntf != std::end(service.second.second))
+ {
+ if (service.first == serv)
+ {
+ service.second.first = isOwned;
+ return;
+ }
+ }
+ }
+ auto intfs = {intf};
+ itServ->second[serv] = std::make_pair(isOwned, intfs);
+}
+
+const std::string& Manager::findService(const std::string& path,
+ const std::string& intf)
+{
+ static const std::string empty = "";
+
+ auto itServ = _servTree.find(path);
+ if (itServ != _servTree.end())
+ {
+ for (const auto& service : itServ->second)
+ {
+ auto itIntf = std::find_if(
+ service.second.second.begin(), service.second.second.end(),
+ [&intf](const auto& interface) { return intf == interface; });
+ if (itIntf != std::end(service.second.second))
+ {
+ // Service found, return service name
+ return service.first;
+ }
+ }
+ }
+
+ return empty;
+}
+
+void Manager::addServices(const std::string& path, const std::string& intf,
+ int32_t depth)
+{
+ // Get all subtree objects for the given interface
+ auto objects = util::SDBusPlus::getSubTree(util::SDBusPlus::getBus(), "/",
+ intf, depth);
+ // Add what's returned to the cache of path->services
+ for (auto& itPath : objects)
+ {
+ auto pathIter = _servTree.find(itPath.first);
+ if (pathIter != _servTree.end())
+ {
+ // Path found in cache
+ for (auto& itServ : itPath.second)
+ {
+ auto servIter = pathIter->second.find(itServ.first);
+ if (servIter != pathIter->second.end())
+ {
+ // Service found in cache
+ for (auto& itIntf : itServ.second)
+ {
+ if (std::find(servIter->second.second.begin(),
+ servIter->second.second.end(),
+ itIntf) == servIter->second.second.end())
+ {
+ // Add interface to cache
+ servIter->second.second.emplace_back(itIntf);
+ }
+ }
+ }
+ else
+ {
+ // Service not found in cache
+ auto intfs = {intf};
+ pathIter->second[itServ.first] =
+ std::make_pair(true, intfs);
+ }
+ }
+ }
+ else
+ {
+ // Path not found in cache
+ auto intfs = {intf};
+ _servTree[itPath.first] = {
+ {itPath.second.begin()->first, std::make_pair(true, intfs)}};
+ }
+ }
+}
+
+const std::string& Manager::getService(const std::string& path,
+ const std::string& intf)
+{
+ // Retrieve service from cache
+ const auto& serviceName = findService(path, intf);
+ if (serviceName.empty())
+ {
+ addServices(path, intf, 0);
+ return findService(path, intf);
+ }
+
+ return serviceName;
+}
+
void Manager::addTimer(const TimerType type,
const std::chrono::microseconds interval,
std::unique_ptr<TimerPkg> pkg)