[PATCH] Add association results filtering

# HG changeset patch # User Kaitlin Rupert <karupert@us.ibm.com> # Date 1194546376 28800 # Node ID 66548720dc50f268b861d336ac295003a9a03ec9 # Parent 404c4803b1b542676c4d283226a7cc3b7f3ab58d Add association results filtering. This adds result filtering so that an association only returns instances that match the result class specified during the query. Such an example is the following: HostedService needs to return VSMS and RPCS instances when queried using CIM_ManagedElement as the result class. However, if CIM_VSMS is specified as the result class, then only the VSMS instance needs to be returned. Signed-off-by: Kaitlin Rupert <karupert@us.ibm.com> diff -r 404c4803b1b5 -r 66548720dc50 std_association.c --- a/std_association.c Fri Nov 02 15:29:38 2007 -0700 +++ b/std_association.c Thu Nov 08 10:26:16 2007 -0800 @@ -47,6 +47,17 @@ void set_reference(struct std_assoc *ass (CMPIValue *)&target, CMPI_ref); } +static bool match_op(const CMPIBroker *broker, + CMPIObjectPath *op, + const char *filter_class) +{ + if ((filter_class == NULL) || + CMClassPathIsA(broker, op, filter_class, NULL)) + return true; + else + return false; +} + static bool match_class(const CMPIBroker *broker, const char *ns, const char *test_class, @@ -58,10 +69,44 @@ static bool match_class(const CMPIBroker if ((test_class == NULL) || (comp_class == NULL) || - CMClassPathIsA(broker, rop, comp_class, NULL)) + match_op(broker, rop, comp_class)) return true; else return false; +} + +static CMPIStatus filter_results(struct inst_list *list, + char *ns, + const char *filter_class, + const CMPIBroker *broker) +{ + struct inst_list result_list; + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIObjectPath *op; + int i; + + result_list = *list; + inst_list_init(list); + + for (i = 0; result_list.list[i] != NULL; i++) { + op = CMGetObjectPath(result_list.list[i], &s); + if ((s.rc != CMPI_RC_OK) || CMIsNullObject(op)) + goto out; + + s = CMSetNameSpace(op, ns); + if (s.rc != CMPI_RC_OK) + goto out; + + if (!match_op(broker, op, filter_class)) + continue; + + inst_list_add(list, result_list.list[i]); + } + +out: + inst_list_free(&result_list); + + return s; } static struct std_assoc * @@ -142,6 +187,20 @@ static CMPIStatus do_assoc(struct std_as goto out; } else { CU_DEBUG("\thandler returned CMPI_RC_OK.\n"); + } + + if (list.list == NULL) { + CU_DEBUG("\tlist is empty.\n"); + goto out; + } + + s = filter_results(&list, + NAMESPACE(ref), + info->result_class, + ctx->brkr); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("\tfilter_results did not return CMPI_RC_OK.\n"); + goto out; } if (list.list == NULL) {

KR> # HG changeset patch KR> # User Kaitlin Rupert <karupert@us.ibm.com> KR> # Date 1194546376 28800 KR> # Node ID 66548720dc50f268b861d336ac295003a9a03ec9 KR> # Parent 404c4803b1b542676c4d283226a7cc3b7f3ab58d KR> Add association results filtering. Thanks! I tested this with HostedResourcePool, since I had it handy. Now, I can specify a result class of just, say, DiskPool and it filters appropriately. Very cool. KR> + result_list = *list; KR> + inst_list_init(list); KR> + KR> + for (i = 0; result_list.list[i] != NULL; i++) { KR> + op = CMGetObjectPath(result_list.list[i], &s); KR> + if ((s.rc != CMPI_RC_OK) || CMIsNullObject(op)) KR> + goto out; KR> + KR> + s = CMSetNameSpace(op, ns); KR> + if (s.rc != CMPI_RC_OK) KR> + goto out; KR> + KR> + if (!match_op(broker, op, filter_class)) KR> + continue; KR> + KR> + inst_list_add(list, result_list.list[i]); KR> + } KR> + KR> +out: KR> + inst_list_free(&result_list); I think it's a little weird to call your temporary list "result_list" and then free it before you return. Might be a little confusing to someone reading your code without the context of this being a revision on a previous version :) I'll apply this, but I think it would be nice to get a little follow-on patch to clean up the naming at some point :-D -- Dan Smith IBM Linux Technology Center Open Hypervisor Team email: danms@us.ibm.com
participants (2)
-
Dan Smith
-
Kaitlin Rupert