Skip to content

Commit

Permalink
[JSONRPC] Support method and notification aliases in framework (#1453)
Browse files Browse the repository at this point in the history
* [JSONRPC] Support method and notification aliases in framework

* Don't use std::set

---------

Co-authored-by: Pierre Wielders <[email protected]>
  • Loading branch information
sebaszm and pwielders authored Dec 1, 2023
1 parent 0d2047a commit 469d6c3
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 18 deletions.
25 changes: 22 additions & 3 deletions Source/core/JSONRPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ namespace Core {
auto retval = _handlers.emplace(std::piecewise_construct,
std::make_tuple(methodName),
std::make_tuple(lambda));

if ( retval.second == false ) {
retval.first->second = lambda;
}
Expand All @@ -704,6 +704,25 @@ namespace Core {
retval.first->second = lambda;
}
}
void Register(const string& methodName, const string& primaryName)
{
ASSERT(methodName.empty() == false);
ASSERT(primaryName.empty() == false);

auto retval = _handlers.find(primaryName);
ASSERT(retval != _handlers.end());

auto retvalAlias = _handlers.find(methodName);
ASSERT(retvalAlias == _handlers.end());

// Register the handler under an alternative name.

if ((retval != _handlers.end()) && (retvalAlias == _handlers.end())) {
_handlers.emplace(std::piecewise_construct,
std::make_tuple(methodName),
std::make_tuple(retval->second));
}
}
void Unregister(const string& methodName)
{
HandlerMap::iterator index = _handlers.find(methodName);
Expand Down Expand Up @@ -1078,8 +1097,8 @@ namespace Core {
else {
code = Core::ERROR_PARSE_FAILURE;
result = report.Value().Message();
}
}

return (code);
};
Register(methodName, implementation);
Expand Down
12 changes: 12 additions & 0 deletions Source/plugins/JSONRPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ namespace WPEFramework {
, _service(nullptr)
, _callsign()
, _validate()
, _versions()
, _observers()
, _eventAliases()
{
std::vector<uint8_t> versions = { 1 };

Expand All @@ -41,6 +44,9 @@ namespace WPEFramework {
, _service(nullptr)
, _callsign()
, _validate()
, _versions()
, _observers()
, _eventAliases()
{
_handlers.emplace_back(versions);
}
Expand All @@ -51,6 +57,9 @@ namespace WPEFramework {
, _service(nullptr)
, _callsign()
, _validate(validation)
, _versions()
, _observers()
, _eventAliases()
{
std::vector<uint8_t> versions = { 1 };

Expand All @@ -63,6 +72,9 @@ namespace WPEFramework {
, _service(nullptr)
, _callsign()
, _validate(validation)
, _versions()
, _observers()
, _eventAliases()
{
_handlers.emplace_back(versions);
}
Expand Down
83 changes: 68 additions & 15 deletions Source/plugins/JSONRPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ namespace PluginHost {
}
}
}
void Event(JSONRPC& parent, const string event, const string& parameter, std::function<bool(const string&)>&& sendifmethod) {
void Event(JSONRPC& parent, const string event, const string& parameter, const std::function<bool(const string&)>& sendifmethod) {
for (const Destination& entry : _designators) {
if (!sendifmethod || sendifmethod(entry.second)) {
parent.Notify(entry.first, entry.second + '.' + event, parameter);
Expand All @@ -155,8 +155,10 @@ namespace PluginHost {
Remotes _callbacks;
Destinations _designators;
};

using HandlerList = std::list<Core::JSONRPC::Handler>;
using ObserverMap = std::unordered_map<string, Observer>;
using EventAliasesMap = std::map<string, std::vector<string>>;

class VersionInfo {
public:
Expand Down Expand Up @@ -342,6 +344,10 @@ namespace PluginHost {
{
_handlers.front().Register(methodName, lambda);
}
void Register(const string& methodName, const string& originalName)
{
_handlers.front().Register(methodName, originalName);
}
void Unregister(const string& methodName)
{
_handlers.front().Unregister(methodName);
Expand All @@ -354,6 +360,48 @@ namespace PluginHost {
_versions.emplace_back(name, major, minor, patch);
}

//
// Methods to register alternative event names
// ------------------------------------------------------------------------------------------------------------------------------
void RegisterEventAlias(const string& event, const string& primary)
{
ASSERT(event.empty() == false);
ASSERT(primary.empty() == false);

_adminLock.Lock();

_eventAliases[primary].emplace_back(event);

ASSERT(std::count(_eventAliases[primary].begin(), _eventAliases[primary].end(), event) == 1);

_adminLock.Unlock();
}
void UnregisterEventAlias(const string& event, const string& primary)
{
ASSERT(event.empty() == false);
ASSERT(primary.empty() == false);

_adminLock.Lock();

auto const& entry = _eventAliases.find(primary);
ASSERT(entry != _eventAliases.end());

if (entry != _eventAliases.end()) {
auto it = std::find(entry->second.begin(), entry->second.end(), event);
ASSERT(it != entry->second.end());

if (it != entry->second.end()) {
entry->second.erase(it);

if (entry->second.empty() == true) {
_eventAliases.erase(entry);
}
}
}

_adminLock.Unlock();
}

//
// Methods to send outbound event messages
// ------------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -544,18 +592,7 @@ namespace PluginHost {
// Inherited via IDispatcher::ICallback
// ---------------------------------------------------------------------------------
Core::hresult Event(const string& eventId, const string& parameters) override {
_adminLock.Lock();

ObserverMap::iterator index = _observers.find(eventId);

if (index != _observers.end()) {
index->second.Event(*this, eventId, parameters, std::function<bool(const string&)>());
}

_adminLock.Unlock();

return (Core::ERROR_NONE);

return (InternalNotify(eventId, parameters));
}
Core::hresult Error(const uint32_t channel, const uint32_t id, const uint32_t code, const string& errorText) override {
Core::ProxyType<Web::JSONRPC::Body> message = IFactories::Instance().JSONRPC();
Expand Down Expand Up @@ -710,7 +747,7 @@ namespace PluginHost {
}
return (result);
}
uint32_t InternalNotify(const string& event, const string& parameters, std::function<bool(const string&)>&& sendifmethod = std::function<bool(const string&)>()) const
uint32_t InternalNotify(const string& event, const string& parameters, const std::function<bool(const string&)>& sendifmethod = std::function<bool(const string&)>()) const
{
uint32_t result = Core::ERROR_UNKNOWN_KEY;

Expand All @@ -719,7 +756,22 @@ namespace PluginHost {
ObserverMap::const_iterator index = _observers.find(event);

if (index != _observers.end()) {
const_cast<Observer&>(index->second).Event(const_cast<JSONRPC&>(*this), event, parameters, std::move(sendifmethod));
const_cast<Observer&>(index->second).Event(const_cast<JSONRPC&>(*this), event, parameters, sendifmethod);
}

// See if this is perhaps a registered alias for an event...

EventAliasesMap::const_iterator iter = _eventAliases.find(event);

if (iter != _eventAliases.end()) {

for (const string& alias : iter->second) {
ObserverMap::const_iterator index = _observers.find(alias);

if (index != _observers.end()) {
const_cast<Observer&>(index->second).Event(const_cast<JSONRPC&>(*this), alias, parameters, sendifmethod);
}
}
}

_adminLock.Unlock();
Expand Down Expand Up @@ -750,6 +802,7 @@ namespace PluginHost {
TokenCheckFunction _validate;
VersionList _versions;
ObserverMap _observers;
EventAliasesMap _eventAliases;
};

class EXTERNAL JSONRPCSupportsEventStatus : public PluginHost::JSONRPC {
Expand Down

0 comments on commit 469d6c3

Please sign in to comment.