How to deal with GWT RPC encoding in LR scripts?

235 views
Skip to first unread message

Chaitanya Bhatt(www.performancecompetence.com)

unread,
Feb 16, 2010, 8:48:20 AM2/16/10
to LoadRunner
I'm stuck with an annoying problem dealing with GWT (Google Web Tool)
RPC encoding of HTTP requests (POST).
Problem description: The recorded client is launched through Internet
Explorer (With GoogleGears plug installed) and is completely developed
using GWT framework. Hence, all the http body contents are encoded
with EncType=text/x-gwt-rpc; charset=utf-8. as a result of which the
request messages sent from LoadRunner(Web-Http/Html Protocol) is
completely unintelligible.

The script seems to work for a certain hardcoded value but if
parametrized, then the script fails because few body elements are not
correlated. But when I try to correlate dynamic values I tend to get
bogged down because there is no guarantee of which one is really
critical for the script to pass and which isn't. Plus, the encoded
pattern found in the body of the requests is completely unintelligible
as stated earlier.
Sample:web_custom_request("therapy.rpc_3",
"URL=http://aGWTapp/myapplication.rpc",
"Method=POST",
"Resource=0",
"RecContentType=application/json",
"Referer=http://aWPCapp:8080/theGWT.html",
"Snapshot=t20.inf",
"Mode=HTML",
"EncType=text/x-gwt-rpc; charset=utf-8",
"Body=5|0|123|http://.client.profile.therapy.controller.ISomeService|
checkItemType|com.client.hxm.client.profile.therapy.model.TherapyDTO|I|
com.client.hmm.client.profile.therapy.model.TherapyDTO/703513613|
java.util.ArrayList/3821976829|
com.client.hmm.client.profile.therapy.model.PhysicianDTO/2164436112|
com.extjs.gxt.ui.client.data.RpcMap/3441186752|physiciancode|
java.lang.String/2004016611|00050|"
"physicianName|MARX, GROUCHO|
com.client.hmm.client.profile.therapy.model.StockAreaDTO/4273915306|
description|System Determines Stock Area|code||CENTRAL STOCK AREA|
CENTRAL|com.client.hmm.client.profile.therapy.model.TherapyItemDTO/
1306964257|java.util.HashMap/962170901|bulk|java.lang.Boolean/
476441737|image|images/therapyIcon.png|itemType|A|ACETAMINOPHEN|
gridIndex|java.lang.Long/4227064769|itemId|form|TAB|strength|325 MG|
doseStrength|325.0 MG|genericCode|00000000000004|genericName|"
"origDoseStrength|brandName|TYLENOL|dispenseSize|java.lang.Double/
858496421|computeDispenseSize|dispCntl|ndc|63739000201|
userSetStartDate|newrxnumber|doseLimit|basetherapy|bottleNum|
infuseOver|scheduleType|rxNumber|doseType|02|patientId|
computedPhysicianname|batchName|therapypriority|placerordernumber|
previousrxnumber|flowRate|defaultITFluid|internalComments|holdstopdate|
status|finalVolume|frequencySet|serviceType|prescribedrate|
showPhysician|userSetPar|screeningGroupId|userSetDispQty|"
"adminRecordGrouping|cancelAction|active|Y|startDate|java.util.Date/
1659716317|stopDate|relationShipGroup|infuseUnit|allLinks|stopdays|
orderingPhysicianCode|recommended|visitId|prevLinkedTherapyRxNumber|
par|externalComments|rateExpression|profile|MED|facilityCode|M|
therapyType|STAND|expiresIn|expiresUnit|dispenseQuantity|
defaultIVFluid|previousplacerordernumber|linkRelationship|
holdstartdate|route|ORAL|frequencyCode|batchGrouping|volume|
parentrordernumber|prn|N|defaultIVFluidDose|cosignautrechecked"
"|therapyMode|1|2|3|4|2|5|6|7|0|0|8|0|0|0|8|0|8|1|9|1|10|2|11|12|13|14|
12|15|0|8|2|16|1|10|2|17|12|18|19|12|20|16|1|10|2|17|12|21|19|12|22|8|
1|23|24|0|0|0|1|10|17|25|26|0|27|12|28|29|12|30|17|12|31|32|33|0|0|34|
33|6|0|35|12|36|37|12|38|39|12|40|41|12|42|43|-25|44|-30|45|12|46|47|
48|1|49|26|1|50|0|51|12|52|0|24|0|8|0|0|1|10|63|53|0|54|0|55|0|56|0|
57|-13|58|0|59|-22|60|33|0|0|61|12|62|63|33|98|0|64|0|65|0|66|0|67|-13|
68|-39|69|48|0|70|0|71|0|72|0|73|0|74|48|0|75|-39|76|12|6|77|0|78|-22|
79|-22|80|-39|81|-22|82|0|83|-22|84|12|85|86|87|3508980059|
1262720385024|88|0|89|0|90|0|91|-22|92|0|93|0|94|-22|95|33|132|0|
96|-39|97|-39|98|0|99|0|100|12|101|102|12|103|104|12|105|106|-13|107|0|
108|-39|109|0|110|-13|111|0|112|0|113|12|114|115|0|116|0|117|48|0|
118|-13|119|12|120|121|0|122|-22|123|-44|0|",
LAST);
Phew! looks ugly isn't it? :P...

Kindly share your experiences and/or ideas in dealing with such client
side encoding issues in order to over come it.

Regards,
Chaitanya M Bhatt
http://www.performancecompetence.com

Floris Kraak

unread,
Feb 16, 2010, 9:18:12 AM2/16/10
to lr-loa...@googlegroups.com
On Tue, Feb 16, 2010 at 2:48 PM, Chaitanya
Bhatt(www.performancecompetence.com) <bhatt.c...@gmail.com>
wrote:

>
> The script seems to work for a certain hardcoded value but if
> parametrized, then the script fails because few body elements are not
> correlated. But when I try to correlate dynamic values I tend to get
> bogged down because there is no guarantee of which one is really
> critical for the script to pass and which isn't. Plus, the encoded
> pattern found in the body of the requests is completely unintelligible
> as stated earlier.
>

This looks interesting.
I'll have a look to see what I make of it, but no guarantees. This
kind of problem is inherently hard. The only way to really tackle it
would be to have a browser plugin of some kind to generate the load,
instead of using loadrunner ;-)

> Sample:web_custom_request("therapy.rpc_3",
>  "URL=http://aGWTapp/myapplication.rpc",
>  "Method=POST",
>  "Resource=0",
>  "RecContentType=application/json",
>  "Referer=http://aWPCapp:8080/theGWT.html",
>  "Snapshot=t20.inf",
>  "Mode=HTML",
>  "EncType=text/x-gwt-rpc; charset=utf-8",

So far, so good: Easy to understand headers. "therapy.rpc" seems to be
what we're testing here.


> "Body=5|0|123|http://.client.profile.therapy.controller.ISomeService|
> checkItemType|com.client.hxm.client.profile.therapy.model.TherapyDTO|I|
> com.client.hmm.client.profile.therapy.model.TherapyDTO/703513613|

Here we get your request. Immediate gut feeling is that this is a java
based application.
com.client.hmx. .. etc means classpaths.


> java.util.ArrayList/3821976829|
> com.client.hmm.client.profile.therapy.model.PhysicianDTO/2164436112|
> com.extjs.gxt.ui.client.data.RpcMap/3441186752|physiciancode|

RpcMap .. uh oh. Remote procedure calls? This doesn't bode much good.
Looking at the numbers in this bit (and the bit before) it seems to me
that those are object id's or references of some kind. Most of them
should definitely be something you'd want to correlate.

If you want to be 100% sure you should make multiple recordings
(possible from multiple machines and accounts) and compare each
recording. See what changes and what doesn't.

Also, note the "ArrayList" at the top. This signifies that what
follows is a list of elements placed inside an array.


> java.lang.String/2004016611|00050|"

The format here seems to be "Object class/Object id|Value". So this is
a java.lang.String, with object id 200401661, containing the value
"00050".

>  "physicianName|MARX, GROUCHO|

Here we see a pattern: Name|Value pairs. So the first field is the
name of the variable, the second the value of the variable.
Perhaps the previous value is an anonymous string containing the value
"00050". What that value signifies is hard to tell, though.

> com.client.hmm.client.profile.therapy.model.StockAreaDTO/4273915306|

class/object id.

> description|System Determines Stock Area|code||CENTRAL STOCK AREA|

Name|Value|Name|Value...

A list of some kind, or are these values nested, like an XML document
would have them?

> CENTRAL|com.client.hmm.client.profile.therapy.model.TherapyItemDTO/
> 1306964257|java.util.HashMap/962170901|bulk|java.lang.Boolean/

HashMap = another list. The difference with an array is that an array
is a simple straightforward list, whereas a hashmap uses keys
("hashes") for object lookups.

> 476441737|image|images/therapyIcon.png|itemType|A|ACETAMINOPHEN|
> gridIndex|java.lang.Long/4227064769|itemId|form|TAB|strength|325 MG|
> doseStrength|325.0 MG|genericCode|00000000000004|genericName|"
>  "origDoseStrength|brandName|TYLENOL|dispenseSize|java.lang.Double/
> 858496421|computeDispenseSize|dispCntl|ndc|63739000201|
> userSetStartDate|newrxnumber|doseLimit|basetherapy|bottleNum|
> infuseOver|scheduleType|rxNumber|doseType|02|patientId|
> computedPhysicianname|batchName|therapypriority|placerordernumber|
> previousrxnumber|flowRate|defaultITFluid|internalComments|holdstopdate|
> status|finalVolume|frequencySet|serviceType|prescribedrate|
> showPhysician|userSetPar|screeningGroupId|userSetDispQty|"
> "adminRecordGrouping|cancelAction|active|Y|startDate|java.util.Date/
> 1659716317|stopDate|relationShipGroup|infuseUnit|allLinks|stopdays|
> orderingPhysicianCode|recommended|visitId|prevLinkedTherapyRxNumber|
> par|externalComments|rateExpression|profile|MED|facilityCode|M|
> therapyType|STAND|expiresIn|expiresUnit|dispenseQuantity|
> defaultIVFluid|previousplacerordernumber|linkRelationship|
> holdstartdate|route|ORAL|frequencyCode|batchGrouping|volume|
> parentrordernumber|prn|N|defaultIVFluidDose|cosignautrechecked"

I'd try to split this blob up into specific name|value pairs, to see
what is still a (part of a) list and what isn't.


> "|therapyMode|1|2|3|4|2|5|6|7|0|0|8|0|0|0|8|0|8|1|9|1|10|2|11|12|13|14|
> 12|15|0|8|2|16|1|10|2|17|12|18|19|12|20|16|1|10|2|17|12|21|19|12|22|8|
> 1|23|24|0|0|0|1|10|17|25|26|0|27|12|28|29|12|30|17|12|31|32|33|0|0|34|
> 33|6|0|35|12|36|37|12|38|39|12|40|41|12|42|43|-25|44|-30|45|12|46|47|
> 48|1|49|26|1|50|0|51|12|52|0|24|0|8|0|0|1|10|63|53|0|54|0|55|0|56|0|
> 57|-13|58|0|59|-22|60|33|0|0|61|12|62|63|33|98|0|64|0|65|0|66|0|67|-13|
> 68|-39|69|48|0|70|0|71|0|72|0|73|0|74|48|0|75|-39|76|12|6|77|0|78|-22|
> 79|-22|80|-39|81|-22|82|0|83|-22|84|12|85|86|87|3508980059|
> 1262720385024|88|0|89|0|90|0|91|-22|92|0|93|0|94|-22|95|33|132|0|
> 96|-39|97|-39|98|0|99|0|100|12|101|102|12|103|104|12|105|106|-13|107|0|
> 108|-39|109|0|110|-13|111|0|112|0|113|12|114|115|0|116|0|117|48|0|
> 118|-13|119|12|120|121|0|122|-22|123|-44|0|",


No idea what to do with this bit, sorry.

>  LAST);
>  Phew! looks ugly isn't it? :P...

Ugly, but not entirely impossible to correlate.
To be honest I'd probably go the "let's just try to correlate
everything until it works" route.
But I'd make a few more recordings and compare the values between them first.

> Kindly share your experiences and/or ideas in dealing with such client
> side encoding issues in order to over come it.
>

Regards,
Floris
---
'What does it mean to say that one is 48% slower? That's like saying
that a squirrel is 48% juicier than an orange - maybe it's true, but
anybody who puts the two in a blender to compare them is kind of
sick.'
--- Linus Torvalds

chaitanya bhatt

unread,
Feb 16, 2010, 1:00:07 PM2/16/10
to lr-loa...@googlegroups.com
Floris, thanks a ton for your valuable inputs.
Your write up was really overwhelming. :)

Few inputs which I gained through the internet regarding GWT RPC encoding:

As uncanny as it sounds, supposedly the pairing of keywords to its value works as mentioned below:

NameofVariable1|NameofVariable2|NameofVariable3|........|ValueofVariable1|ValueofVariable1|ValueofVariable2)..

Notice that towards the end of the body once all tags/names of variables are mentioned then starts the array of corresponding values separated by delimiters and identified by unique offset for each.

Pretty annoying isn't it? :P

Since my current project is challenged by a strict time frame I am afraid I might have to suggest my clients to buy GUI level protocol license as an alternative. :(



Regards,
Chaitanya M Bhatt
http://www.performancecompetence.com


--
You received this message because you are subscribed to the Google "LoadRunner" group.
To post to this group, send email to LR-Loa...@googlegroups.com
To unsubscribe from this group, send email to
LR-LoadRunne...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/LR-LoadRunner?hl=en

Floris Kraak

unread,
Feb 16, 2010, 3:46:08 PM2/16/10
to lr-loa...@googlegroups.com
On Tue, Feb 16, 2010 at 7:00 PM, chaitanya bhatt
<bhatt.c...@gmail.com> wrote:
> Floris, thanks a ton for your valuable inputs.
> Your write up was really overwhelming. :)

hmn, I thought I was just pointing out the obvious ;-)

>
> Few inputs which I gained through the internet regarding GWT RPC encoding:
>
> As uncanny as it sounds, supposedly the pairing of keywords to its value
> works as mentioned below:
>
> NameofVariable1|NameofVariable2|NameofVariable3|........|ValueofVariable1|ValueofVariable1|ValueofVariable2)..
>

Ah, right. That does make a lot of sense. More importantly, it
explains exactly where that last blob of numbers comes from.
So what we're looking at is basically a table, except it's encoded in
a funky way :p

> Notice that towards the end of the body once all tags/names of variables are
> mentioned then starts the array of corresponding values separated by
> delimiters and identified by unique offset for each.

Indeed.

>
> Pretty annoying isn't it? :P
>
> Since my current project is challenged by a strict time frame I am afraid I
> might have to suggest my clients to buy GUI level protocol license as an
> alternative. :(
>

Well, that call is yours to make. I don't know how much of this type
of code you have to correlate. It certainly does not look impossible -
but it does look like a lot of work.
GUI level users have their own challenges as I'm sure you are aware.

Reply all
Reply to author
Forward
0 new messages