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"]
Related
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
I had the following error while trying to sign a part of SOAP Request :
org.apache.xml.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID _53ea293168db637b15e2d4d7894
at org.apache.xml.security.utils.resolver.implementations.ResolverFragment.engineResolve(ResolverFragment.java:86)
at org.apache.xml.security.utils.resolver.ResourceResolver.resolve(ResourceResolver.java:279)
at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Reference.java:417)
at org.apache.xml.security.signature.Reference.dereferenceURIandPerformTransforms(Reference.java:597)
at org.apache.xml.security.signature.Reference.calculateDigest(Reference.java:689)
at org.apache.xml.security.signature.Reference.generateDigestValue(Reference.java:396)
at org.apache.xml.security.signature.Manifest.generateDigestValues(Manifest.java:206)
at org.apache.xml.security.signature.XMLSignature.sign(XMLSignature.java:595)
It comes from the resolution of the URI declared on the reference tag.
Here is the java code i'm using for signing via X509 :
KeyStore.PrivateKeyEntry pke = ISKeyStoreManager.getInstance().getPrivateKeyEntry(keyStoreAlias, keyAlias);
AlgorithmStrings algStrings = AlgorithmStrings.getAlgDSStrings( pke.getPrivateKey(), signatureAlgorithmString, digestAlgorithmString);
String resultantXPath = StringUtils.join(xpaths, '|');
Transforms transforms = new Transforms(originalDocument);
NodeList targetDocumentList = obtainNodesForXPath(originalDocument, resultantXPath, nc);
if(targetDocumentList != null && targetDocumentList.getLength() > 0)
{
if(targetDocumentList.item(0).hasAttributes()){
Node attrId = targetDocumentList.item(0).getAttributes().getNamedItem("Id");
if(attrId != null && !attrId.getNodeValue().equals("")){
uri = new StringBuilder().append('#').append(attrId.getNodeValue()).toString();
}
else{
((Element) targetDocumentList.item(0)).setAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
((Element) targetDocumentList.item(0)).setAttribute("wsu:Id", idForXmlObject);
}
}
else{
((Element) targetDocumentList.item(0)).setAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
((Element) targetDocumentList.item(0)).setAttribute("wsu:Id", idForXmlObject);
}
}else{
log.debug("Target not found in the original document with xpath: " + resultantXPath);
}
transforms.addTransform("http://www.w3.org/2000/09/xmldsig#enveloped-signature");
if (resultantXPath != null) {
log.debug("Instantiation XPATHContainer");
XPathContainer xpathC = new XPathContainer(originalDocument);
xpathC.setXPath(resultantXPath);
if ((ncMap != null) && (!ncMap.isEmpty())) {
for (Map.Entry<String,String> e : ncMap.entrySet()) {
log.debug("Adding namespace to XPATH Container: " + e.getKey() + " -> " + e.getValue());
xpathC.setXPathNamespaceContext(e.getKey(), e.getValue());
}
}
transforms.addTransform("http://www.w3.org/TR/1999/REC-xpath-19991116", xpathC.getElement());
}
log.debug("Instantiation Signature");
XMLSignature sig = new XMLSignature(originalDocument, null, algStrings.signatureAlgorithm, canonicalizationAlg);
sig.setFollowNestedManifests(true);
log.debug("Ajout des assertions de transformation");
sig.addDocument("", transforms, algStrings.digestMethod);
if (idAttrForSignature != null) {
sig.setId(idAttrForSignature);
}
log.debug("DOMToString: " + serializeDOMToString(originalDocument));
// signature node insertion
NodeList nodeList = obtainNodesForXPath(originalDocument, insertSignatureAtXPath, nc);
if(nodeList != null && nodeList.getLength() > 0){
Node nodeSignature = nodeList.item(0);
Node childNode = nodeSignature.getFirstChild();
if (childNode != null) {
if (addSignatureAsLastElement)
nodeSignature.appendChild(sig.getElement());
else
nodeSignature.insertBefore(sig.getElement(), childNode);
}
else nodeSignature.appendChild(sig.getElement());
}
else{
throw new ServiceException("INVALID_SIGNATURE_NODE_SELECTOR_XPATH");
}
// Public key insertion
//X509Data x509Data = getX509Data(includeCertChain, certificateData, originalDocument, pke);
//KeyInfoReference kir = new KeyInfoReference(x509Data.getDocument());
SecurityTokenReference str = new SecurityTokenReference(sig.getKeyInfo().getDocument());
str.setKeyIdentifier(ISKeyStoreAccessorUtil.getIaikCertificate(pke.getCertificate()));
sig.getKeyInfo().getElement().appendChild(str.getElement());
log.debug("DOMToString: " + serializeDOMToString(originalDocument));
//sig.getSignedInfo().addResourceResolver(new ResolverXPointer());
((Element)(sig.getSignedInfo().getElement().getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Reference").item(0))).setAttribute("URI", uri);
log.debug("DOMToString: " + serializeDOMToString(originalDocument));
//sig.addDocument(uri, trans);
// Signature generation
sig.sign(pke.getPrivateKey());
Do you have any proposition of workaround ? or another way to set URI attribute ?
Thank you for helping !
I found it.
I added InclusiveNamespaces so that the sign method can figure out that ID is on a specific namespace defined attribute.
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, "}");
}
The netmap/virtio_net driver didn't work (Linux 3.10 kernel). There were two problems.
On the 3.10.60 kernel from kernel.org, the patch to virtio_net.c didn't
work, one part of the patch was rejected. This is easily fixed.
More serious, was that the virtio initialization code didn't work, nor
did the packet receive code. The basic problem was failure to initialize
the indices properly and failure to maintain a 1 slot separation between
head/tail indices. (Same problem 2 locations in the code.)
This problem is easily seen by creating a KVM guest with a
netmap/virtio_net driver, and simply pinging the guest from the host.
The receive traffic can easily be monitored using the pkt-gen tool on
the guest.
The first 255 pings will work fine, when the index hits 255, then the
packet receive will fail, and will continue to fail every time on slot 255.
I've included patches for both problems in the hopes that the source code
will be updated and others won't have to find these problems.
First virtio_netmap_3.10.60.patch:
# patch is the whole netmap virtio driver patch for 3.10.60 (from
# kernel.org), and it applies correctly.
#
Index: linux-3.10.60/drivers/net/virtio_net.c
===================================================================
--- linux-3.10.60.orig/drivers/net/virtio_net.c 2014-11-14 11:48:23.000000000 -0500
+++ linux-3.10.60/drivers/net/virtio_net.c 2014-11-21 12:54:29.751760095 -0500
## -131,6 +131,10 ##
struct notifier_block nb;
};
+#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE)
+#include <virtio_netmap.h>
+#endif
+
struct skb_vnet_hdr {
union {
struct virtio_net_hdr hdr;
## -210,6 +214,10 ##
/* Suppress further interrupts. */
virtqueue_disable_cb(vq);
+#ifdef DEV_NETMAP
+ if (netmap_tx_irq(vi->dev, vq2txq(vq)))
+ return;
+#endif
/* We were probably waiting for more output buffers. */
netif_wake_subqueue(vi->dev, vq2txq(vq));
}
## -646,7 +654,16 ##
struct virtnet_info *vi = rq->vq->vdev->priv;
void *buf;
unsigned int r, len, received = 0;
+#ifdef DEV_NETMAP
+ int work_done = 0;
+
+ if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) {
+ napi_complete(napi);
+ ND("called netmap_rx_irq");
+ return 1;
+ }
+#endif
again:
while (received < budget &&
(buf = virtqueue_get_buf(rq->vq, &len)) != NULL) {
## -679,6 +696,16 ##
{
struct virtnet_info *vi = netdev_priv(dev);
int i;
+#ifdef DEV_NETMAP
+ int ok = virtio_netmap_init_buffers(vi);
+
+ netmap_enable_all_rings(dev);
+ if (ok) {
+ for (i = 0; i < vi->max_queue_pairs; i++)
+ virtnet_napi_enable(&vi->rq[i]);
+ return 0;
+ }
+#endif
for (i = 0; i < vi->max_queue_pairs; i++) {
if (i < vi->curr_queue_pairs)
## -972,6 +999,9 ##
struct virtnet_info *vi = netdev_priv(dev);
int i;
+#ifdef DEV_NETMAP
+ netmap_disable_all_rings(dev);
+#endif
/* Make sure refill_work doesn't re-enable napi! */
cancel_delayed_work_sync(&vi->refill);
## -1644,6 +1674,10 ##
goto free_recv_bufs;
}
+#ifdef DEV_NETMAP
+ virtio_netmap_attach(vi);
+#endif
+
/* Assume link up if device can't report link status,
otherwise get link status from config. */
if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
## -1690,6 +1724,9 ##
{
struct virtnet_info *vi = vdev->priv;
+#ifdef DEV_NETMAP
+ netmap_detach(vi->dev);
+#endif
unregister_hotcpu_notifier(&vi->nb);
/* Prevent config work handler from accessing the device. */
Next is the virtio_netmap.patch
# There is a problem with the initialization, and during read packet with
# control of the indices .
#
# This problem is easily seen by building a KVM netmap/virtio_net driver, and
# simply pinging it (host pings KVM guest). All goes well, until ring buffer
# reaches index 255, and no packet is actually received. This will fix that
# problem and resulted in a working driver.
#
Index: b/LINUX/virtio_netmap.h
===================================================================
--- a/LINUX/virtio_netmap.h 2014-11-21 16:26:03.951278021 -0500
+++ b/LINUX/virtio_netmap.h 2014-11-21 16:26:25.451386665 -0500
## -398,8 +398,8 ##
* Second part: skip past packets that userspace has released.
*/
nm_i = kring->nr_hwcur; /* netmap ring index */
- if (nm_i != head) {
- for (n = 0; nm_i != head; n++) {
+ if (nm_next(nm_i, lim) != head) {
+ for (n = 0; nm_next(nm_i, lim) != head; n++) {
struct netmap_slot *slot = &ring->slot[nm_i];
void *addr = NMB(slot);
int err;
## -421,7 +421,7 ##
virtqueue_kick(vq);
nm_i = nm_next(nm_i, lim);
}
- kring->nr_hwcur = head;
+ kring->nr_hwcur = nm_i;
}
/* We have finished processing used RX buffers, so we have to tell
## -454,6 +454,7 ##
for (r = 0; r < na->num_rx_rings; r++) {
COMPAT_DECL_SG
struct netmap_ring *ring = na->rx_rings[r].ring;
+ struct netmap_kring *kring = &na->rx_rings[r];
struct virtqueue *vq = GET_RX_VQ(vi, r);
struct scatterlist *sg = GET_RX_SG(vi, r);
struct netmap_slot* slot;
## -485,6 +486,7 ##
if (VQ_FULL(vq, err))
break;
}
+ kring->nr_hwcur = i;
D("added %d inbufs on queue %d", i, r);
virtqueue_kick(vq);
}
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.