diff options
author | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-01-22 00:58:54 -0500 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2017-02-01 16:28:34 -0500 |
commit | eb68a687575b31d5d69a8ed9a26a2a0877ebec57 (patch) | |
tree | 72b3b071e737a6ab9adce5a83a42bf3ba01007d3 | |
parent | db92c28ac9f354833753b451e4fba081c75d2564 (diff) | |
download | phosphor-inventory-manager-eb68a687575b31d5d69a8ed9a26a2a0877ebec57.tar.gz phosphor-inventory-manager-eb68a687575b31d5d69a8ed9a26a2a0877ebec57.zip |
Add support for createObjects action
Change-Id: I999a5e506a236eac8ca0944b0e2b003c57612e54
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
-rw-r--r-- | actions.hpp | 11 | ||||
-rw-r--r-- | example/events.d/match1.yaml | 47 | ||||
-rw-r--r-- | manager.cpp | 109 | ||||
-rw-r--r-- | manager.hpp | 4 | ||||
-rw-r--r-- | test/test.cpp | 45 |
5 files changed, 168 insertions, 48 deletions
diff --git a/actions.hpp b/actions.hpp index dfa1d00..634cbc9 100644 --- a/actions.hpp +++ b/actions.hpp @@ -3,6 +3,7 @@ #include <utility> #include <memory> #include "utils.hpp" +#include "types.hpp" namespace phosphor { @@ -48,6 +49,16 @@ inline auto destroyObjects(std::vector<const char*> paths) }; } +/** @brief Create objects action. */ +inline auto createObjects( + const std::map<sdbusplus::message::object_path, Object>& objs) +{ + return [&objs](auto&, auto & m) + { + m.createObjects(objs); + }; +} + /** @brief Set a property action. * * Invoke the requested method with a reference to the requested diff --git a/example/events.d/match1.yaml b/example/events.d/match1.yaml index 2219c9f..0d53657 100644 --- a/example/events.d/match1.yaml +++ b/example/events.d/match1.yaml @@ -2,7 +2,7 @@ description: > An example inventory match rule. events: - - name: Example Match(1) + - name: Example Match description: > Sets the value of ExampleProperty1 on /changeme when the value of ExampleProperty2 on @@ -29,4 +29,49 @@ events: type: string value: changed + - name: Example Match + description: > + Create /createme1 and /createme2 when the value of + ExampleProperty2 on /testing/trigger5 changes to abc123. + type: match + signatures: + - type: signal + interface: org.freedesktop.DBus.Properties + path: /testing/trigger5 + member: PropertiesChanged + filters: + - name: propertyChangedTo + interface: xyz.openbmc_project.Example.Iface2 + property: ExampleProperty2 + value: + type: string + value: abc123 + actions: + - name: createObjects + objs: + /createme1: + xyz.openbmc_project.Example.Iface1: + ExampleProperty1: + value: foo + type: string + xyz.openbmc_project.Example.Iface2: + ExampleProperty2: + value: bar + type: string + ExampleProperty3: + value: 999 + type: int64 + /createme2: + xyz.openbmc_project.Example.Iface1: + ExampleProperty1: + value: bar + type: string + xyz.openbmc_project.Example.Iface2: + ExampleProperty2: + value: foo + type: string + ExampleProperty3: + value: 888 + type: int64 + # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/manager.cpp b/manager.cpp index 83ca75f..1ebcb7f 100644 --- a/manager.cpp +++ b/manager.cpp @@ -132,52 +132,7 @@ void Manager::notify(sdbusplus::message::object_path path, Object object) { try { - - if (object.cbegin() == object.cend()) - throw std::runtime_error( - "No interfaces in " + path.str); - - path.str.insert(0, _root); - - auto obj = _refs.find(path); - if (obj != _refs.end()) - throw std::runtime_error( - obj->first + " already exists"); - - // Create an interface holder for each interface - // provided by the client and group them into - // a container. - InterfaceComposite ref; - - auto i = object.size(); - for (auto& x : object) - { - // Defer sending any signals until the last interface. - auto deferSignals = --i != 0; - auto pMakers = _makers.find(x.first.c_str()); - - if (pMakers == _makers.end()) - throw std::runtime_error( - "Unimplemented interface: " + x.first); - - auto& maker = std::get<MakerType>(pMakers->second); - - auto& props = x.second; - ref.emplace(x.first, maker( - _bus, - path.str.c_str(), - props, - deferSignals)); - } - - if (!ref.empty()) - { - // Hang on to a reference to the object (interfaces) - // so it stays on the bus, and so we can make calls - // to it if needed. - _refs.emplace( - path, std::move(ref)); - } + createObjects({std::make_pair(path, object)}); } catch (const std::exception& e) { @@ -215,6 +170,68 @@ void Manager::destroyObjects( } } +void Manager::createObjects( + const std::map<sdbusplus::message::object_path, Object>& objs) +{ + std::string absPath; + + for (auto& o : objs) + { + auto& relPath = o.first; + auto& ifaces = o.second; + + absPath.assign(_root); + absPath.append(relPath); + + auto obj = _refs.find(absPath); + if (obj != _refs.end()) + { + // This object already exists...skip. + continue; + } + + // Create an interface holder for each interface + // provided by the client and group them into + // a container. + InterfaceComposite ref; + + auto i = ifaces.size(); + for (auto& iface : ifaces) + { + auto& props = iface.second; + + // Defer sending any signals until the last interface. + auto deferSignals = --i != 0; + auto pMakers = _makers.find(iface.first.c_str()); + + if (pMakers == _makers.end()) + { + // This interface is not known. + continue; + } + + auto& maker = std::get<MakerType>(pMakers->second); + + ref.emplace( + iface.first, + maker( + _bus, + absPath.c_str(), + props, + deferSignals)); + } + + if (!ref.empty()) + { + // Hang on to a reference to the object (interfaces) + // so it stays on the bus, and so we can make calls + // to it if needed. + _refs.emplace( + absPath, std::move(ref)); + } + } +} + details::holder::Base& Manager::getInterfaceHolder( const char* path, const char* interface) { diff --git a/manager.hpp b/manager.hpp index 7a01bee..e6c08bf 100644 --- a/manager.hpp +++ b/manager.hpp @@ -103,6 +103,10 @@ class Manager final : void destroyObjects( const std::vector<const char*>& paths); + /** @brief Add objects to DBus. */ + void createObjects( + const std::map<sdbusplus::message::object_path, Object>& objs); + /** @brief Invoke an sdbusplus server binding method. * * Invoke the requested method with a reference to the requested diff --git a/test/test.cpp b/test/test.cpp index 21f89e2..816d471 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -40,7 +40,8 @@ const auto trigger3 = sdbusplus::message::object_path(EXAMPLE_ROOT + "/trigger3"s); const auto trigger4 = sdbusplus::message::object_path(EXAMPLE_ROOT + "/trigger4"s); - +const auto trigger5 = sdbusplus::message::object_path(EXAMPLE_ROOT + + "/trigger5"s); const sdbusplus::message::object_path relDeleteMeOne{"/deleteme1"}; const sdbusplus::message::object_path relDeleteMeTwo{"/deleteme2"}; @@ -78,6 +79,8 @@ struct ExampleService ExampleIface1, ExampleIface2 > t3(bus, trigger3.str.c_str()); sdbusplus::server::object::object < ExampleIface1, ExampleIface2 > t4(bus, trigger4.str.c_str()); + sdbusplus::server::object::object < + ExampleIface1, ExampleIface2 > t5(bus, trigger5.str.c_str()); while (!shutdown) { @@ -456,6 +459,46 @@ void runTests() } } } + + // Validate the create object action. + { + sdbusplus::message::object_path relCreateMe1{"/createme1"}; + sdbusplus::message::object_path relCreateMe2{"/createme2"}; + std::string createMe1{root + relCreateMe1.str}; + std::string createMe2{root + relCreateMe2.str}; + + // Trigger the action. + { + sdbusplus::message::object_path signalPath; + Object signalObject; + + SignalQueue queue( + "path='" + root + "',member='InterfacesAdded'"); + + auto m = set(trigger5.str); + m.append("xyz.openbmc_project.Example.Iface2"); + m.append("ExampleProperty2"); + m.append(sdbusplus::message::variant<std::string>("abc123")); + b.call(m); + { + auto sig{queue.pop()}; + assert(sig); + sig.read(signalPath); + assert(createMe1 == signalPath.str); + sig.read(signalObject); + } + { + auto sig{queue.pop()}; + assert(sig); + sig.read(signalPath); + assert(createMe2 == signalPath.str); + sig.read(signalObject); + } + + auto moreSignals{queue.pop()}; + assert(!moreSignals); + } + } } int main() |