Drools comparing objects in working memory - drools

I am trying to accumulate similar objects in working memory and set actions based on object attributes. My Rule: 3 or more procedures done on the same date for a patient by the same provider. Condition: Same date of service and same provider ID Action: 100% for 1st procedure, 50% for 2nd procedure and 25% for remaining. Each line item contains details about the procedure.
My Model object:
public class LineItem {
private Date dateOfService;
private String procedureCode;
private String providerID;
private double billedAmount;
private double allowableAmount;
//getters and setters
}
Drools Rule:
**rule "Multiple Procedures done on the same day by Same Provider"**
lock-on-active true
when
$lineItem1 : LineLevelData ( $dateOfService : dateOfService , $providerId : providerId, reasonCode == null, $lineNumber : lineNumber )
and
$lineItem2 : LineLevelData ( lineNumber!= $lineNumber , dateOfService == $dateOfService , providerId == $providerId, reasonCode == null )
and
accumulate( $lineItem: LineLevelData( dateOfService == $dateOfService , providerId == $providerId, reasonCode == null );
$list: collectList( $lineItem ) )
then
System.out.println("List size: " + $list.size () );
for ( int i = 0; i < $list.size(); i++ ){
LineLevelData lineItem = (LineLevelData)$list.get(i);
if(i == 0){
modify(lineItem){ setReimbursementAmount(0.8* ( lineItem.getBilledAmount() ) )
};
System.out.println("Line Number: " + lineItem.getLineNumber() );
}
else if(i == 1){
modify(lineItem) { setReimbursementAmount(0.5* (lineItem.getBilledAmount() ) )
};
System.out.println("Line Number: " + lineItem.getLineNumber() );
}
else {
modify(lineItem ){ setReimbursementAmount(0.25* (lineItem.getBilledAmount() ) )
};
System.out.println("Line Number: " + lineItem.getLineNumber() );
}
}
Java code:
LineLevelData line1Item = new LineLevelData();
line1Item.setLineNumber(1);
line1Item.setProcedureCode("99201");
line1Item.setDateOfService(new GregorianCalendar(2017, 9, 15).getTime());
line1Item.setBilledAmount(1000);
line1Item.setProviderId("670112");
billLineItems.add(line1Item);
LineLevelData line2Item = new LineLevelData();
line2Item.setLineNumber(2);
line2Item.setProcedureCode("99205");
**line2Item.setDateOfService(new GregorianCalendar(2017, 8, 20).getTime());
line2Item.setProviderId("670118");**
line2Item.setBilledAmount(1500);
billLineItems.add(line2Item);
LineLevelData line3Item = new LineLevelData();
line3Item.setLineNumber(3);
line3Item.setProcedureCode("99049");
**line3Item.setDateOfService(new GregorianCalendar(2017, 8, 20).getTime());
line3Item.setProviderId("670118");**
line3Item.setBilledAmount(1000);
billLineItems.add(line3Item);
LineLevelData line4Item = new LineLevelData();
line4Item.setLineNumber(4);
line4Item.setProcedureCode("99058");
**line4Item.setDateOfService(new GregorianCalendar(2017, 8, 20).getTime());**
line4Item.setBilledAmount(520);
**line4Item.setProviderId("670118");**
billLineItems.add(line4Item);
//Inserting facts in working memory
for(LineLevelData billLineItem : buildBillLineItems()){
kSession.insert(billLineItem);
log.info("Inserted Line Item : " + billLineItem.getLineNumber());
}
int rulesFired = kSession.fireAllRules(new RuleNameEqualsAgendaFilter("Multiple Procedures done on the same day by Same Provider"));
According to my test above line items with line number 2 , 3 and 4 should be updated. Instead I am getting line number 1, 3 and 4.
Rule Output:
List size: 3
Line Number: 4
Line Number: 3
Line Number: 1
Multiple Procedures rule is fired...Wed Sep 20 00:00:00 CDT 2017
===========Rule Fired============ : MULTIPLE PROCEDURES DONE ON THE SAME DAY BY SAME PROVIDER
No. of Rules fired: 1
Line Item Number: 1
Billed amount: 1500.0
Reimbursable amount: 375.0
Reason Code: CHI
Message: Coverage for all subsequent procedures is 25%
Line Item Number: 4
Billed amount: 520.0
Reimbursable amount: 416.0
Reason Code: NR
Message: Submit to Nurse Review. 100% of UCR at 80th percentile.
Line Item Number: 3
Billed amount: 1000.0
Reimbursable amount: 500.0
Reason Code: PHY
Message: Manual review is required. 50% coverage for secondary procedure.
**Line Item Number: 2
Billed amount: 1000.0
Reimbursable amount: 0.0
Reason Code: null
Message: null**

Related

ORA-06550: PLS-00103: Encountered the symbol "" with mybatis TypeHandler

I am using Typehandler to map a List<Dep> to oracle array of ... here is the setPArameter method in the handler :
public void setParameter(PreparedStatement ps, int i, List<Dep> parameter, JdbcType jdbcType)
throws SQLException {
Connection connection = ps.getConnection();
// StructDescriptor structDescriptor = StructDescriptor.createDescriptor("MEMS_ARR", connection);
Struct[] structs = null;
if(parameter != null && parameter.size() >0) {
structs = new Struct[parameter.size()];
for (int index = 0; index < parameter.size(); index++)
{
Dep dep = parameter.get(index);
Object[] params = new Object[7];
params[0] = dep.getOrder();
params[1] = dep.getIdTp;
params[2] = dep.getId();
params[3] = " ";
params[4] = " ";
params[5] = " ";
params[6] = " ";
// STRUCT struct = new STRUCT(structDescriptor, ps.getConnection(), params);
structs[index] = connection.createStruct("MEMS", params);
}
// ArrayDescriptor desc = ArrayDescriptor.createDescriptor("MEMS_ARR", ps.getConnection());
// ARRAY oracleArray = new ARRAY(desc, ps.getConnection(), structs);
}else {
parameter = new ArrayList<DependentDTO>();
structs= new Struct[0];
}
this.parameter = parameter;
Array oracleArray = ((OracleConnection) connection).createOracleArray("MEMS_ARR", structs);
ps.setArray(i, oracleArray);
}
and here is the MEMS type :
create or replace TYPE MEMS AS OBJECT
( MEM1 NUMBER(2,0),
MEM2 VARCHAR2(1),
MEM3 VARCHAR2(15),
MEM4 VARCHAR2(60),
MEM5 VARCHAR2(1),
MEM6 VARCHAR2(40),
MEM7 VARCHAR2(10)
);
and here is the portion of the xml mapping file that uses the Typehandler :
#{nat,javaType=String,jdbcType=VARCHAR,mode=IN}, --nat
**#{deps,javaType=List,jdbcType=ARRAY,mode=IN,jdbcTypeName=MEMS_ARR,typeHandler=com.my.package.MyHandler}, --mems**
#{res,javaType=String,jdbcType=VARCHAR,mode=OUT} --res
the error log is as follows :
Error querying database. Cause: java.sql.SQLException: ORA-06550: line 31, column 5: PLS-00103: Encountered the symbol "" when expecting one of the following: . ( ) , * # % & = - + < / > at in is mod remainder not rem => <an exponent (**)> <> or != or ~= >= <= <> and or like like2 like4 likec between || indicator multiset member submultiset The symbol "(" was substituted for "" to continue. ORA-06550: line 44, column 4: PLS-00103: Encountered the symbol ";" when expecting one of the following: . ( ) , * % & = - + < / > at in is mod remainder not rem => <an exponent (**)> <> or != or ~= >= <= <> and or like like2 like4 likec between || multiset ### The error may exist in file [E:\path\to\mapper\ADao.xml] ### The error may involve my.package.ADao.mthodToCall -Inline ### The error occurred while setting parameters ### SQL: {call MY_PROC( ... , --nat?, **--mems? --res**)}
As you can see in the logs, the mems is replaced by empty string or is merged with the next arg res ... the comma is not there
Also kindly note that I already debugged inside the mybatis code and realized that the mapping setParameter method is called and the input List is mapped correctly to the oracle array ... the issue happens at the time of real calling
The issue actually was that I simply missed one comma between two previous parameters ... but the error pointed to the wrong parameter to look at

for each group by date in coffeescript

which pulls data from and reformats it.
Promise = require "bluebird"
request = Promise.promisify require "request"
moment = require "moment"
cdn = require('config').server.cloudFrontDomain
toTitleCase = require "titlecase"
exports.getStocks = (path) ->
return new Promise (resolve, reject) ->
request path
.then (body) ->
germanStock = []
germanStocks = JSON.parse body.body
germanStocks.forEach (stock) ->
obj = {}
this.parsePart = (remaining) ->
value = remaining.value
dashIndex = value.lastIndexOf '-'
if dashIndex != -1
remaining.value = value.substring 0, dashIndex - 1
return value.substring(dashIndex + 1).trim()
else
return ''
remaining =
value: stock.name
size = parsePart remaining
colour = parsePart remaining
name = remaining.value
sku = stock.sku
styleId = sku.split(/-/)[0]
colorcode = /^(.*)-(.*)([0-9])$/.exec(sku)?[2]
bgStyle = "url(//#{cdn}/assets/product_shots/thumbs/#{styleId}-#{colorcode}.jpg)"
obj.id = sku
obj.name = name
obj.colorUrl = bgStyle
obj.colour = toTitleCase(colour.toLowerCase())
obj.size = size
obj.stock = stock.stock
obj.inProduction = ''
obj.office = 'DE'
stock.preorders.forEach (i, idx) ->
date = moment(i.date).format('DD-MM-YYYY')
if idx != stock.preorders.length - 1
obj.inProduction = obj.inProduction.concat i.amount + ' due on ' + date + ', '
else
obj.inProduction = obj.inProduction.concat i.amount + ' due on ' + date
germanStock.push obj
resolve germanStock
.catch (err) ->
reject err
where my data is like:
{
"id":1,
"stamp":"2014-09-25T12:55:30Z",
"name":" MENS T-SHIRT - BRIGHT BLUE - XS",
"sku":"SS01-BB0",
"stock":81,
"active":true,
"preorders":[
{
"id":92549,
"amount":160,
"date":"2016-06-19T22:00:00Z"
},
{
"id":92549,
"amount":200,
"date":"2016-06-19T22:00:00Z"
},
{
"id":92549,
"amount":1000,
"date":"2016-06-21T22:00:00Z"
}
],
"discountMatrix":0.0,
"stockNormalized":81,
"preOrdersSum":1360
},
{
"id":2,
"stamp":"2014-09-25T12:55:30Z",
"name":" MENS T-SHIRT - BRIGHT BLUE - S",
"sku":"SS01-BB1",
"stock":339,
"active":true,
"preorders":[
{
"id":92551,
"amount":240,
"date":"2016-06-19T22:00:00Z"
},
{
"id":92438,
"amount":160,
"date":"22016-06-19T22:00:00Z"
}
],
"discountMatrix":0.0,
"stockNormalized":339,
"preOrdersSum":400
},
what is the correct way to group each preorders quantity that is on the same date, so that instead of getting:
160 due on 19-06-2016, 200 due on 19-06-2016, 1000 due on 21-06-2016
i get 360 due on 19-06-2016, 1000 due on 21-06-2016
any advice much appreciated.
You could just use an object with the date as key and the total amount for the date as value.
For each preorder, add it's amount at it's date index in this object. At the end of the iteration print the content of the object:
moment = require "moment"
data = [
{
id:1
stamp: "2014-09-25T12:55:30Z"
name: " MENS T-SHIRT - BRIGHT BLUE - XS"
sku: "SS01-BB0"
stock:81
active:true
preorders:[
{
id:92549
amount:160
date: "2016-06-19T22:00:00Z"
}
{
id:92549
amount:200
date: "2016-06-19T22:00:00Z"
}
{
id:92549
amount:1000
date: "2016-06-21T22:00:00Z"
}
]
discountMatrix:0.0
stockNormalized:81
preOrdersSum:1360
}
]
obj = {}
obj.inProduction = ""
amountByDate = {}
# for each document in your data
for doc in data
# for each preorder in your document
for preorder in doc.preorders
# add it's amount in the index equals to it's date
if amountByDate[preorder.date]
amountByDate[preorder.date] += preorder.amount
else
# or create the index with the value if it doesn't exist
amountByDate[preorder.date] = preorder.amount
for date, amount of amountByDate
if obj.inProduction != ""
obj.inProduction = obj.inProduction.concat ", #{amount} due on #{moment(date).format('DD-MM-YYYY')}"
else
obj.inProduction = obj.inProduction.concat "#{amount} due on #{moment(date).format('DD-MM-YYYY')}"
console.log obj.inProduction
Result:
360 due on 20-06-2016, 1000 due on 22-06-2016

Using ecpg with postgresql, unable to parse boolean field

I am trying to retrieve records from a PostgreSQL
I use the following script to create the database, table and fill it up with some records:
psql << "EOF"
CREATE DATABASE todo;
\c todo
CREATE TABLE items
(
id serial PRIMARY KEY,
task VARCHAR(40) NOT NULL,
complete boolean
);
INSERT INTO items (id, task, complete) VALUES (1, 'task1', true);
INSERT INTO items (id, task, complete) VALUES (2, 'task2', true);
INSERT INTO items (id, task, complete) VALUES (3, 'task3', true);
INSERT INTO items (id, task, complete) VALUES (4, 'task4', true);
INSERT INTO items (id, task, complete) VALUES (5, 'task5', false);
INSERT INTO items (id, task, complete) VALUES (6, 'task6', false);
EOF
I use a) structure as well as b) individual variables to handle the problem. Method a) could not parse boolean field complete. Here is the program:
#include <stdio.h>
#include <stdlib.h>
#include <ecpglib.h>
int
main(void)
{
#if ENABLE_DEBUG
ECPGdebug(1, stderr);
#endif
EXEC SQL WHENEVER SQLERROR sqlprint;
EXEC SQL BEGIN DECLARE SECTION;
/* Use structure as host variable */
typedef struct {
int id;
char task[40];
bool complete;
} item_t;
item_t item;
/* Use individual variables as host variables */
int id;
char task[40];
bool complete;
EXEC SQL END DECLARE SECTION;
memset(&item, 0, sizeof(item_t));
EXEC SQL CONNECT TO todo;
/*
* Use structure as host variable
*/
EXEC SQL DECLARE cur1 CURSOR FOR
SELECT id, task, complete
FROM items;
EXEC SQL OPEN cur1;
printf("sizeof(item_t) = %ld\n", sizeof(item));
printf(" sizeof(item.int) = %ld\n", sizeof(item.id));
printf(" sizeof(item.task) = %ld\n", sizeof(item.task));
printf(" sizeof(item.complete) = %ld\n", sizeof(item.complete));
printf("\n"
"Using structure variable\n"
"------------------------\n");
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH FROM cur1 INTO :item;
printf("id=%d, task=%s, complete=%d\n\n",
item.id, item.task, item.complete);
}
EXEC SQL CLOSE cur1;
/*
* Use individual variables as host variables
*/
EXEC SQL DECLARE cur2 CURSOR FOR
SELECT id, task, complete
FROM items;
EXEC SQL OPEN cur2;
printf("sizeof(int) = %ld\n", sizeof(id));
printf("sizeof(task) = %ld\n", sizeof(task));
printf("sizeof(complete) = %ld\n", sizeof(complete));
printf("\n"
"Using individual variables\n"
"--------------------------\n");
EXEC SQL WHENEVER NOT FOUND DO BREAK;
while (1)
{
EXEC SQL FETCH FROM cur2 INTO :id, :task, :complete;
printf("id=%d, task=%s, complete=%d\n",
id, task, complete);
}
EXEC SQL CLOSE cur2;
EXEC SQL DISCONNECT ALL;
return 0;
}
The outputs:
sizeof(item_t) = 48
sizeof(item.int) = 4
sizeof(item.task) = 40
sizeof(item.complete) = 1
Using structure variable
------------------------
SQL error: could not convert boolean value: size mismatch, on line 80
id=1, task=task1, complete=0
SQL error: could not convert boolean value: size mismatch, on line 80
id=2, task=task2, complete=0
SQL error: could not convert boolean value: size mismatch, on line 80
id=3, task=task3, complete=0
SQL error: could not convert boolean value: size mismatch, on line 80
id=4, task=task4, complete=0
SQL error: could not convert boolean value: size mismatch, on line 80
id=5, task=task5, complete=0
SQL error: could not convert boolean value: size mismatch, on line 80
id=6, task=task6, complete=0
sizeof(int) = 4
sizeof(task) = 40
sizeof(complete) = 1
Using individual variables
--------------------------
id=1, task=task1, complete=1
id=2, task=task2, complete=1
id=3, task=task3, complete=1
id=4, task=task4, complete=1
id=5, task=task5, complete=0
id=6, task=task6, complete=0
The problem was raised as a bug and fixed by Michael Meskes. If you need the solution, apply the fix yourself fist.
diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index 8d36484..82ab4aa 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
## -423,27 +423,13 ## ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
case ECPGt_bool:
if (pval[0] == 'f' && pval[1] == '\0')
{
- if (offset == sizeof(char))
- *((char *) (var + offset * act_tuple)) = false;
- else if (offset == sizeof(int))
- *((int *) (var + offset * act_tuple)) = false;
- else
- ecpg_raise(lineno, ECPG_CONVERT_BOOL,
- ECPG_SQLSTATE_DATATYPE_MISMATCH,
- NULL);
+ *((bool *) (var + offset * act_tuple)) = false;
pval++;
break;
}
else if (pval[0] == 't' && pval[1] == '\0')
{
- if (offset == sizeof(char))
- *((char *) (var + offset * act_tuple)) = true;
- else if (offset == sizeof(int))
- *((int *) (var + offset * act_tuple)) = true;
- else
- ecpg_raise(lineno, ECPG_CONVERT_BOOL,
- ECPG_SQLSTATE_DATATYPE_MISMATCH,
- NULL);
+ *((bool *) (var + offset * act_tuple)) = true;
pval++;
break;
}
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 9e40f41..3b6eedb 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
## -752,18 +752,9 ## ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
{
strcpy(mallocedval, "{");
- if (var->offset == sizeof(char))
- for (element = 0; element < asize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');
+ for (element = 0; element < asize; element++)
+ sprintf(mallocedval + strlen(mallocedval), "%c,", (((bool *) var->value)[element]) ? 't' : 'f');
- /*
- * this is necessary since sizeof(C++'s bool)==sizeof(int)
- */
- else if (var->offset == sizeof(int))
- for (element = 0; element < asize; element++)
- sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f');
- else
- ecpg_raise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
strcpy(mallocedval + strlen(mallocedval) - 1, "}");
}

drools condition compilation error

I am getting compilations errors in drools. I am velocity file for rule string.
I am not familiar with drools. Please help me in resolving the following.
I am getting compilation error while loading the rules:
Error while creating rule package - [927,27]: unknown:927:27 Unexpected token '"Y1PC"'[927,35]: unknown:927:35 mismatched token: [#2072,12451:12451='>',<77>,927:35];
expecting type RIGHT_PAREN[927,61]: unknown:927:61 mismatched token: [#2078,12477:12482='"Y0CC"',<20>,927:61]; expecting type RIGHT_PAREN[928,3]:
unknown:928:3 Unexpected token 'departureTime'[928,25]: unknown:928:25 Unexpected token 'departureTime'
Below is the vm code:
#macro(generateDepartureMinTimeCond $condition)
&& departureTime >= $condition.minVal && departureTime <= $condition.maxVal
#end
#macro(generatePaxVarCond $condition)
#set( $Q = '"' )
&& $mapValues: variableValues
Map(this["Y1PC"] > this["Y0CC"]) from $mapValues
##flight : Flight()
##&& getValue(flight.getVariableValues(),${condition.leftPaxCls.abbr}${condition.leftPaxVariable.paxVariableCode}) ${condition.operator} getValue(flight.getVariableValues(),${condition.rightPaxCls.abbr}${condition.rightPaxVariable.paxVariableCode})
##&& variableValue[${Q}${condition.leftPaxCls.abbr}${condition.leftPaxVariable.paxVariableCode}${Q}]${condition.operator} variableValue[${Q}${condition.rightPaxCls.abbr}${condition.rightPaxVariable.paxVariableCode}${Q}]
#end
#macro(generateConditionText $condition)
#elseif($condition.conditionType.id.longValue() == $COND_DEP_MINUS_TIME)
#generateDepartureMinTimeCond($condition)
#elseif($condition.conditionType.id.longValue() == $COND_PAX_VAR)
#generatePaxVarCond($condition)
#end
#end
#macro(generateConditionsText $rule $p)
flight : Flight(eval(fireNextPriority==true), categoryCount==$category.paxCatgySeq, eval(!firedRules.contains(Integer.valueOf($rule.id))) && airlineId == $ruleSet.carrier.id && (departureDate >= $ruleSet.effDate.getTime()) && (departureDate <= $ruleSet.expDate.getTime()) && (departureDate >= $rule.effDate.getTime()) && (departureDate <= $rule.expDate.getTime())
&& eval($p == $rule.priority)
#foreach($condition in $rule.paxConditions)#generateConditionText($condition)#end)
#end
#macro(generateActionRollover $action)
Integer oldValueFrom;
Integer oldValueTo;
Integer newValueFrom;
Integer newValueTo;
Integer oldPCVarFrom;
Integer oldPCVarTo;
Integer newPCVarFrom;
Integer newPCVarTo;
#foreach($rollover in $action.actionRolloverSet)
#if (!$rollover.varCode)
#set ($fromString = "$rollover.fromCabinClass.abbr$roVariable")
#set ($toString = "$rollover.toCabinClass.abbr$roVariable")
#set ($compareTo = "$rollover.fromCabinClass.abbr$capVariable")
oldValueFrom = flight.getVariableValue("$fromString");
oldValueTo = flight.getVariableValue("$toString");
flight.rollOverVariableValue("$fromString", "$toString", "$compareTo");
newValueFrom = flight.getVariableValue("$fromString");
newValueTo = flight.getVariableValue("$toString");
System.out.println("generateActionRollover 1 valuefrom :"+ oldValueFrom +" -- "+ newValueFrom +" -- "+ $fromString);
System.out.println("generateActionRollover 1 valueto :"+ oldValueTo +" -- "+ newValueTo +" -- "+ $toString);
ruleLog.addLogEntry(flight.getSoFltLegId(),flight.getFlightLegId(), new Long($ruleSet.id), new Long($category.id), new Long($action.paxAdjRule.id), "$rollover.fromCabinClass.abbr", "$roVariable", oldValueFrom, newValueFrom, flight.getPaxCountString());
ruleLog.addLogEntry(flight.getSoFltLegId(),flight.getFlightLegId(), new Long($ruleSet.id), new Long($category.id), new Long($action.paxAdjRule.id), "$rollover.toCabinClass.abbr", "$roVariable", oldValueTo, newValueTo, flight.getPaxCountString());
#else
#set ($fromString = "$rollover.fromCabinClass.abbr$rollover.varCode")
#set ($fromPaxString = "$rollover.fromCabinClass.abbr$roVariable")
#set ($toString = "$rollover.toCabinClass.abbr$roVariable")
#set ($compareToCC = "$rollover.toCabinClass.abbr$capVariable")
#set ($compareToPC = "$rollover.toCabinClass.abbr$roVariable")
oldValueFrom = flight.getVariableValue("$fromString");
oldValueTo = flight.getVariableValue("$toString");
oldPCVarFrom = flight.getVariableValue("$fromPaxString");
oldPCVarTo = flight.getVariableValue("$toString");
flight.rollOverVariableValue("$fromString", "$fromPaxString", "$toString", "$compareToCC", "$compareToPC");
newValueFrom = flight.getVariableValue("$fromString");
newValueTo = flight.getVariableValue("$toString");
newPCVarFrom = flight.getVariableValue("$fromPaxString");
newPCVarTo = flight.getVariableValue("$toString");
#end
#end
#end
#macro(generateRuleText $rule $p)
rule "$category.paxCatgyCode - $rule.ruleCode"
salience -$rule.priority$rule.sortSeq
agenda-group "$rule.paxRuleSet.paxRuleSetCode - $category.paxCatgyCode"
auto-focus true
when
#generateConditionsText($rule $p)
then
System.out.println("Firing rule: $category.paxCatgyCode - $rule.ruleCode");
flight.setStatus(true);
flight.setPriority($p);
flight.addToFiredRules($rule.id);
update(flight);
#set ($maxPrio = "-$rule.priority$rule.sortSeq");
## \#System.out.println("maxPrio : " + $maxPrio );
#foreach($action in $rule.actions)
#if ($category.catgyType.id.longValue() == $CT_ROLLOVER)
#generateActionRollover($action)
#end
#end
end
#end
#foreach($rule in $rulesWithPriorities)
#set ($lastRuleId = $sortedRulesInCatgMap.get($rule.priority))
#if($rule.isEnabled.intValue() == 1)
#generateRuleText($rule $p)
#end
#set ($maxSequ = $rule.sortSeq)
#end ## \# foreach rule
rule "Default Rule to clear agenda $category.paxCatgyCode - $p"
salience #generatePrio("$maxSequ" $p)
agenda-group "$ruleSet.paxRuleSetCode - $category.paxCatgyCode"
auto-focus true
when
$flight : Flight(eval(fireNextPriority==true),categoryCount==$category.paxCatgySeq, eval(priority==$p), eval(status==true))
then
System.out.println("Firing rule: Default Rule to clear agenda $category.paxCatgyCode - Priority $p " );
$flight.setFireNextPriority(false);
$flight.setStatus(false);
## \#flight.setExecuteFinalRuleForCatg(false);
update($flight);
drools.getWorkingMemory().clearAgendaGroup("$ruleSet.paxRuleSetCode - $category.paxCatgyCode");
end
#end ## \# foreach p
#end
#macro (calcPriority $value)
#set($prio = ($value.trim()))
#set ($Integer = 0)
#set ($intValue = ($Integer.parseInt($prio) - 1))$intValue#end
#macro (generatePrio $value $p)
#set ($Integer = 0)
#set ($priValue = ($Integer.parseInt($value) + 1))
-$p$priValue #end
Object Flight code:
public class Flight {
Long departureTime;
// Variable Details
Map<String, Integer> variableValues = new HashMap<String, Integer>();
public Long getDepartureTime() {
return departureTime;
}
public void setDepartureTime(Long departureTime) {
this.departureTime = departureTime;
}
public Map<String, Integer> getVariableValues() {
return variableValues;
}
public void setVariableValues(Map<String, Integer> variableValues) {
this.variableValues = variableValues;
}
/**
* Add an entry to the variable-count map for the given variable with the given count.
* If an entry already exists, update the count.
* #param variableCode
* #param count
*/
public void addVariableValue(String variableCode, Integer count){
if (count < 0) count = 0;
this.variableValues.put(variableCode, count);
}
/**
* Return the currently stored count for the variable code
* #param variableCode
* #return
*/
public Integer getVariableValue(String variableCode){
Integer value = this.variableValues.get(variableCode);
return value == null? 0 : value;
}
}
Generated Rule String for above vm file. Rule is used to generate the keya of map which is used in the object and the key is showing as unexpected token:
rule "PRL - PRL001"
salience -11
agenda-group "PARS_LIVE - PRL"
auto-focus true
when
flight : Flight(eval(fireNextPriority==true), categoryCount==3, eval(!firedRules.contains(Integer.valueOf(23537))) && airlineId == 1189321015 && (departureDate >= 1263925800000) && (departureDate <= 4102338600000) && (departureDate >= 1263925800000) && (departureDate <= 4102338600000)
&& eval(1 == 1)
&& flight.getVariableValue("Y1PC") > flight.getVariableValue("Y0CC")
&& departureTime >= 6 && departureTime <= 8
)
then
System.out.println("Firing rule: PRL - PRL001");
flight.setStatus(true);
flight.setPriority(1);
flight.addToFiredRules(23537);
update(flight);
Integer oldValueFrom;
Integer oldValueTo;
Integer newValueFrom;
Integer newValueTo;
Integer oldPCVarFrom;
Integer oldPCVarTo;
Integer newPCVarFrom;
Integer newPCVarTo;
oldValueFrom = flight.getVariableValue("Y1PC");
oldValueTo = flight.getVariableValue("C1PC");
flight.rollOverVariableValue("Y1PC", "C1PC", "Y1CC");
newValueFrom = flight.getVariableValue("Y1PC");
newValueTo = flight.getVariableValue("C1PC");
end
This part of the condition:
flight.getVariableValue("Y1PC") > flight.getVariableValue("Y0CC")
has to be written as an eval expression because Drools expects any getX() call to be a getter call without a parameter.
eval( flight.getVariableValue("Y1PC") > flight.getVariableValue("Y0CC") )
It might be simpler to access the Map variableValues directly, e.g.
variableValues["Y1PC"] > variableValues["Y0CC"]

LSP packet modify

anybody care to share some insights on how to use LSP for packet modifying ?
I am using the non IFS subtype and I can see how (pseudo?) packets first enter WSPRecv. But how do I modify them ? My inquiry is about one single HTTP response that causes WSPRecv to be called 3 times :((. I need to modify several parts of this response, but since it comes in 3 slices, it is pretty hard to modify it accordingly. And, maybe on other machines or under different conditions (such as high traffic) there would only be one sole WSPRecv call, or maybe 10 calls. What is the best way to work arround this (please no NDIS :D), and how to properly change the buffer (lpBuffers->buf) by increasing it ?
int WSPAPI
WSPRecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
LPWSATHREADID lpThreadId,
LPINT lpErrno
)
{
LPWSAOVERLAPPEDPLUS ProviderOverlapped = NULL;
SOCK_INFO *SocketContext = NULL;
int ret = SOCKET_ERROR;
*lpErrno = NO_ERROR;
//
// Find our provider socket corresponding to this one
//
SocketContext = FindAndRefSocketContext(s, lpErrno);
if ( NULL == SocketContext )
{
dbgprint( "WSPRecv: FindAndRefSocketContext failed!" );
goto cleanup;
}
//
// Check for overlapped I/O
//
if ( NULL != lpOverlapped )
{
/*bla bla .. not interesting in my case*/
}
else
{
ASSERT( SocketContext->Provider->NextProcTable.lpWSPRecv );
SetBlockingProvider(SocketContext->Provider);
ret = SocketContext->Provider->NextProcTable.lpWSPRecv(
SocketContext->ProviderSocket,
lpBuffers,
dwBufferCount,
lpNumberOfBytesRecvd,
lpFlags,
lpOverlapped,
lpCompletionRoutine,
lpThreadId,
lpErrno);
SetBlockingProvider(NULL);
//is this the place to modify packet length and contents ?
if (strstr(lpBuffers->buf, "var mapObj = null;"))
{
int nLen = strlen(lpBuffers->buf) + 200;
/*CHAR *szNewBuf = new CHAR[];
CHAR *pIndex;
pIndex = strstr(lpBuffers->buf, "var mapObj = null;");
nLen = strlen(strncpy(szNewBuf, lpBuffers->buf, (pIndex - lpBuffers->buf) * sizeof (CHAR)));
nLen = strlen(strncpy(szNewBuf + nLen * sizeof(CHAR), "var com = null;\r\n", 17 * sizeof(CHAR)));
pIndex += 18 * sizeof(CHAR);
nLen = strlen(strncpy(szNewBuf + nLen * sizeof(CHAR), pIndex, 1330 * sizeof (CHAR)));
nLen = strlen(strncpy(szNewBuf + nLen * sizeof(CHAR), "if (com == null)\r\n" \
"com = new ActiveXObject(\"InterCommJS.Gateway\");\r\n" \
"com.lat = latitude;\r\n" \
"com.lon = longitude;\r\n}", 111 * sizeof (CHAR)));
pIndex = strstr(szNewBuf, "Content-Length:");
pIndex += 16 * sizeof(CHAR);
strncpy(pIndex, "1465", 4 * sizeof(CHAR));
lpBuffers->buf = szNewBuf;
lpBuffers->len += 128;*/
}
if ( SOCKET_ERROR != ret )
{
SocketContext->BytesRecv += *lpNumberOfBytesRecvd;
}
}
cleanup:
if ( NULL != SocketContext )
DerefSocketContext( SocketContext, lpErrno );
return ret;
}
Thank you
my comment worked out. http response headers / request turned out to end in \r\n\r\n.