summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarri Devender Rao <devenrao@in.ibm.com>2018-04-12 09:22:55 -0500
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2018-06-05 02:10:49 +0000
commit80c70610a0ea96cf609387638f9f3f9bee0c581d (patch)
treee07a5f96bff47280cf47980f63b6bce78b491caf
parent0dabe5924d56be25a9bf2277effd2b87c698a9fe (diff)
downloadphosphor-dbus-monitor-80c70610a0ea96cf609387638f9f3f9bee0c581d.tar.gz
phosphor-dbus-monitor-80c70610a0ea96cf609387638f9f3f9bee0c581d.zip
Modify parser and add mako scripts for watch on object path
Added support for watch and callback on 'interface added' signal for the specified object paths. Added mako scripts for events to auto create callback and watch objects for the specified object path groups. Clients specify object paths to watch and callbacks to invoke in the config.yaml file Change-Id: I3fa2ea1520649120b927c0cb83a16e5cace2f24e Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
-rw-r--r--src/example/example.yaml25
-rw-r--r--src/main.cpp9
-rwxr-xr-xsrc/pdmgen.py190
-rw-r--r--src/templates/callbackpathgroup.mako.cpp2
-rw-r--r--src/templates/eventpath.mako.cpp1
-rw-r--r--src/templates/generated.mako.hpp56
6 files changed, 282 insertions, 1 deletions
diff --git a/src/example/example.yaml b/src/example/example.yaml
index ec0a611..b011a26 100644
--- a/src/example/example.yaml
+++ b/src/example/example.yaml
@@ -244,3 +244,28 @@
countbound: 3
op: '>='
bound: 115
+
+- name: errorlog path group
+ class: group
+ group: path
+ members:
+ - meta: PATH
+ path: /xyz/openbmc_project/logging
+
+- name: pathwatch errorlog
+ description: >
+ 'A pathwatch watches on the specified object path goup.
+ pathcallback are actions PDM should take when instructed to do so.'
+
+ class: pathwatch
+ pathwatch: path
+ paths: errorlog path group
+ pathcallback: create errorlog event
+
+- name: create errorlog event
+ description: >
+ 'eventType specifies the type of the SNMP notification.'
+ class: pathcallback
+ pathcallback: eventpath
+ paths: errorlog path group
+ eventType: ErrorTrap
diff --git a/src/main.cpp b/src/main.cpp
index 68cef3e..3b75e3b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -54,6 +54,15 @@ int main(void)
{
watch->callback(Context::START);
}
+ for (auto& watch : ConfigPathWatches::get())
+ {
+ watch->start();
+ }
+
+ for (auto& watch : ConfigPathWatches::get())
+ {
+ watch->callback(Context::START);
+ }
Loop::run();
diff --git a/src/pdmgen.py b/src/pdmgen.py
index 48d4589..c4184fc 100755
--- a/src/pdmgen.py
+++ b/src/pdmgen.py
@@ -354,6 +354,17 @@ class Instance(ConfigEntry):
super(Instance, self).setup(objs)
+class PathInstance(ConfigEntry):
+ '''Path association.'''
+
+ def __init__(self, *a, **kw):
+ super(PathInstance, self).__init__(**kw)
+
+ def setup(self, objs):
+ '''Resolve elements to indices.'''
+ self.path = self.name['path']['path']
+ self.pathmeta = self.name['path']['meta']
+ super(PathInstance, self).setup(objs)
class Group(ConfigEntry):
'''Pop the members keyword for groups.'''
@@ -468,6 +479,27 @@ class GroupOfInstances(ImplicitGroup):
super(GroupOfInstances, self).setup(objs)
+class GroupOfPathInstances(ImplicitGroup):
+ '''A group of path instances.'''
+
+ def __init__(self, *a, **kw):
+ super(GroupOfPathInstances, self).__init__(**kw)
+
+ def setup(self, objs):
+ '''Resolve group members.'''
+
+ def map_member(x):
+ path = get_index(objs, 'pathname', x['path']['path'])
+ pathmeta = get_index(objs, 'meta', x['path']['meta'])
+ pathinstance = get_index(objs, 'pathinstance', x)
+ return (path, pathmeta, pathinstance)
+
+ self.members = map(
+ map_member,
+ self.members)
+
+ super(GroupOfPathInstances, self).setup(objs)
+
class HasPropertyIndex(ConfigEntry):
'''Handle config file directives that require an index to be
@@ -531,6 +563,54 @@ class HasPropertyIndex(ConfigEntry):
super(HasPropertyIndex, self).setup(objs)
+class HasPathIndex(ConfigEntry):
+ '''Handle config file directives that require an index to be
+ constructed.'''
+
+ def __init__(self, *a, **kw):
+ self.paths = kw.pop('paths')
+ super(HasPathIndex, self).__init__(**kw)
+
+ def factory(self, objs):
+ '''Create a group of instances for this index.'''
+
+ members = []
+ path_group = get_index(
+ objs, 'pathgroup', self.paths, config=self.configfile)
+
+ for path in objs['pathgroup'][path_group].members:
+ member = {
+ 'path': path,
+ }
+ members.append(member)
+
+ args = {
+ 'members': members,
+ 'class': 'pathinstancegroup',
+ 'pathinstancegroup': 'pathinstance',
+ 'name': '{0}'.format(self.paths)
+ }
+
+ group = GroupOfPathInstances(configfile=self.configfile, **args)
+ add_unique(group, objs, config=self.configfile)
+ group.factory(objs)
+
+ super(HasPathIndex, self).factory(objs)
+
+ def setup(self, objs):
+ '''Resolve path and instance groups.'''
+
+ self.pathinstances = get_index(
+ objs,
+ 'pathinstancegroup',
+ '{0}'.format(self.paths),
+ config=self.configfile)
+ self.paths = get_index(
+ objs,
+ 'pathgroup',
+ self.paths,
+ config=self.configfile)
+ super(HasPathIndex, self).setup(objs)
class PropertyWatch(HasPropertyIndex):
'''Handle the property watch config file directive.'''
@@ -551,6 +631,23 @@ class PropertyWatch(HasPropertyIndex):
super(PropertyWatch, self).setup(objs)
+class PathWatch(HasPathIndex):
+ '''Handle the path watch config file directive.'''
+
+ def __init__(self, *a, **kw):
+ self.pathcallback = kw.pop('pathcallback', None)
+ super(PathWatch, self).__init__(**kw)
+
+ def setup(self, objs):
+ '''Resolve optional callback.'''
+ if self.pathcallback:
+ self.pathcallback = get_index(
+ objs,
+ 'pathcallback',
+ self.pathcallback,
+ config=self.configfile)
+ super(PathWatch, self).setup(objs)
+
class Callback(HasPropertyIndex):
'''Interface and common logic for callbacks.'''
@@ -558,6 +655,11 @@ class Callback(HasPropertyIndex):
def __init__(self, *a, **kw):
super(Callback, self).__init__(**kw)
+class PathCallback(HasPathIndex):
+ '''Interface and common logic for callbacks.'''
+
+ def __init__(self, *a, **kw):
+ super(PathCallback, self).__init__(**kw)
class ConditionCallback(ConfigEntry, Renderer):
'''Handle the journal callback config file directive.'''
@@ -718,6 +820,19 @@ class Event(Callback, Renderer):
c=self,
indent=indent)
+class EventPath(PathCallback, Renderer):
+ '''Handle the event path callback config file directive.'''
+
+ def __init__(self, *a, **kw):
+ self.eventType = kw.pop('eventType')
+ super(EventPath, self).__init__(**kw)
+
+ def construct(self, loader, indent):
+ return self.render(
+ loader,
+ 'eventpath.mako.cpp',
+ c=self,
+ indent=indent)
class ElogWithMetadata(Callback, Renderer):
'''Handle the elog_with_metadata callback config file directive.'''
@@ -854,6 +969,24 @@ class CallbackGraphEntry(Group):
super(CallbackGraphEntry, self).setup(objs)
+class PathCallbackGraphEntry(Group):
+ '''An entry in a traversal list for groups of callbacks.'''
+
+ def __init__(self, *a, **kw):
+ super(PathCallbackGraphEntry, self).__init__(**kw)
+
+ def setup(self, objs):
+ '''Resolve group members.'''
+
+ def map_member(x):
+ return get_index(
+ objs, 'pathcallback', x, config=self.configfile)
+
+ self.members = map(
+ map_member,
+ self.members)
+
+ super(PathCallbackGraphEntry, self).setup(objs)
class GroupOfCallbacks(ConfigEntry, Renderer):
'''Handle the callback group config file directive.'''
@@ -893,6 +1026,42 @@ class GroupOfCallbacks(ConfigEntry, Renderer):
c=self,
indent=indent)
+class GroupOfPathCallbacks(ConfigEntry, Renderer):
+ '''Handle the callback group config file directive.'''
+
+ def __init__(self, *a, **kw):
+ self.members = kw.pop('members')
+ super(GroupOfPathCallbacks, self).__init__(**kw)
+
+ def factory(self, objs):
+ '''Create a graph instance for this group of callbacks.'''
+
+ args = {
+ 'configfile': self.configfile,
+ 'members': self.members,
+ 'class': 'pathcallbackgroup',
+ 'pathcallbackgroup': 'pathcallback',
+ 'name': self.members
+ }
+
+ entry = PathCallbackGraphEntry(**args)
+ add_unique(entry, objs, config=self.configfile)
+ super(GroupOfPathCallbacks, self).factory(objs)
+
+ def setup(self, objs):
+ '''Resolve graph entry.'''
+
+ self.graph = get_index(
+ objs, 'callbackpathgroup', self.members, config=self.configfile)
+
+ super(GroupOfPathCallbacks, self).setup(objs)
+
+ def construct(self, loader, indent):
+ return self.render(
+ loader,
+ 'callbackpathgroup.mako.cpp',
+ c=self,
+ indent=indent)
class Everything(Renderer):
'''Parse/render entry point.'''
@@ -901,7 +1070,6 @@ class Everything(Renderer):
def classmap(cls, sub=None):
'''Map render item class and subclass entries to the appropriate
handler methods.'''
-
class_map = {
'path': {
'element': Path,
@@ -918,9 +1086,15 @@ class Everything(Renderer):
'watch': {
'property': PropertyWatch,
},
+ 'pathwatch': {
+ 'path': PathWatch,
+ },
'instance': {
'element': Instance,
},
+ 'pathinstance': {
+ 'element': PathInstance,
+ },
'callback': {
'journal': Journal,
'elog': Elog,
@@ -930,6 +1104,10 @@ class Everything(Renderer):
'method': Method,
'resolve callout': ResolveCallout,
},
+ 'pathcallback': {
+ 'eventpath': EventPath,
+ 'grouppath': GroupOfPathCallbacks,
+ },
'condition': {
'count': CountCondition,
},
@@ -1020,10 +1198,15 @@ class Everything(Renderer):
self.propertynames = kw.pop('propertyname', [])
self.propertygroups = kw.pop('propertygroup', [])
self.instances = kw.pop('instance', [])
+ self.pathinstances = kw.pop('pathinstance', [])
self.instancegroups = kw.pop('instancegroup', [])
+ self.pathinstancegroups = kw.pop('pathinstancegroup', [])
self.watches = kw.pop('watch', [])
+ self.pathwatches = kw.pop('pathwatch', [])
self.callbacks = kw.pop('callback', [])
+ self.pathcallbacks = kw.pop('pathcallback', [])
self.callbackgroups = kw.pop('callbackgroup', [])
+ self.pathcallbackgroups = kw.pop('pathcallbackgroup', [])
self.conditions = kw.pop('condition', [])
super(Everything, self).__init__(**kw)
@@ -1047,10 +1230,15 @@ class Everything(Renderer):
pathgroups=self.pathgroups,
propertygroups=self.propertygroups,
instances=self.instances,
+ pathinstances=self.pathinstances,
watches=self.watches,
+ pathwatches=self.pathwatches,
instancegroups=self.instancegroups,
+ pathinstancegroups=self.pathinstancegroups,
callbacks=self.callbacks,
+ pathcallbacks=self.pathcallbacks,
callbackgroups=self.callbackgroups,
+ pathcallbackgroups=self.pathcallbackgroups,
conditions=self.conditions,
indent=Indent()))
diff --git a/src/templates/callbackpathgroup.mako.cpp b/src/templates/callbackpathgroup.mako.cpp
new file mode 100644
index 0000000..33418d5
--- /dev/null
+++ b/src/templates/callbackpathgroup.mako.cpp
@@ -0,0 +1,2 @@
+std::make_unique<GroupOfPathCallbacks<ConfigPathCallbacks>>(
+${indent(1)}ConfigPathCallbackGroups::get()[${c.graph}])\ \ No newline at end of file
diff --git a/src/templates/eventpath.mako.cpp b/src/templates/eventpath.mako.cpp
new file mode 100644
index 0000000..3fa9fb9
--- /dev/null
+++ b/src/templates/eventpath.mako.cpp
@@ -0,0 +1 @@
+std::make_unique<SNMPTrap<${c.eventType}>>()
diff --git a/src/templates/generated.mako.hpp b/src/templates/generated.mako.hpp
index 1b73198..8dbaa20 100644
--- a/src/templates/generated.mako.hpp
+++ b/src/templates/generated.mako.hpp
@@ -12,9 +12,11 @@
#include "errors.hpp"
#include "method.hpp"
#include "propertywatchimpl.hpp"
+#include "pathwatchimpl.hpp"
#include "resolve_errors.hpp"
#include "sdbusplus.hpp"
#include "event.hpp"
+#include "snmp_trap.hpp"
#include "sdevent.hpp"
using namespace std::string_literals;
@@ -75,6 +77,22 @@ struct ConfigInterfaces
}
};
+struct ConfigIntfAddPaths
+{
+ using Paths = std::array<std::string, ${len(pathinstances)}>;
+
+ static auto& get()
+ {
+ static const Paths paths =
+ {
+% for p in pathinstances:
+ "${p.path}"s,
+% endfor
+ };
+ return paths;
+ }
+};
+
struct ConfigProperties
{
using Properties = std::array<std::string, ${len(propertynames)}>;
@@ -186,6 +204,22 @@ struct ConfigPropertyCallbacks
}
};
+struct ConfigPathCallbacks
+{
+ using Callbacks = std::array<std::unique_ptr<Callback>, ${len(pathcallbacks)}>;
+
+ static auto& get()
+ {
+ static const Callbacks pathCallbacks =
+ {
+% for c in pathcallbacks:
+ ${c.construct(loader, indent=indent +3)},
+% endfor
+ };
+ return pathCallbacks;
+ }
+};
+
struct ConfigPropertyWatches
{
using PropertyWatches = std::array<std::unique_ptr<Watch>, ${len(watches)}>;
@@ -207,6 +241,28 @@ struct ConfigPropertyWatches
return propertyWatches;
}
};
+
+struct ConfigPathWatches
+{
+ using PathWatches = std::array<std::unique_ptr<Watch>, ${len(pathwatches)}>;
+
+ static auto& get()
+ {
+ static const PathWatches pathWatches =
+ {
+% for w in pathwatches:
+ std::make_unique<PathWatch<SDBusPlus>>(
+ % if w.pathcallback is None:
+ ConfigIntfAddPaths::get()[${w.pathinstances}]),
+ % else:
+ ConfigIntfAddPaths::get()[${w.pathinstances}],
+ *ConfigPathCallbacks::get()[${w.pathcallback}]),
+ % endif
+% endfor
+ };
+ return pathWatches;
+ }
+};
} // namespace monitoring
} // namespace dbus
} // namespace phosphor
OpenPOWER on IntegriCloud