Skip to content

Commit 2c2eb6c

Browse files
author
Senthil Nathan
committed
Changes done for v1.0.4.
1 parent 0b08209 commit 2c2eb6c

File tree

7 files changed

+3057
-14
lines changed

7 files changed

+3057
-14
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes
22

3+
## v1.0.4
4+
* Apr/23/2021
5+
* Added a new function get_tuple_attribute_value to fetch the value of a user given attribute name if present in a user given tuple.
6+
37
## v1.0.3
48
* Apr/20/2021
59
* Added more special operations for rstring, set, list and map. They are sizeEQ, sizeNE, sizeLT, sizeLE, sizeGT and sizeGE.

README.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## Purpose
44
This toolkit offers an improved and a simpler facility for 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.
55

6-
## Main feature
6+
## Major features
77
It provides the following function that can be called from within the IBM Streams application code. This function is designed to use internal in-memory caching in order to be optimal when processing a rule that gets evaluated frequently inside a given IBM Streams Custom operator logic. Such caching is done on a per PE i.e. Linux process thread basis. In addition, it uses C++ reference pointers wherever possible to reduce the overall rule processing time by avoiding unnecessary data copy that can get expensive.
88

99
**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 the dependency is in place, this function can be called from wherever it is needed within the application code.
@@ -54,6 +54,58 @@ if(result == true) {
5454
// It returns a non-zero error when there is an evaluation execution failure.
5555
```
5656

57+
**get_tuple_attribute_value** is another C++ native function provided via this toolkit. This function fetches the value of a user given attribute name if present in a user given tuple. Any valid fully qualified attribute name can be given via a input string argument to this function.
58+
59+
```
60+
// This namespace usage declaration is needed at the top of an application.
61+
use com.ibm.streamsx.eval_predicate::*;
62+
63+
// Schema can include other deeply nested types.
64+
type Person_t = rstring name, rstring title,
65+
int32 id, rstring gender, set<rstring> skills;
66+
type Department_t = rstring name, rstring id,
67+
rstring manager, int32 employeeCnt;
68+
type Employee_t = Person_t employee, Department_t department;
69+
70+
// Let us say that an incoming tuple holds the values as shown below.
71+
mutable Employee_t myEmployee = {};
72+
myEmployee.employee.name = "Jill Doe";
73+
myEmployee.employee.title = "Software Engineer";
74+
myEmployee.employee.id = 452397;
75+
myEmployee.employee.gender = "Female";
76+
myEmployee.employee.skills = {"C++", "Java", "Python", "SPL"};
77+
myEmployee.department.name = "Process Optimization";
78+
myEmployee.department.id = "XJ825";
79+
myEmployee.department.manager = "Mary Williams";
80+
myEmployee.department.employeeCnt = 18;
81+
82+
// Following code snippet shows how a Custom operator logic
83+
// can fetch the value of a given tuple attribute.
84+
mutable int32 error = 0;
85+
// Get the full set<rstring> value of a given tuple attribute name.
86+
rstring attributeName = "employee.skills";
87+
mutable set<rstring> employeeSkills = {};
88+
get_tuple_attribute_value(attributeName, myEmployee,
89+
employeeSkills, error, false);
90+
91+
if(error == 0) {
92+
printStringLn("Tuple attribute value was fetched successfully.");
93+
printStringLn(attributeName + "=" + (rstring)employeeSkills);
94+
} else {
95+
printStringLn("Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
96+
}
97+
98+
// Following is the usage description for the get_tuple_attribute_value function.
99+
//
100+
// Arg1: Fully qualified attribute name
101+
// Arg2: Your tuple
102+
// Arg3: A mutable variable of an appropriate type in which the
103+
// value of a given attribute will be returned.
104+
// Arg4: A mutable int32 variable to receive non-zero error code if any.
105+
// Arg5: A boolean value to enable debug tracing inside this function.
106+
// It is a void function that returns nothing.
107+
```
108+
57109
## Design considerations
58110
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 made available freely 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.
59111

com.ibm.streamsx.eval_predicate/EvalPredicateExample.spl

Lines changed: 212 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/*
99
==================================================================
1010
First created on: Mar/05/2021
11-
Last modified on: Apr/18/2021
11+
Last modified on: Apr/23/2021
1212

1313
This is an example application that shows how to use the
1414
eval_predicate function to evaluate an SPL expression a.k.a
@@ -86,6 +86,13 @@ Following expressions use nested parenthesis.
8686
((a == "hi" || c endsWith 'pqr') && (b contains "xyz")) || (g[4] > 6.7 || id % 8 == 3)
8787
(((a == 'hi') || (x <= 5) || (t == 3.14) || (p > 7)) && ((j == 3) && (y < 1) && (r == 9)) && s endsWith 'Nation')
8888

89+
In addition to showing how to do rule expression processing,
90+
this example also shows another feature of the eval_predicate
91+
toolkit i.e. how to get a value of a specific tuple attribute as
92+
that is expressed via a user provided string input.
93+
In this example, you can search for get_tuple_attribute_value to
94+
see 10 different test cases on that topic.
95+
8996
How can you use this new eval_predicate function?
9097
-------------------------------------------------
9198
Any other application that wants to use this function must
@@ -124,6 +131,13 @@ composite EvalPredicateExample {
124131
expression<boolean> $EVAL_PREDICATE_TRACING :
125132
(boolean)getSubmissionTimeValue("EvalPredicateTracing", "false");
126133

134+
// This constant can be used to specify whether the
135+
// value of the tuple attribute fetched via the
136+
// get_tuple_attribute_value should be displayed on
137+
// the console or not.
138+
expression<boolean> $DISPLAY_FETCHED_ATTRIBUTE_VALUE :
139+
(boolean)getSubmissionTimeValue("DisplayFetchedAttributeValue", "true");
140+
127141
type
128142
// These are types or schema of the tuples that we will use to
129143
// evaluate different kinds of expressions.
@@ -165,6 +179,7 @@ composite EvalPredicateExample {
165179
logic
166180
onTuple S: {
167181
mutable rstring rule = "";
182+
mutable rstring attributeName = "";
168183
mutable int32 error = 0;
169184
mutable boolean result = false;
170185

@@ -322,6 +337,49 @@ composite EvalPredicateExample {
322337
} else {
323338
printStringLn("Testcase 2.4: Evaluation execution failed. Error=" + (rstring)error);
324339
}
340+
341+
// Get the value of a given tuple attribute name.
342+
// Arg1: Fully qualified attribute name
343+
// Arg2: Your tuple
344+
// Arg3: A mutable variable of an appropriate type in which the
345+
// value of a given attribute will be returned.
346+
// Arg4: A mutable int32 variable to receive non-zero error code if any.
347+
// Arg5: A boolean value to enable debug tracing inside this function.
348+
// It is a void method that returns nothing.
349+
//
350+
// 2.5
351+
// Get an int32 value of a given tuple attribute name.
352+
attributeName = "employee.id";
353+
mutable int32 employeeId = 0;
354+
get_tuple_attribute_value(attributeName, myEmployee,
355+
employeeId, error, $EVAL_PREDICATE_TRACING);
356+
357+
if(error == 0) {
358+
printStringLn("Testcase 2.5: Tuple attribute value was fetched successfully.");
359+
360+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
361+
printStringLn(attributeName + "=" + (rstring)employeeId);
362+
}
363+
} else {
364+
printStringLn("Testcase 2.5: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
365+
}
366+
367+
// 2.6
368+
// Get the full set<rstring> value of a given tuple attribute name.
369+
attributeName = "employee.skills";
370+
mutable set<rstring> employeeSkills = {};
371+
get_tuple_attribute_value(attributeName, myEmployee,
372+
employeeSkills, error, $EVAL_PREDICATE_TRACING);
373+
374+
if(error == 0) {
375+
printStringLn("Testcase 2.6: Tuple attribute value was fetched successfully.");
376+
377+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
378+
printStringLn(attributeName + "=" + (rstring)employeeSkills);
379+
}
380+
} else {
381+
printStringLn("Testcase 2.6: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
382+
}
325383

326384
// ============== TESTCASE GROUP 3 ==============
327385
mutable City_t myCity = {};
@@ -524,7 +582,118 @@ composite EvalPredicateExample {
524582
} else {
525583
printStringLn("Testcase 3.13: Evaluation execution failed. Error=" + (rstring)error);
526584
}
585+
586+
// Get the value of a given tuple attribute name.
587+
// Arg1: Fully qualified attribute name
588+
// Arg2: Your tuple
589+
// Arg3: A mutable variable of an appropriate type in which the
590+
// value of a given attribute will be returned.
591+
// Arg4: A mutable int32 variable to receive non-zero error code if any.
592+
// Arg5: A boolean value to enable debug tracing inside this function.
593+
// It is a void method that returns nothing.
594+
//
595+
// 3.14
596+
// Get an rstring value of a given tuple attribute name.
597+
attributeName = "name";
598+
mutable rstring cityName = "";
599+
get_tuple_attribute_value(attributeName, myCity,
600+
cityName, error, $EVAL_PREDICATE_TRACING);
601+
602+
if(error == 0) {
603+
printStringLn("Testcase 3.14: Tuple attribute value was fetched successfully.");
604+
605+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
606+
printStringLn(attributeName + "=" + (rstring)cityName);
607+
}
608+
} else {
609+
printStringLn("Testcase 3.14: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
610+
}
611+
612+
// 3.15
613+
// Get a float32 value of a given tuple attribute name.
614+
attributeName = "details.location.geo.latitude";
615+
mutable float32 latitude = (float32)0.0;
616+
get_tuple_attribute_value(attributeName, myCity,
617+
latitude, error, $EVAL_PREDICATE_TRACING);
618+
619+
if(error == 0) {
620+
printStringLn("Testcase 3.15: Tuple attribute value was fetched successfully.");
621+
622+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
623+
printStringLn(attributeName + "=" + (rstring)latitude);
624+
}
625+
} else {
626+
printStringLn("Testcase 3.15: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
627+
}
628+
629+
// 3.16
630+
// Get a list<rstring>[idx] value of a given tuple attribute name.
631+
attributeName = "details.location.info.businesses[2]";
632+
mutable rstring businessName = "";
633+
get_tuple_attribute_value(attributeName, myCity,
634+
businessName, error, $EVAL_PREDICATE_TRACING);
635+
636+
if(error == 0) {
637+
printStringLn("Testcase 3.16: Tuple attribute value was fetched successfully.");
638+
639+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
640+
printStringLn(attributeName + "=" + (rstring)businessName);
641+
}
642+
} else {
643+
printStringLn("Testcase 3.16: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
644+
}
645+
646+
// 3.17
647+
// Get a map<rstring,rstring>[key] value of a given tuple attribute name.
648+
attributeName = "details.location.info.officials['Mayor']";
649+
mutable rstring mayor = "";
650+
get_tuple_attribute_value(attributeName, myCity,
651+
mayor, error, $EVAL_PREDICATE_TRACING);
652+
653+
if(error == 0) {
654+
printStringLn("Testcase 3.17: Tuple attribute value was fetched successfully.");
655+
656+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
657+
printStringLn(attributeName + "=" + (rstring)mayor);
658+
}
659+
} else {
660+
printStringLn("Testcase 3.17: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
661+
}
662+
663+
// 3.18
664+
// Get the entire list<rstring> value of a given tuple attribute name.
665+
attributeName = "roadwayNumbers";
666+
mutable list<int32> routeNumbers = [];
667+
get_tuple_attribute_value(attributeName, myCity,
668+
routeNumbers, error, $EVAL_PREDICATE_TRACING);
669+
670+
if(error == 0) {
671+
printStringLn("Testcase 3.18: Tuple attribute value was fetched successfully.");
672+
673+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
674+
printStringLn(attributeName + "=" + (rstring)routeNumbers);
675+
}
676+
} else {
677+
printStringLn("Testcase 3.18: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
678+
}
679+
680+
// 3.19
681+
// Get the entire map<rstring,rstring> value of a given tuple attribute name.
682+
attributeName = "housingNumbers";
683+
mutable map<rstring,int32> housingReport = {};
684+
get_tuple_attribute_value(attributeName, myCity,
685+
housingReport, error, $EVAL_PREDICATE_TRACING);
527686

687+
if(error == 0) {
688+
printStringLn("Testcase 3.19: Tuple attribute value was fetched successfully.");
689+
690+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
691+
printStringLn(attributeName + "=" + (rstring)housingReport);
692+
}
693+
} else {
694+
printStringLn("Testcase 3.19: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
695+
}
696+
528697
// ============== TESTCASE GROUP 4 ==============
529698
mutable AccuWeather_t myWeather = {};
530699
myWeather.city = "New York";
@@ -583,6 +752,48 @@ composite EvalPredicateExample {
583752
printStringLn("Testcase 4.2: Evaluation execution failed. Error=" + (rstring)error);
584753
}
585754

755+
// Get the value of a given tuple attribute name.
756+
// Arg1: Fully qualified attribute name
757+
// Arg2: Your tuple
758+
// Arg3: A mutable variable of an appropriate type in which the
759+
// value of a given attribute will be returned.
760+
// Arg4: A mutable int32 variable to receive non-zero error code if any.
761+
// Arg5: A boolean value to enable debug tracing inside this function.
762+
// It is a void method that returns nothing.
763+
//
764+
// 4.3
765+
// Get a list<TUPLE>[idx] value of a given tuple attribute name.
766+
attributeName = "weatherList[0].hourlyTemperatureMap";
767+
mutable map<int64, float64> myTemperatureMap = {};
768+
get_tuple_attribute_value(attributeName, accuWeatherTestData,
769+
myTemperatureMap, error, $EVAL_PREDICATE_TRACING);
770+
771+
if(error == 0) {
772+
printStringLn("Testcase 4.3: Tuple attribute value was fetched successfully.");
773+
774+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
775+
printStringLn(attributeName + "=" + (rstring)myTemperatureMap);
776+
}
777+
} else {
778+
printStringLn("Testcase 4.3: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
779+
}
780+
781+
// 4.4
782+
// Get the entire list<TUPLE> value of a given tuple attribute name.
783+
attributeName = "weatherList";
784+
mutable list<AccuWeather_t> myWeatherList = [];
785+
get_tuple_attribute_value(attributeName, accuWeatherTestData,
786+
myWeatherList, error, $EVAL_PREDICATE_TRACING);
787+
788+
if(error == 0) {
789+
printStringLn("Testcase 4.4: Tuple attribute value was fetched successfully.");
790+
791+
if($DISPLAY_FETCHED_ATTRIBUTE_VALUE == true) {
792+
printStringLn(attributeName + "=" + (rstring)myWeatherList);
793+
}
794+
} else {
795+
printStringLn("Testcase 4.4: Tuple attribute value was not fetched successfully. Error=" + (rstring)error);
796+
}
586797
} // End of onTuple S
587798
} // End of the Custom operator.
588799
} // End of the main composite.

0 commit comments

Comments
 (0)