diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2013-11-15 17:45:36 +0100 |
---|---|---|
committer | Tomas Bzatek <tbzatek@redhat.com> | 2013-11-15 17:45:36 +0100 |
commit | cb1ffc827aa461fcb31cc1de7305d7d611262c90 (patch) | |
tree | 02bf7d71eaa126c11a17047509a678acec530cb2 /src/indmanager | |
parent | aa9cdfa38d112dbfd7805959d9892d1d572b2370 (diff) | |
download | openlmi-providers-cb1ffc827aa461fcb31cc1de7305d7d611262c90.tar.gz openlmi-providers-cb1ffc827aa461fcb31cc1de7305d7d611262c90.tar.xz openlmi-providers-cb1ffc827aa461fcb31cc1de7305d7d611262c90.zip |
indmanager: Introduce common filter checker
The filter checker code was kinda duplicate across providers and no special
plans have been made for it. This change makes passing a filter checker callback
during indication manager creation no longer mandatory and default filter
checker will be used when NULL. However, the list of acceptable classes need
to be registered before first use.
This change also brings greater flexibility of the filter query which may now
consist of multiple limit conditions.
Diffstat (limited to 'src/indmanager')
-rw-r--r-- | src/indmanager/ind_manager.c | 72 | ||||
-rw-r--r-- | src/indmanager/ind_manager.h | 7 |
2 files changed, 73 insertions, 6 deletions
diff --git a/src/indmanager/ind_manager.c b/src/indmanager/ind_manager.c index 446137d..cae141b 100644 --- a/src/indmanager/ind_manager.c +++ b/src/indmanager/ind_manager.c @@ -795,10 +795,6 @@ IMManager* im_create_manager(IMInstGather gather, IMFilterChecker f_checker, *err = IM_ERR_GATHER; return NULL; } - if (!f_checker) { - *err = IM_ERR_FILTER_CHECKER; - return NULL; - } if (!watcher) { *err = IM_ERR_WATCHER; return NULL; @@ -866,6 +862,50 @@ bool im_destroy_manager(IMManager *manager, const CMPIContext *ctx, return true; } +static bool default_ind_filter_cb(IMManager *manager, const CMPISelectExp *filter) +{ + /* Looks for a class to be subscribed and matches it against a list of + * allowed classes. Filter query may contain more conditions, only those + * with a ISA operator are looked for. + */ + CMPIStatus st; + unsigned int i; + + CMPISelectCond *sec = CMGetDoc(filter, &st); + if (!sec) + return false; + CMPICount count = CMGetSubCondCountAndType(sec, NULL, &st); + if (count != 1) + return false; + CMPISubCond *sub = CMGetSubCondAt(sec, 0, &st); + if (!sub) + return false; + count = CMGetPredicateCount(sub, &st); + if (count == 0) + return false; + + for (i = 0; i < count; i++) { + CMPIType type; + CMPIPredOp op; + CMPIString *lhs = NULL; + CMPIString *rhs = NULL; + CMPIPredicate *pred = CMGetPredicateAt(sub, i, &st); + if (!pred) + return false; + st = CMGetPredicateData(pred, &type, &op, &lhs, &rhs); + if (st.rc != CMPI_RC_OK || op != CMPI_PredOp_Isa) + continue; + const char *rhs_str = CMGetCharsPtr(rhs, &st); + if (!rhs_str) + continue; + while (manager->f_allowed_classes[i]) { + if (strcasecmp(rhs_str, manager->f_allowed_classes[i++]) == 0) + return true; + } + } + return false; +} + bool im_verify_filter(IMManager *manager, const CMPISelectExp *filter, const CMPIContext *ctx, IMError *err) { @@ -880,9 +920,18 @@ bool im_verify_filter(IMManager *manager, const CMPISelectExp *filter, *err = IM_ERR_FILTER; return NULL; } + if (!filter && !manager->f_allowed_classes) { + *err = IM_ERR_FILTER_CHECKER; + return NULL; + } manager->ctx_main = ctx; - DEBUG("Verifying filter. Manager = %p, filter checker = %p", manager, manager->f_checker); - return manager->f_checker(filter); + if (manager->f_checker) { + DEBUG("Verifying filter. Manager = %p, filter checker = %p", manager, manager->f_checker); + return manager->f_checker(filter); + } else { + DEBUG("Verifying filter. Manager = %p, using default filter checker", manager); + return default_ind_filter_cb(manager, filter); + } } /* @@ -1009,6 +1058,17 @@ bool im_add_filter(IMManager *manager, CMPISelectExp *filter, return true; } +bool im_register_filter_classes(IMManager *manager, + const char** allowed_classes, IMError *err) +{ + if (!manager) { + *err = IM_ERR_MANAGER; + return false; + } + manager->f_allowed_classes = allowed_classes; + return true; +} + /* * Decrease reference count for polled enumerations. If count is 0, remove * the whole enumerations. diff --git a/src/indmanager/ind_manager.h b/src/indmanager/ind_manager.h index 01aa2e5..383f4b6 100644 --- a/src/indmanager/ind_manager.h +++ b/src/indmanager/ind_manager.h @@ -131,6 +131,7 @@ struct _IMManager { IMFilterChecker f_checker; // filters container IMFilters *filters; + const char** f_allowed_classes; // others IMIndType type; bool running; @@ -196,6 +197,12 @@ bool im_add_filter(IMManager *manager, CMPISelectExp *filter, bool im_remove_filter(IMManager *manager, const CMPISelectExp *filter, const CMPIContext *ctx, IMError *err); +// Register list of classes to be used with a default filter checker +// when callback not given during im_create_manager() +// The allowed_classes array should be kept accessible all the time +bool im_register_filter_classes(IMManager *manager, + const char** allowed_classes, IMError *err); + // Start indications. // Return true when correctly started, false if not and // appropriate IMError is set, |