Skip to content

Commit a917bfb

Browse files
author
Senthil Nathan
committed
Changes done for v1.0.0.
1 parent e9897e7 commit a917bfb

File tree

8 files changed

+13558
-1
lines changed

8 files changed

+13558
-1
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changes
2+
3+
## v1.0.0
4+
* Apr/05/2021
5+
* Very first release of this toolkit that was tested to support the use of set, list, map and nested tuple attributes in a rule expression.

Makefile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright (C)2020, 2021 International Business Machines Corporation and
2+
# others. All Rights Reserved.
3+
.PHONY: build all distributed clean
4+
5+
ifeq ($(STREAMS_STUDIO_BUILDING), 1)
6+
$(info Building from Streams Studio, use env vars set by studio)
7+
SPLC = $(STREAMS_STUDIO_SC_PATH)
8+
DATA_DIR = $(STREAMS_STUDIO_DATA_DIRECTORY)
9+
OUTPUT_DIR = $(STREAMS_STUDIO_OUTPUT_DIRECTORY)
10+
TOOLKIT_PATH = $(STREAMS_STUDIO_SPL_PATH)
11+
else
12+
$(info build use env settings)
13+
ifndef STREAMS_INSTALL
14+
$(error require streams environment STREAMS_INSTALL)
15+
endif
16+
SPLC = $(STREAMS_INSTALL)/bin/sc
17+
DATA_DIR = data
18+
OUTPUT_DIR1 = output/com.ibm.streamsx.eval_predicate.EvalPredicateExample/BuildConfig
19+
OUTPUT_DIR2 = output/com.ibm.streamsx.eval_predicate.FunctionalTests/BuildConfig
20+
TOOLKIT_PATH =
21+
endif
22+
23+
SPL_MAIN_COMPOSITE1 = com.ibm.streamsx.eval_predicate::EvalPredicateExample
24+
SPL_MAIN_COMPOSITE2 = com.ibm.streamsx.eval_predicate::FunctionalTests
25+
SPLC_FLAGS = -a
26+
SPL_CMD_ARGS ?=
27+
28+
build: distributed
29+
30+
all: clean build
31+
32+
distributed:
33+
$(SPLC) $(SPLC_FLAGS) -M $(SPL_MAIN_COMPOSITE1) --data-dir $(DATA_DIR) --output-dir $(OUTPUT_DIR1) $(SPL_CMD_ARGS)
34+
$(SPLC) $(SPLC_FLAGS) -M $(SPL_MAIN_COMPOSITE2) --data-dir $(DATA_DIR) --output-dir $(OUTPUT_DIR2) $(SPL_CMD_ARGS)
35+
36+
clean:
37+
$(SPLC) $(SPLC_FLAGS) -M $(SPL_MAIN_COMPOSITE1) --data-dir $(DATA_DIR) --output-dir $(OUTPUT_DIR1) -C $(SPL_CMD_ARGS)
38+
$(SPLC) $(SPLC_FLAGS) -M $(SPL_MAIN_COMPOSITE2) --data-dir $(DATA_DIR) --output-dir $(OUTPUT_DIR2) -C $(SPL_CMD_ARGS)
39+
40+
rm -rf output

README.md

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,109 @@
1-
# streamsx.eval_predicate
1+
# Rule processor for IBM Streams
2+
3+
## Purpose
4+
This toolkit offers a simpler and an improved facility for the users to let their externally authored business rules to be consumed either statically or dynamically from within the IBM Streams SPL application code and then process (evaluate) them as the data flows through the application pipeline. Such an evaluation returns a true or false result for every rule that gets processed to indicate whether the rule expression criteria is met or not met.
5+
6+
It provides the following function that can be called from within the IBM Streams application code. This function is designed to use internal caching in order to be optimal when processing a rule that gets evaluated frequently inside a given IBM Streams Custom operator logic. In addition, it uses C++ reference pointers wherever possible to reduce the overall rule processing time by avoiding unnecessary data copy.
7+
8+
**eval_predicate** is a C++ native function provided via this toolkit. IBM Streams applications can add this toolkit as a dependency either via the -t Streams compiler option or by adding this toolkit directory path in the Streams Studio and/or the Microsoft Visual Studio Code. Once this dependency is in place, then this function can be called from wherever it is needed within the application code.
9+
10+
```
11+
// This namespace usage declaration is needed at the top of an application.
12+
use com.ibm.streamsx.eval_predicate::*;
13+
14+
// Schema can include other deeply nested types.
15+
// But, a simple flat tuple schema is used here for illustration.
16+
type Ticker_t = rstring symbol, float32 price, uint32 quantity,
17+
boolean buyOrSell, map<boolean, int32> myMap1;
18+
19+
// Let us say that an incoming tuple holds the values as shown below.
20+
// A given rule expression will get evaluated (processed) based on a
21+
// user given tuple's attribute values.
22+
mutable Ticker_t myTicker = {};
23+
myTicker.symbol = "INTC";
24+
myTicker.price = (float32)79.25;
25+
myTicker.quantity = 1287u;
26+
myTicker.buyOrSell = true;
27+
myTicker.myMap1 = {true:1, false:0};
28+
29+
// Following code snippet shows how a Custom operator logic
30+
// can do the rule processing.
31+
mutable int32 error = 0;
32+
rstring rule27 = "(symbol == 'INTC' && price > 698.56 && quantity == 7492)";
33+
boolean result = eval_predicate(rule27, myTicker, error, false);
34+
35+
if(result == true) {
36+
printStringLn("Rule 27: Evaluation criteria is met.");
37+
} else if(result == false && error == 0) {
38+
printStringLn("Rule 27: Evaluation criteria is not met.");
39+
} else {
40+
printStringLn("Rule 27: Evaluation execution failed. Error=" + (rstring)error);
41+
}
42+
43+
// Following is the usage description for the eval_predicate function.
44+
//
45+
// Arg1: Expression string i.e. your custom rule.
46+
// Arg2: Your tuple carrying the attributes needed for evaluating the rule.
47+
// Arg3: A mutable int32 variable to receive a non-zero eval error code if any.
48+
// (You can refer to top of the impl/include/eval_predicate.h file in the
49+
// streamsx.eval_predicate toolkit for the meaning of a given error code.)
50+
// Arg4: A boolean value to enable debug tracing inside this function.
51+
// It returns true if the rule evaluation criteria is met.
52+
// It returns false and error=0 if the rule evaluation criteria is not met.
53+
// It returns a non-zero error when there is an evaluation execution failure.
54+
```
55+
56+
## Design considerations
57+
This toolkit came into existence for a specific need with which a large enterprise customer approached the author of this toolkit. There is already a built-in function named *evalPredicate* that is available in the official IBM Streams product. However, that function has certain limitations. To fill that gap, this toolkit with its own **eval_predicate** function is being freely made available via the publicly accessible IBMStreams GitHub. The **eval_predicate** function from this toolkit differs from the *evalPredicate* built-in function in the IBM Streams product in the following ways.
58+
59+
1. This new eval_predicate function allows the user defined rule expression to access map based tuple attributes.
60+
61+
2. This new eval_predicate function allows the user defined rule expression to access nested tuple attributes.
62+
63+
3. This new eval_predicate function allows the user defined rule expression to have operational verbs such as contains, startsWith, endsWith, notContains, notStartsWith, notEndsWith.
64+
65+
4. This new eval_predicate function supports the following operations inside the rule.
66+
a. It supports these relational operations: ==, !=, <, <=, >, >=
67+
68+
b. It supports these logical operations: ||, &&
69+
70+
c. It supports these arithmetic operations: +, -, *, /, %
71+
72+
d. It supports these special operations: contains, startsWith, endsWith, notContains, notStartsWith, notEndsWith
73+
74+
e. No bitwise operations are supported at this time.
75+
76+
5. It allows a rule expression that can refer to boolean, integer, float, string, set, list, map and other nested tuple attributes.
77+
78+
6. It allows certain level of subexpression chaining in a rule.
79+
a. Currently, it supports either zero or single level of parenthesis in a rule.
80+
81+
b. There is no support for nested parenthesis right now. It will be available in a future release.
82+
83+
c. Within a given subexpression, one must use the same logical operators.
84+
85+
d. Zero parenthesis is used in this example rule:
86+
"a == 'hi' && b contains 'xyz' && g[4] > 6.7 && id % 8 == 3"
87+
88+
e. Single level parenthesis is used within each subexpression in this example rule:
89+
"(a == 'hi') && (b contains 'xyz' || g[4] > 6.7 || id % 8 == 3)"
90+
91+
f. Support for nested expressions as shown in the examples below will become available in future releases.
92+
"(a == 'hi') && ((b contains 'xyz' || g[4] > 6.7) && id % 8 == 3)"
93+
"(a == 'hi') && (b contains 'xyz' && (g[4] > 6.7 || id % 8 == 3))"
94+
"(a == 'hi') && ((b contains 'xyz') || (g[4] > 6.7) || (id % 8 == 3))"
95+
96+
## Source code
97+
The complete C++ logic for the **eval_predicate** function is available in the *impl/include/eval_predicate.h* file of this repository.
98+
99+
## Example applications
100+
There is a well documented and well tested example application available in the *com.ibm.streamsx.eval_predicate/EvalPredicateExample.spl* file of this repository. Users can browse that example code, compile and run it to become familiar with the usage of the **eval_predicate** function. There is also *com.ibm.streamsx.eval_predicate/FunctionalTests.spl* which is a very comprehensive application that tests the major code paths in the **eval_predicate** function.
101+
102+
At the top-level of this toolkit directory, a Makefile can be found. To build the two example applications mentioned above, one can type `make` from a Linux terminal window by being in that top-level directory. Alternatively, the extracted toolkit directory can also be imported into IBM Streams Studio or Microsoft Visual Studio Code. Before importing, it is a must to rename that Makefile in that top-level directory to *Makefile.org*. Only with that renaming of the Makefile, the example applications will build correctly after importing the toolkit into the Studio development environment.
103+
104+
## Getting an official version of this toolkit
105+
One can clone this repository as needed for making code changes. But, for users who only want to use this toolkit in their applications, it is better to download an official version of this toolkit that has a release tag. In the right hand side column of this web page, you will see the *Releases* section. There, you can click on the *Latest* button and then download the tar.gz file which can be extracted for ready use as a dependency in your IBM Streams application project.
106+
107+
## WHATS NEW
108+
109+
see: [CHANGELOG.md](CHANGELOG.md)

0 commit comments

Comments
 (0)