-
Notifications
You must be signed in to change notification settings - Fork 2
Feat/filter control blocks #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
* Feature/includeparameter (#14) * Add skeleton for inclusion list parameter Extend interface/skeleton for include_list * Input POinter Attempt to add input pointer parameter for control blocks * Definitions outside of if statements * Attempt to map the intended inclusion list * Try Virtual Function to keep Control Block in Explorer * No longer have get return * Attempt to add the meat of the function -Add methods and members to control blocks to get name of control block, specific control blocks within it, and all control blocks within it -add functions in control block explorer to parse inclusion "map" into actionable data name fix * Update psa.cpp Update psa.cpp * Update cvt.cpp * Update asvt.cpp * algorithm cleanup * better cleanup * Update control_block.cpp * Update main.cpp * Finish addressing merge issues and commit hooks -Minor code updates that were lost in merge commit -Bring new code up to standard for cppcheck -Format new code with clang-format * Update _cbxp.c * Streamline Control Block Explorer Class Update control_block_explorer.hpp * Massive refactor -Shave 2 step process down to one -Change serialized json inclusion map to use a vector of strings still split by "dot" operators * Error Handling Logic * BIG UPDATE PR COMMENTS -Switch pre-processing to one hash map function -use try/catch with custom errors rather than passing return codes everywhere -style and name changes -Enforce more rigid parm structure on entry -Fix some behavioral bugs and oversights in inclusion preprocessing -General streamlining and refactoring of functions, methods, classes, etc. * Another Big Refactor -PR comments (mostly style, but streamlining of error code as well) -Reworked base and derived classes to allow for includables to be defined to the base class and include_map to be defined to the base and derived classes * Update ascb.cpp * Update control_block.hpp * . * .. * ... * PR Comments -ASCB pointer deref in ASVT -Minor name changes -Remove double wildcard error -Add control_block_name_ private member and add initialization to constructor -move include_map_ to protected and remove private using statement * Update asvt.cpp * Update asvt.cpp * PR Comments Mostly renaming things streamlining some unnecessary text, parms and strings * Update control_block.cpp * Update main.cpp * Last round of PR comments string compare with == remove vestiges of old mechanisms for control block management name changes minor tweaks * Update cvt.cpp * Update cvt.cpp * Update cvt.cpp * Final comments Update control_block_explorer.cpp * comments * Last Comments * include changes * Last round of comments * debug * Unit testing (#17) * initial commit 1 * cleaned code before include test cases * wrote test cases, need to check with team now * added space after every function * added .value * shell script done * made changes proposed by leonard 1 * PR changes requested by team * added tests to check for ascb and asvt entries whether it be a string or dict * added tests to check for ascb and asvt entries whether it be a string or dict one more place * made minor tweaks * added updates provided by leonard * grouped failure test cases together * grouped error test cases together * removed extra lines * style changes * Feat/oss housekeeping2 (#18) * Set explicit C/C++ standard and cleanup README. Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> * Update contribution guidelines and functional tests. Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> * Cleanup contribution guidelines and debug debug mode. Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> * Cleanup. Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> * Cleanup. Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> * Fix sdist packaging and pyproject.toml metadata. Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> --------- Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> * Fix _C.pyi and removed unused import from cbxp.py. Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> --------- Signed-off-by: Leonard Carcaramo <lcarcaramo@ibm.com> Co-authored-by: Elijah Swift <Elijah.Swift@ibm.com> Co-authored-by: Varun Chennamadhava <varunchennamadhava@ibm.com>
|
DCO signoff seems to be missing on all commits. Maybe consider squashing all of these commits into one commit that has a DCO signoff? |
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
0d354a7 to
954478d
Compare
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
|
Somewhat unrelated, but I think we should remove the trailing spaces from extracted string fields in control blocks. Now that we are extracting more string fields, I am now noticing this more: |
I'm not opposed to that, but I would prefer to keep that out of the scope for this change since we are close to the end of the review for this PR. |
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
| // we need to use a mutex to make this thread safe. | ||
| // Technically we shouldn't need this because the Python GIL, | ||
| // but we will set this up anyways to be safe. | ||
| pthread_mutex_lock(&cbxp_mutex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about it now, this still isn't thread safe because of the static cbxp_result_t. You could potentially have a use after free if CBXP is being called concurrently in multiple threads due to one thread potentially reading a result JSON string from the static cbxp_result_t structure and another thread already freed the buffer before the first thread tries to read it.
Maybe have a separate cbxp_free() to free the pointer and and unlock the mutex? Then I think the API will be fully thread safe. The user will have to explicitely call cbxp_free() for subsequent calls to be made, with the assumption that everything that needed to be read was read before calling cbxp_free(). OpenSSL uses a similar convention to this: https://docs.openssl.org/master/man3/
Also, I think you can use std::mutex here rather than pthread_mutex_t since this is C++ code: https://www.geeksforgeeks.org/cpp/std-mutex-in-cpp/
| "' is not specified in the inclusion list"); | ||
| throw FilterError(); | ||
| } | ||
| options_map_[control_block].filters.push_back(control_block_filter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add debug message indicating that a filter is being added to the options map?
| throw FilterError(); | ||
| } | ||
| cbxp_filter_t filter_data = {del, filter_value}; | ||
| current_filters_[filter_key].push_back(filter_data); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add debug message indicating that a filter is being added to the current filters?
| } | ||
|
|
||
| bool ControlBlock::compare(const nlohmann::json& json_value, | ||
| const std::string& filter_value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add debug messages indicating the comparison that is being performed?
| } | ||
|
|
||
| bool ControlBlock::matchFilter(nlohmann::json& control_block_json) { | ||
| for (const auto& [json_key, json_value] : control_block_json.items()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add debug messages indicating the result and the reason for the result?
| filters = [] | ||
| for control_block_filter in filters: | ||
| if "," in control_block_filter: | ||
| raise CBXPError(CBXPErrorCode.COMMA_IN_FILTER.value, control_block) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the Python interface, it might be cleaner to have maybe a CBXPFilter object and a CBXPFilterOperation enum like the following:
class CBXPFilterOperation(Enum):
EQUAL = "="
LESS_THAN = "<"
GREATER_THAN = ">"
LESS_THAN_OR_EQUAL = "<="
GREATER_THAN_OR_EQUAL = ">="
class CBXPFilter:
def __init__(self, key: str, operation: CBXPFilterOperation, value: Union[str,int]):
self.key = key
self.operation = operation
self.value = valueThen the user would use filters something like this:
from cbxp import cbxp, CBXPFilter, CBXPFilterOperation
filters = [
CBXPFilter(
"assb.assbjbni",
CBXPFilterOperation.EQUAL,
"IBMUSER"
),
CBXPFilter(
"assb.assbjbns",
CBXPFilterOperation.EQUAL,
"BPXAS"
),
CBXPFilter(
"ascbasid",
CBXPFilterOperation.LESS_THAN_OR_EQUAL,
50
)
]
cbdata = cbxp("ascb", includes=["assb"] filters=filters)We would still have to make sure the key and value don't contain any commas, but I think this would be a little bit cleaner than providing a key-value pair string. Instead we would build the key-value pair strings dynamically from the provided CBXPFilter objects. It is a little verbose, but given that the Python interface is intended for more complex automation scenarios rather than just trying to extract control block data on demand like you would with the shell interface, I think this makes sense.
If you want to take a look, I think all you would have to do is add a little code for trimming the trailing spaces in
|
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
Signed-off-by: Elijah Swift <Elijah.Swift@IBM.com>
💡 Issue Reference
Issue: #5
💻 What does this address?
Control block filtering is a valuable enhancement. In basic cases it allows for simple validation that a control block containing the right data is collected, but in more complex cases, it allows users to grab information on just a singular relevant control block or collection of them in a large table.
📟 Implementation Details
The core control block class now has a new unordered map for filtration that is built on object creation. The filter is passed from block to block along with inclusion patterns and validated along the way. At the "end" of the line, the control block's value is validated against that of the filter. In the event of a match, the json data is returned, otherwise an empty json comes back. Large lists of control blocks like ASCB's and ASSB's were edited to filter out these null values, allowing for a true filter.
📋 Is there a test case?
I added the following tests in both the python and the shell test suites (the names in python are fare more descriptive)
test_cbxp_raises_cbxp_error_if_filter_uses_non_included_control_block
test_cbxp_raises_cbxp_error_if_filter_uses_unknown_key
test_cbxp_raises_cbxp_error_if_filter_dict_wrong_size (python only)
test_cbxp_raises_cbxp_error_if_filter_value_not_string (python only)
test_cbxp_raises_cbxp_error_if_no_filter_match
test_cbxp_can_use_basic_filter
test_cbxp_can_use_include_filter_with_generic_include
test_cbxp_can_use_include_filter_with_discrete_include